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
的值可以使用 產生器表達式
。
注意
INTERFACE_LINK_LIBRARIES_DIRECT
目標屬性旨在用於進階使用案例,例如將靜態外掛程式注入到消費性可執行檔中。它不應用作組織對 target_link_libraries()
的正常呼叫的替代品。
作為使用需求的直接連結相依性¶
INTERFACE_LINK_LIBRARIES_DIRECT
和 INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE
目標屬性是 使用需求。它們的效果會遞移地傳播到相依目標,因此可能會影響相依函式庫鏈中每個目標的直接連結相依性。每當某些函式庫目標 X
連結到另一個函式庫目標 Y
,而目標 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
會放置在X
的INTERFACE_LINK_LIBRARIES
中,因此Y
的使用需求,包括INTERFACE_LINK_LIBRARIES_DIRECT
、INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE
,以及它們新增的直接連結相依性宣告的使用需求,都會傳播到X
的相依者。如果
X
是靜態函式庫或物件函式庫,並且私下連結Y
target_link_libraries(X PRIVATE Y)
則
$<LINK_ONLY:Y>
會放置在X
的INTERFACE_LINK_LIBRARIES
中。Y
的連結需求,包括INTERFACE_LINK_LIBRARIES_DIRECT
、INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE
,以及它們新增的直接連結相依性宣告的遞移連結相依性,都會傳播到X
的相依者。但是,Y
的非連結使用需求會被LINK_ONLY
產生器表達式封鎖,並且不會傳播到X
的相依者。如果
X
是共用函式庫或可執行檔,並且私下連結Y
target_link_libraries(X PRIVATE Y)
則
Y
不會放置在X
的INTERFACE_LINK_LIBRARIES
中,因此Y
的使用需求,甚至INTERFACE_LINK_LIBRARIES_DIRECT
和INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE
,都不會傳播到X
的相依者。在所有情況下,
X
的INTERFACE_LINK_LIBRARIES
的內容不受Y
的INTERFACE_LINK_LIBRARIES_DIRECT
或INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE
的影響。
可以使用 TARGET_PROPERTY
產生器表達式,將 INTERFACE_LINK_LIBRARIES_DIRECT
和 INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE
的效果限制為相依目標的子集。例如,若要將效果限制為可執行目標,請使用以下形式的項目
"$<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:...>"
同樣地,若要將效果限制為特定目標,請使用以下形式的項目
"$<$<BOOL:$<TARGET_PROPERTY:USE_IT>>:...>"
此項目只會影響將其 USE_IT
目標屬性設定為 true 值的目標。
直接連結相依性順序¶
目標的直接連結相依性清單是從其 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)
Foo
上的 INTERFACE_LINK_LIBRARIES_DIRECT
目標屬性告訴 CMake 假裝 app
也直接連結到 FooPlugin
。Foo
上的 INTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE
目標屬性告訴 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
的相依性。