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.28: Файл библиотеки может указывать на папку
.xcframeworkна платформах Apple. Если это так, целевой объект получит каталог выбранной библиотеки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) для обсуждения дополнительной внимательности, которая требуется при указании требований к использованию при создании пакетов для распространения.
См. также
target_compile_definitions()target_compile_features()target_compile_options()target_include_directories()target_link_directories()target_link_options()target_precompile_headers()target_sources()
© 2000–2024 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/v3.29/command/target_link_libraries.html