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