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не зависит от свойствINTERFACE_LINK_LIBRARIES_DIRECTиINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDEцелиY.
Можно ограничить действие 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)
В этом случае мы не хотим, чтобы свойства цели INTERFACE_LINK_LIBRARIES_DIRECT и INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE у Foo влияли на прямые зависимости 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–2026 Kitware, Inc. and Contributors
Licensed under the BSD 3-clause License.
https://cmake.org/cmake/help/latest/prop_tgt/INTERFACE_LINK_LIBRARIES_DIRECT.html