Spec-Zone.ru › CMake 3.29

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_LIBRARIES X, поэтому требования к использованию Y, включая INTERFACE_LINK_LIBRARIES_DIRECT, INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE, и требования к использованию, объявленные добавленными прямыми зависимостями, распространяются на зависимые целевые объекты X.

  • Если X — это статическая библиотека или библиотека объектов, и связывает Y приватно:

    target_link_libraries(X PRIVATE Y)
    

    тогда $<LINK_ONLY:Y> помещается в INTERFACE_LINK_LIBRARIES X. Требования к подключению 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_LIBRARIES X, поэтому требования к использованию Y, даже INTERFACE_LINK_LIBRARIES_DIRECT и INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE, не распространяются на зависимые целевые объекты X.

  • Во всех случаях содержимое INTERFACE_LINK_LIBRARIES X не изменяется требованиями 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API