CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>¶
加入於版本 3.24。
此變數定義當使用 LINK_GROUP
產生器表達式,且目標的連結語言為 <LANG>
時,如何針對指定的 <FEATURE>
連結一組函式庫。若要使此變數生效,關聯的 CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED
變數必須設定為 true。
對於與連結語言無關的功能,應該改為定義 CMAKE_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 平台時使用此功能。