INTERFACE_LINK_LIBRARIES_DIRECT
Добавлен в версии 3.24.
Список библиотек, которые потребители этой библиотеки должны рассматривать как зависимости с прямыми ссылками.
Это свойство целевого объекта может быть установлено для включения элементов в конечный набор прямых зависимостей ссылок целевого объекта-зависимости. См. свойство целевого объекта INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE для исключения элементов.
Начальный набор прямых зависимостей ссылок целевого объекта-зависимости задается его свойством целевого объекта LINK_LIBRARIES. Косвенные зависимости ссылок задаются транзитивным замыканием свойств прямых зависимостей ссылок INTERFACE_LINK_LIBRARIES. Любая зависимость ссылок может указать дополнительные прямые зависимости ссылок, используя свойство целевого объекта INTERFACE_LINK_LIBRARIES_DIRECT. Затем набор прямых зависимостей ссылок фильтруется для исключения элементов, названных в свойстве целевого объекта любой зависимости INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE.
Значение INTERFACE_LINK_LIBRARIES_DIRECT может использовать generator expressions.
Примечание
Свойство целевого объекта INTERFACE_LINK_LIBRARIES_DIRECT предназначено для использования в сложных случаях, таких как внедрение статических плагинов в исполняемый файл-потребитель. Его не следует использовать как замену для организации обычных вызовов target_link_libraries().
Прямые зависимости ссылок как требования к использованию
Свойства целевого объекта INTERFACE_LINK_LIBRARIES_DIRECT и INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE являются требованиями к использованию. Их эффекты распространяются на зависимые целевые объекты транзитивно и, следовательно, могут влиять на прямые зависимости ссылок каждого целевого объекта в цепочке зависимых библиотек. Всякий раз, когда некоторый целевой объект библиотеки X ссылается на другой целевой объект библиотеки Y, чьи прямые или транзитивные требования к использованию содержат INTERFACE_LINK_LIBRARIES_DIRECT или INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE, свойства могут влиять на список прямых зависимостей ссылок X.
- Если
Xявляется динамической библиотекой или исполняемым файлом, его зависимости подключаются. Они также влияют на требования к использованию, с которыми компилируются исходные кодыX. - Если
Xявляется статической библиотекой или библиотекой объектов, он фактически не подключается, поэтому его зависимости, в лучшем случае, влияют на требования к использованию, с которыми компилируются исходные кодыX.
Свойства также могут влиять на список прямых зависимостей ссылок на зависимых объектах X.
-
Если
Xпублично ссылается наY:target_link_libraries(X PUBLIC Y)
тогда
Yпомещается вINTERFACE_LINK_LIBRARIESX, поэтому требованияYк использованию, включаяINTERFACE_LINK_LIBRARIES_DIRECT,INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE, и требования к использованию, объявленные прямыми зависимостями ссылок, которые они добавляют, распространяются на зависимые объектыX. -
Если
Xявляется статической библиотекой или библиотекой объектов и приватно ссылается наY:target_link_libraries(X PRIVATE Y)
тогда
$<LINK_ONLY:Y>помещается вINTERFACE_LINK_LIBRARIESX. Требования к подключениюY, включаяINTERFACE_LINK_LIBRARIES_DIRECT,INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE, и транзитивные зависимости ссылок, объявленные прямыми зависимостями ссылок, которые они добавляют, распространяются на зависимые объектыXОднако требованияYк использованию, не связанным с подключением, блокируются выражением генератораLINK_ONLYи не распространяются на зависимые объектыX. -
Если
Xявляется динамической библиотекой или исполняемым файлом и приватно ссылается наY:target_link_libraries(X PRIVATE Y)
тогда
Yне помещается вINTERFACE_LINK_LIBRARIESX, поэтому требованияYк использованию, дажеINTERFACE_LINK_LIBRARIES_DIRECTиINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE, не распространяются на зависимые объектыX. - Во всех случаях содержимое
INTERFACE_LINK_LIBRARIESXне затрагивается требованиямиYк использованиюINTERFACE_LINK_LIBRARIES_DIRECTилиINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE.
Можно ограничить влияние INTERFACE_LINK_LIBRARIES_DIRECT и INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE на подмножество зависимых целевых объектов, используя выражение генератора TARGET_PROPERTY. Например, чтобы ограничить влияние исполняемыми файлами, используйте запись вида:
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:...>"
Аналогично, чтобы ограничить влияние на определённые целевые объекты, используйте запись вида:
"$<$<BOOL:$<TARGET_PROPERTY:USE_IT>>:...>"
Эта запись будет влиять только на целевые объекты, которые установили своё свойство целевого объекта USE_IT в истинное значение.
Порядок прямых зависимостей ссылок
Список прямых зависимостей ссылок для целевого объекта вычисляется из начального упорядоченного списка в его свойстве целевого объекта LINK_LIBRARIES. Для каждого элемента обнаруживаются дополнительные прямые зависимости ссылок по его прямым и транзитивным требованиям к использованию INTERFACE_LINK_LIBRARIES_DIRECT. Каждый обнаруженный элемент вставляется перед элементом, который его указал. Однако обнаруженный элемент добавляется не более одного раза и только в том случае, если он не встречался нигде в исходном списке. Это даёт LINK_LIBRARIES контроль над порядком тех прямых зависимостей ссылок, которые он явно указывает.
После сбора всех прямых зависимостей ссылок элементы, названные во всех их требованиях к использованию INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE, удаляются из окончательного списка. Это не влияет на порядок оставшихся элементов.
Пример: статические плагины
Рассмотрим статическую библиотеку Foo, которая предоставляет статический плагин FooPlugin для исполняемых файлов-приложений-потребителей, где реализация плагина зависит от Foo и других вещей. В этом случае приложение должно подключаться к FooPlugin напрямую, прежде чем к Foo Однако автор приложения знает только о Foo. Мы можем выразить это следующим образом:
# Core library used by other components. add_library(Core STATIC core.cpp) # Foo is a static library for use by applications. # Implementation of Foo depends on Core. add_library(Foo STATIC foo.cpp foo_plugin_helper.cpp) target_link_libraries(Foo PRIVATE Core) # Extra parts of Foo for use by its static plugins. # Implementation of Foo's extra parts depends on both Core and Foo. add_library(FooExtras STATIC foo_extras.cpp) target_link_libraries(FooExtras PRIVATE Core Foo) # The Foo library has an associated static plugin # that should be linked into the final executable. # Implementation of the plugin depends on Core, Foo, and FooExtras. add_library(FooPlugin STATIC foo_plugin.cpp) target_link_libraries(FooPlugin PRIVATE Core Foo FooExtras) # An app that links Foo should link Foo's plugin directly. set_property(TARGET Foo PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT FooPlugin) # An app does not need to link Foo directly because the plugin links it. set_property(TARGET Foo PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE Foo)
Приложению app необходимо только указать, что оно подключается к Foo:
add_executable(app main.cpp) target_link_libraries(app PRIVATE Foo)
Свойство целевого объекта INTERFACE_LINK_LIBRARIES_DIRECT в Foo сообщает CMake, что app также подключается напрямую к FooPlugin Свойство целевого объекта INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE в Foo сообщает CMake, что app не подключался напрямую к Foo Вместо этого Foo будет подключен как зависимость FooPlugin. Окончательная строка подключения для app будет подключать библиотеки в следующем порядке:
-
FooPluginкак прямая зависимостьapp(через требованияFooк использованию). -
FooExtrasкак зависимостьFooPlugin. -
Fooкак зависимостьFooPluginиFooExtras. -
Coreкак зависимостьFooPlugin,FooExtras, иFoo.
Обратите внимание, что без свойства целевого объекта INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE Foo было бы подключено дважды: один раз как прямая зависимость от app, и один раз как зависимость от FooPlugin.
Пример: опциональные статические плагины
В приведенном выше примере Пример: статические плагины исполняемый файл app указывает, что он подключается напрямую к Foo В реальном приложении может быть промежуточная библиотека:
add_library(app_impl STATIC app_impl.cpp) target_link_libraries(app_impl PRIVATE Foo) add_executable(app main.cpp) target_link_libraries(app PRIVATE app_impl)
В этом случае мы не хотим, чтобы свойства целевого объекта Foo и INTERFACE_LINK_LIBRARIES_DIRECT INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE влияли на прямые зависимости app_impl Для предотвращения этого мы можем пересмотреть значения свойств, чтобы их действие стало опциональным:
# An app that links Foo should link Foo's plugin directly. set_property(TARGET Foo PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT "$<$<BOOL:$<TARGET_PROPERTY:FOO_STATIC_PLUGINS>>:FooPlugin>" ) # An app does not need to link Foo directly because the plugin links it. set_property(TARGET Foo PROPERTY INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE "$<$<BOOL:$<TARGET_PROPERTY:FOO_STATIC_PLUGINS>>:Foo>" )
Теперь исполняемый файл app может включить плагин(ы) Foo:
set_property(TARGET app PROPERTY FOO_STATIC_PLUGINS 1)
Окончательная строка подключения для app теперь будет подключать библиотеки в следующем порядке:
-
FooPluginкак прямая зависимость отapp(через требования использованияFoo). -
app_implкак прямая зависимость отapp. -
FooExtrasкак зависимость отFooPlugin. -
Fooкак зависимость отapp_impl,FooPlugin, иFooExtras. -
Coreкак зависимость отFooPlugin,FooExtras, иFoo.
© 2000–2024 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT.html