target_link_libraries
- Обзор
- Библиотеки для целевого объекта и/или его зависимостей
- Библиотеки для целевого объекта и его зависимостей
- Библиотеки для целевого объекта и/или его зависимостей (устаревшее)
- Библиотеки только для зависимостей (устаревшее)
- Циклические зависимости статических библиотек
- Создание переносимых пакетов
Укажите библиотеки или флаги, которые нужно использовать при создании ссылок на данный целевой объект и/или его зависимости. Требования к использованию соединенных целевых библиотек будут переданы. Требования к использованию зависимостей целевого объекта влияют на компиляцию его собственных исходных кодов.
Обзор
Эта команда имеет несколько синтаксических вариантов, как подробно описано в подразделах ниже. Все они имеют общий вид
target_link_libraries(<target> ... <item>... ...)
Именованный <target> должен был быть создан командой, такой как add_executable() или add_library(), и не должен быть целевым объектом-псевдонимом. Если политика CMP0079 не установлена в NEW, то целевой объект должен быть создан в текущем каталоге. Повторные вызовы для того же <target> добавляют элементы в порядке вызова.
Новое в версии 3.13: Целевой объект <target> не обязательно должен быть определен в том же каталоге, что и вызов target_link_libraries.
Каждый <item> может быть:
-
Имя целевого объекта библиотеки: Сгенерированная строка ссылки будет содержать полный путь к файлу связуемой библиотеки, связанный с целевым объектом. Система построения будет иметь зависимость от повторной связи
<target>при изменении файла библиотеки.Именованный целевой объект должен быть создан с помощью
add_library()в проекте или как импортированная библиотека. Если он создан в проекте, в системе построения автоматически добавляется зависимость от порядка, чтобы убедиться, что указанный целевой объект библиотеки обновлен до того, как<target>создает ссылку.Если у импортированной библиотеки установлено свойство целевого объекта
IMPORTED_NO_SONAME, CMake может попросить компоновщик искать библиотеку вместо использования полного пути (например,/usr/lib/libfoo.soстановится-lfoo).Полный путь к артефакту целевого объекта будет автоматически заключён в кавычки/экранирован для оболочки.
-
Полный путь к файлу библиотеки: Сгенерированная строка ссылки обычно сохраняет полный путь к файлу. Система построения будет иметь зависимость от повторной связи
<target>при изменении файла библиотеки.В некоторых случаях CMake может попросить компоновщик искать библиотеку (например,
/usr/lib/libfoo.soстановится-lfoo), например, когда обнаружено, что у разделяемой библиотеки нет поляSONAME. См. политикуCMP0060для обсуждения другого случая.Если файл библиотеки находится в macOS-фреймворке, каталог
Headersфреймворка также будет обработан как требование к использованию. Это имеет тот же эффект, что и передача каталога фреймворка как каталога включения.Новое в версии 3.8: В генераторах Visual Studio для VS 2010 и выше файлы библиотек, заканчивающиеся на
.targets, будут обрабатываться как файлы целей MSBuild и импортироваться в сгенерированные файлы проекта. Это не поддерживается другими генераторами.Полный путь к файлу библиотеки будет автоматически заключён в кавычки/экранирован для оболочки.
-
Простое имя библиотеки: Сгенерированная строка ссылки попросит компоновщик искать библиотеку (например,
fooстановится-lfooилиfoo.lib).Имя/флаг библиотеки обрабатывается как фрагмент строки командной строки и будет использоваться без дополнительных кавычек или экранирования.
-
Флаг ссылки: Имена элементов, начинающиеся с
-, но не с-lили-framework, обрабатываются как флаги компоновщика. Обратите внимание, что такие флаги будут обрабатываться как любой другой элемент ссылки на библиотеку для целей транзитивных зависимостей, поэтому их обычно безопасно указывать только как частные элементы ссылки, которые не будут передаваться зависимым объектам.Указанные здесь флаги ссылки вставляются в команду ссылки в то же место, что и ссылки на библиотеки. Это может быть неверно в зависимости от компоновщика. Используйте свойство целевого объекта
LINK_OPTIONSили командуtarget_link_options(), чтобы явно добавить флаги ссылки. Флаги будут затем размещены в определенном инструментом-построения месте флагов в команде ссылки.Новое в версии 3.13: Свойство целевого объекта
LINK_OPTIONSи командаtarget_link_options(). Для более ранних версий CMake используйте свойствоLINK_FLAGSвместо этого.Флаг ссылки обрабатывается как фрагмент строки командной строки и используется без дополнительных кавычек или экранирования.
-
Выражение генератора:
$<...>generator expressionможет вычисляться как любой из перечисленных выше элементов или как список, разделенный точкой с запятой из них. Если...содержит символы;, например, после вычисления переменной${list}, обязательно используйте явное выражение с кавычками"$<...>"для того, чтобы эта команда получала его как отдельный<item>.Кроме того, выражение генератора может быть фрагментом любого из вышеперечисленных элементов, например
foo$<1:_d>.Обратите внимание, что выражения генератора не будут использоваться в старом обработке политики
CMP0003или политикиCMP0004. - Ключевое слово
debug,optimized, илиgeneral, сразу за которым следует другой<item>. Элемент, следующий за таким ключевым словом, используется только для соответствующей конфигурации построения. Ключевое словоdebugсоответствует конфигурацииDebug(или конфигурациям, указанным в свойстве глобальной переменнойDEBUG_CONFIGURATIONS, если оно установлено). Ключевое словоoptimizedсоответствует всем другим конфигурациям. Ключевое словоgeneralсоответствует всем конфигурациям и является чисто необязательным. Более высокая детализация может быть достигнута для правил по конфигурациям с помощью создания и ссылки на импортированные целевые объекты библиотек.
Элементы, содержащие ::, такие как Foo::Bar, предполагаются именами импортированных или алиасных целевых объектов библиотек и приведут к ошибке, если такого объекта не существует. См. политику CMP0028.
См. руководство cmake-buildsystem(7) для получения дополнительной информации о определении свойств системы построения.
Библиотеки для целевого объекта и/или его зависимостей
target_link_libraries(<target>
<PRIVATE|PUBLIC|INTERFACE> <item>...
[<PRIVATE|PUBLIC|INTERFACE> <item>...]...)
Ключевые слова PUBLIC, PRIVATE и INTERFACE области могут использоваться для указания зависимостей ссылок и интерфейса ссылок в одной команде.
Библиотеки и цели, следующие за PUBLIC, связаны с интерфейсом связи и входят в него. Библиотеки и цели, следующие за PRIVATE, связаны с интерфейсом связи, но не входят в него. Библиотеки, следующие за INTERFACE, добавляются в интерфейс связи и не используются для связывания <target>.
Библиотеки для цели и её зависимостей
target_link_libraries(<target> <item>...)
Зависимости библиотек по умолчанию являются транзитивными с этим сигнатуром. Когда эта цель подключается к другой цели, библиотеки, связанные с этой целью, также будут отображаться на линии связи другой цели. Этот транзитивный «интерфейс связи» хранится в свойстве цели INTERFACE_LINK_LIBRARIES и может быть переопределён путём прямого задания свойства. Когда CMP0022 не задано как NEW, транзитивное связывание включено, но может быть переопределено свойством LINK_INTERFACE_LIBRARIES. Вызовы других сигнатур этой команды могут задать свойство, сделав любые библиотеки, связанные исключительно этим сигнатуром, закрытыми.
Библиотеки для цели и/или её зависимостей (устаревшее)
target_link_libraries(<target>
<LINK_PRIVATE|LINK_PUBLIC> <lib>...
[<LINK_PRIVATE|LINK_PUBLIC> <lib>...]...)
Режимы LINK_PUBLIC и LINK_PRIVATE могут быть использованы для задания как зависимостей связи, так и интерфейса связи в одной команде.
Этот синтаксис предназначен только для совместимости. Вместо него предпочтительно использовать ключевые слова PUBLIC или PRIVATE.
Библиотеки и цели, следующие за LINK_PUBLIC, связаны с и входят в INTERFACE_LINK_LIBRARIES. Если политика CMP0022 не NEW, они также входят в LINK_INTERFACE_LIBRARIES. Библиотеки и цели, следующие за LINK_PRIVATE, связаны с, но не входят в INTERFACE_LINK_LIBRARIES (или LINK_INTERFACE_LIBRARIES).
Библиотеки только для зависимостей (устаревшее)
target_link_libraries(<target> LINK_INTERFACE_LIBRARIES <item>...)
Режим LINK_INTERFACE_LIBRARIES добавляет библиотеки в свойство цели INTERFACE_LINK_LIBRARIES вместо их использования для связывания. Если политика CMP0022 не NEW, то этот режим также добавляет библиотеки в LINK_INTERFACE_LIBRARIES и его эквивалент для каждой конфигурации.
Этот синтаксис предназначен только для совместимости. Вместо него предпочтительно использовать режим INTERFACE.
Библиотеки, указанные как debug, заключены в выражение генератора для соответствия отладочным сборкам. Если политика CMP0022 не NEW, библиотеки также добавляются в свойство LINK_INTERFACE_LIBRARIES_DEBUG (или в соответствующие свойства конфигураций, указанных в глобальном свойстве DEBUG_CONFIGURATIONS, если оно задано). Библиотеки, указанные как optimized, добавляются в свойство INTERFACE_LINK_LIBRARIES. Если политика CMP0022 не NEW, они также добавляются в свойство LINK_INTERFACE_LIBRARIES. Библиотеки, указанные как general (или без ключевого слова) обрабатываются так, как если бы они были указаны и для debug, и для optimized.
Связывание библиотек объектов
Новое в версии 3.12.
Библиотеки объектов могут использоваться в качестве аргумента <target> (первого) в target_link_libraries для задания зависимостей их исходных файлов от других библиотек. Например, код
add_library(A SHARED a.c) target_compile_definitions(A PUBLIC A) add_library(obj OBJECT obj.c) target_compile_definitions(obj PUBLIC OBJ) target_link_libraries(obj PUBLIC A)
компилирует obj.c с -DA -DOBJ и устанавливает требования использования для obj, которые передаются его зависимостям.
Обычные библиотеки и исполняемые файлы могут подключаться к Библиотекам объектов для получения их объектов и требований использования. Продолжая пример выше, код
add_library(B SHARED b.c) target_link_libraries(B PUBLIC obj)
компилирует b.c с -DA -DOBJ, создаёт динамическую библиотеку B с файлами объектов из b.c и obj.c, и связывает B с A. Кроме того, код
add_executable(main main.c) target_link_libraries(main B)
компилирует main.c с -DA -DOBJ и связывает исполняемый файл main с B и A. Требования использования библиотеки объектов передаются транзитивно через B, но её файлы объектов не передаются.
Библиотеки объектов могут «подключаться» к другим библиотекам объектов для получения требований использования, но так как у них нет этапа связи, с их файлами объектов ничего не делается. Продолжая пример выше, код:
add_library(obj2 OBJECT obj2.c) target_link_libraries(obj2 PUBLIC obj) add_executable(main2 main2.c) target_link_libraries(main2 obj2)
компилирует obj2.c с -DA -DOBJ, создаёт исполняемый файл main2 с файлами объектов из main2.c и obj2.c, и связывает main2 с A.
Другими словами, когда Библиотеки объектов появляются в свойстве INTERFACE_LINK_LIBRARIES цели, они будут обрабатываться как Интерфейсные библиотеки, но когда они появляются в свойстве LINK_LIBRARIES цели, их файлы объектов также будут включены в связь.
Связывание библиотек объектов через $<TARGET_OBJECTS>
Новое в версии 3.21.
Файлы объектов, связанные с библиотекой объектов, могут быть указаны выражением генератора $<TARGET_OBJECTS>. Такие файлы объектов размещаются на линии связи перед всеми библиотеками, независимо от их относительного порядка. Кроме того, в систему сборки будет добавлена зависимость порядка, чтобы гарантировать, что библиотека объектов будет обновлена перед связыванием зависимой цели. Например, код
add_library(obj3 OBJECT obj3.c) target_compile_definitions(obj3 PUBLIC OBJ3) add_executable(main3 main3.c) target_link_libraries(main3 PRIVATE a3 $<TARGET_OBJECTS:obj3> b3)
связывает исполняемый файл main3 с файлами объектов из main3.c и obj3.c, за которыми следуют библиотеки a3 и b3. main3.c не компилируется с требованиями использования из obj3, такими как -DOBJ3.
Этот подход можно использовать для обеспечения транзитивного включения файлов объектов в строки связи как требований использования. Продолжая пример выше, код
add_library(iface_obj3 INTERFACE) target_link_libraries(iface_obj3 INTERFACE obj3 $<TARGET_OBJECTS:obj3>)
создаёт интерфейсную библиотеку iface_obj3, которая перенаправляет требования использования obj3 и добавляет файлы объектов obj3 в строки связи зависимостей. Код
add_executable(use_obj3 use_obj3.c) target_link_libraries(use_obj3 PRIVATE iface_obj3)
компилирует use_obj3.c с -DOBJ3 и связывает исполняемый файл use_obj3 с файлами объектов из use_obj3.c и obj3.c.
Это также работает транзитивно через статическую библиотеку. Поскольку статическая библиотека не связывается, она не потребляет файлы объектов из библиотек объектов, на которые ссылаются таким образом. Вместо этого файлы объектов становятся транзитивными зависимостями связи статической библиотеки. Продолжая пример выше, код
add_library(static3 STATIC static3.c) target_link_libraries(static3 PRIVATE iface_obj3) add_executable(use_static3 use_static3.c) target_link_libraries(use_static3 PRIVATE static3)
компилирует static3.c с -DOBJ3 и создаёт libstatic3.a только с использованием своего собственного файла объекта. use_static3.c компилируется без -DOBJ3, потому что требование использования не является транзитивным через закрытую зависимость static3. Однако, зависимости связи static3 передаются, включая ссылку iface_obj3 на $<TARGET_OBJECTS:obj3>. Исполняемый файл use_static3 создаётся с файлами объектов из use_static3.c и obj3.c, и связывается с библиотекой libstatic3.a.
При использовании этого подхода, проект отвечает за избегание связывания нескольких зависимых библиотек с iface_obj3, так как все они получат файлы объектов obj3 в строках их линковки.
Примечание
Обращение к $<TARGET_OBJECTS> в target_link_libraries вызовах работало в версиях CMake до 3.21 в некоторых случаях, но не поддерживалось полностью:
- Файлы объектов не размещались перед библиотеками в строках линковки.
- Не добавлялась зависимость упорядочивания на библиотеке объектов.
- Не работало в Xcode с несколькими архитектурами.
Циклические зависимости статических библиотек
Граф зависимостей библиотек обычно является ациклическим (DAG), но в случае взаимозависимых STATIC библиотек CMake разрешает графу содержать циклы (сильно связанные компоненты). Когда другой целевой компонент ссылается на одну из библиотек, CMake повторяет весь соединённый компонент. Например, код
add_library(A STATIC a.c) add_library(B STATIC b.c) target_link_libraries(A B) target_link_libraries(B A) add_executable(main main.c) target_link_libraries(main A)
связывает main с A B A B. Хотя одного повторения обычно достаточно, патологические расположения файлов объектов и символов могут потребовать большего. Можно справиться с такими случаями, используя свойство целевого компонента LINK_INTERFACE_MULTIPLICITY или вручную повторяя компонент в последнем вызове target_link_libraries. Однако, если две архивы действительно так взаимозависимы, их следует объединить в одну архив, возможно, используя Объектные библиотеки.
Создание переносимых пакетов
Обратите внимание, что не рекомендуется заполнять INTERFACE_LINK_LIBRARIES целевого компонента абсолютными путями к зависимостям. Это зашифрует в установленные пакеты пути к файлам библиотек зависимостей так, как они были найдены на машине, на которой был создан пакет.
См. раздел Создание переносимых пакетов руководства cmake-packages(7) для обсуждения дополнительной осторожности, которая должна быть соблюдена при указании требований к использованию при создании пакетов для распространения.
© 2000–2022 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.25/command/target_link_libraries.html