target_link_libraries
- Обзор
- Библиотеки для целевого объекта и/или его зависимостей
- Библиотеки для целевого объекта и его зависимостей
- Библиотеки для целевого объекта и/или его зависимостей (устаревшее)
- Библиотеки только для зависимостей (устаревшее)
- Циклические зависимости статических библиотек
- Создание переносимых пакетов
Укажите библиотеки или флаги, используемые при компоновке заданного целевого объекта и/или его зависимостей. Требования к использованию связанных целевых библиотек будут проpropagated. Требования к использованию зависимостей целевого объекта влияют на компиляцию его собственных исходных файлов.
Обзор
Эта команда имеет несколько синтаксических вариантов, как подробно описано в разделах ниже. Все они имеют общий вид
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. Вызовы других подписей этой команды могут установить свойство, делая любые библиотеки, подключенные исключительно этой подписью, приватными.
Библиотеки для цели и/или её зависимостей (Legacy)
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).
Библиотеки только для зависимостей (Legacy)
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.23/command/target_link_libraries.html