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/v3.29/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT.html