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
,而後者的直接或傳遞使用需求包含 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
的依賴項。