target_link_libraries
- Обзор
- Библиотеки для целевого объекта и/или его зависимостей
- Библиотеки как для целевого объекта, так и для его зависимостей
- Библиотеки для целевого объекта и/или его зависимостей (Legacy)
- Библиотеки только для зависимостей (Legacy)
- Циклические зависимости статических библиотек
- Создание переносимых пакетов
Укажите библиотеки или флаги для использования при связывании заданного целевого объекта и/или его зависимостей. Требования к использованию связанных целевых библиотек будут перенесены. Требования к использованию зависимостей целевого объекта влияют на компиляцию его собственных исходных кодов.
Обзор
Эта команда имеет несколько подписей, как подробно описано в подразделах ниже. Все они имеют общий вид
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_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–2021 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.21/command/target_link_libraries.html