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对于为其评估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" 变成``-Xlinker -z -Xlinker defs`` 对于``Clang`` 和``-Wl,-z,defs`` 对于``GNU GCC ``。
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()
CMake 在链接 lib2 时将生成以下链接器命令行片段:
GNU:-Wl,--start-group /path/to/lib1.a -lexternal -Wl,--end-groupSunPro:-Wl,-z,rescan-start /path/to/lib1.a -lexternal -Wl,-z,rescan-end
预定义功能¶
以下内置组功能由 CMake 预定义:
重新扫描一些链接器仅是单程的。对于此类链接器,库之间的循环引用通常会导致无法解析的符号。此功能指示链接器重复搜索指定的静态库,直到没有创建新的未定义引用为止。
通常,静态库只会按照在命令行中指定的顺序搜索一次。如果需要该库中的符号来解析由稍后出现在命令行中的库中的对象引用的未定义符号,则链接器将无法解析该引用。通过使用
RESCAN特性对静态库进行分组,它们将被重复搜索,直到所有可能的引用都被解析。这将使用链接器选项,如``--start-group`` 和``--end-group``,或在 SunOS 上,-z rescan-start和``-z rescan-end``。使用此功能会产生显着的性能成本。最好只在两个或多个静态库之间存在不可避免的循环引用时才使用它。
当使用面向 Linux、BSD 和 SunOS 的工具链时,此功能可用。如果使用 GNU 工具链,它也可以在针对 Windows 平台时使用。