CMAKE_LINK_GROUP_USING_<FEATURE>¶
在版本 3.24 中新增。
此變數定義當使用 LINK_GROUP
產生器表達式時,如何連結指定 <FEATURE>
的程式庫群組。以下兩個條件都必須滿足,此變數才會生效
相關聯的
CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED
變數必須設定為 true。對於相同的
<FEATURE>
,沒有語言特定的定義。這表示對於CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED
而言,目標使用的連結語言不能為 true,而LINK_GROUP
產生器表達式會針對該目標進行評估。
對於依賴連結語言的功能,應改為定義 CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>
變數。
功能名稱區分大小寫,且只能包含字母、數字和底線。以全大寫定義的功能名稱保留給 CMake 自己的內建功能(請參閱下方的 預定義功能)。
功能定義¶
群組功能定義是一個包含正好兩個元素的列表
<PREFIX> <SUFFIX>
在連結器命令列中,<PREFIX>
將位於群組中的程式庫列表之前,而 <SUFFIX>
將位於之後。
對於此變數的元素,可以使用 LINKER:
前綴。
若要將選項傳遞至連結器工具,每個編譯器驅動程式都有自己的語法。LINKER:
前綴和 ,
分隔符號可用於以可移植的方式指定要傳遞至連結器工具的選項。LINKER:
會被適當的驅動程式選項取代,而 ,
則被適當的驅動程式分隔符號取代。驅動程式前綴和驅動程式分隔符號由 CMAKE_<LANG>_LINKER_WRAPPER_FLAG
和 CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP
變數的值給定。
例如,"LINKER:-z,defs"
對於 Clang
變成 -Xlinker -z -Xlinker defs
,對於 GNU GCC
變成 -Wl,-z,defs
。
LINKER:
前綴可以指定為 SHELL:
前綴表達式的一部分。
LINKER:
前綴支援使用 SHELL:
前綴和空格作為分隔符號來指定引數的替代語法。先前的範例隨後變成 "LINKER:SHELL:-z defs"
。
注意
不支援在 LINKER:
前綴開頭以外的任何位置指定 SHELL:
前綴。
範例¶
解決兩個靜態程式庫之間的交叉參考¶
專案可以定義兩個或多個靜態程式庫,它們之間具有循環相依性。為了讓連結器在連結時解析所有符號,它可能需要重複搜尋程式庫,直到沒有建立新的未定義參考。不同的連結器使用不同的語法來達成此目的。以下範例顯示如何針對某些連結器實作此目的。請注意,這僅用於說明目的。專案應改為使用內建的 RESCAN
群組功能(請參閱 預定義功能),它提供了更完整且更穩健的此功能實作。
set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED TRUE)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_C_LINK_GROUP_USING_cross_refs
"LINKER:--start-group"
"LINKER:--end-group"
)
elseif(CMAKE_C_COMPILER_ID STREQUAL "SunPro" AND CMAKE_SYSTEM_NAME STREQUAL "SunOS")
set(CMAKE_C_LINK_GROUP_USING_cross_refs
"LINKER:-z,rescan-start"
"LINKER:-z,rescan-end"
)
else()
# feature not yet supported for the other environments
set(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED FALSE)
endif()
add_library(lib1 STATIC ...)
add_library(lib2 SHARED ...)
if(CMAKE_C_LINK_GROUP_USING_cross_refs_SUPPORTED)
target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:cross_refs,lib1,external>")
else()
target_link_libraries(lib2 PRIVATE lib1 external)
endif()
當連結 lib2
時,CMake 將產生以下連結器命令列片段
GNU
:-Wl,--start-group /path/to/lib1.a -lexternal -Wl,--end-group
SunPro
:-Wl,-z,rescan-start /path/to/lib1.a -lexternal -Wl,-z,rescan-end
預定義功能¶
以下內建群組功能由 CMake 預先定義
RESCAN
有些連結器是單次掃描的。對於此類連結器,程式庫之間的循環參考通常會導致未解析的符號。此功能指示連結器重複搜尋指定的靜態程式庫,直到沒有建立新的未定義參考。
通常,靜態程式庫僅在其於命令列上指定的順序中搜尋一次。如果該程式庫中的符號需要解析稍後出現在命令列上的程式庫中的物件所參考的未定義符號,則連結器將無法解析該參考。透過使用
RESCAN
功能對靜態程式庫進行分組,將重複搜尋所有程式庫,直到解析所有可能的參考。這將使用連結器選項,例如--start-group
和--end-group
,或在 SunOS 上使用-z rescan-start
和-z rescan-end
。使用此功能具有顯著的效能成本。最好僅在兩個或多個靜態程式庫之間存在不可避免的循環參考時才使用它。
當使用以 Linux、BSD 和 SunOS 為目標的工具鏈時,此功能可用。如果使用 GNU 工具鏈,則在以 Windows 平台為目標時也可以使用它。