指定一组要链接到目标的库,以及一个 feature
,它定义了该组应如何链接。例如
add_library(lib1 STATIC ...)
add_library(lib2 ...)
target_link_libraries(lib2 PRIVATE "$<LINK_GROUP:RESCAN,lib1,external>")
这指定 lib2
应该链接到 lib1
和 external
,并且这两个库都应根据 RESCAN
特性的定义包含在链接器命令行中。
特性名称区分大小写,并且只能包含字母、数字和下划线。所有大写字母定义的特性名称都为 CMake 自己的内置特性保留。目前,只有一个预定义的内置组特性
RESCAN
某些链接器是单遍的。对于此类链接器,库之间的循环引用通常会导致未解析的符号。此特性指示链接器重复搜索指定的静态库,直到不再创建新的未定义引用。
通常,静态库仅在其在命令行上指定的顺序中搜索一次。如果该库中的符号需要解析命令行上稍后出现的库中的对象引用的未定义符号,则链接器将无法解析该引用。通过使用 RESCAN
特性对静态库进行分组,将重复搜索它们,直到解析所有可能的引用。这将使用链接器选项,如 --start-group
和 --end-group
,或者在 SunOS 上,使用 -z rescan-start
和 -z rescan-end
。
使用此特性会产生显著的性能成本。最好仅在两个或多个静态库之间存在不可避免的循环引用时使用它。
当使用以 Linux、BSD 和 SunOS 为目标的工具链时,此特性可用。如果使用 GNU 工具链,则也可以在以 Windows 平台为目标时使用它。
内置和自定义组特性根据以下变量定义
用于这些变量中的每一个的值是在创建目标的目录作用域结束时设置的值。用法如下
如果语言相关的 CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>_SUPPORTED
变量为真,则 feature
必须由相应的 CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>
变量定义。
如果没有语言相关的 feature
支持,则 CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED
变量必须为真,并且 feature
必须由相应的 CMAKE_LINK_GROUP_USING_<FEATURE>
变量定义。
LINK_GROUP
生成器表达式与 LINK_LIBRARY
生成器表达式兼容。组中涉及的库可以使用 LINK_LIBRARY
生成器表达式指定。
链接步骤中涉及的每个目标或外部库都允许成为多个组的一部分,但前提是所有涉及的组都指定相同的 feature
。此类组不会在链接器命令行上合并,各个组仍将保留。禁止为同一目标或库混合使用不同的组功能。
add_library(lib1 ...)
add_library(lib2 ...)
add_library(lib3 ...)
add_library(lib4 ...)
add_library(lib5 ...)
target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>")
target_link_libraries(lib4 PRIVATE "$<LINK_GROUP:feature1,lib1,lib3>")
# lib4 will be linked with the groups {lib1,lib2} and {lib1,lib3}.
# Both groups specify the same feature, so this is fine.
target_link_libraries(lib5 PRIVATE "$<LINK_GROUP:feature2,lib1,lib3>")
# An error will be raised here because both lib1 and lib3 are part of two
# groups with different features.
当目标或外部库作为组的一部分参与链接步骤,并且也作为任何组之外的部分参与链接步骤时,任何非组链接项的出现都将被其所属的组替换。
add_library(lib1 ...)
add_library(lib2 ...)
add_library(lib3 ...)
add_library(lib4 ...)
target_link_libraries(lib3 PUBLIC lib1)
target_link_libraries(lib4 PRIVATE lib3 "$<LINK_GROUP:feature1,lib1,lib2>")
# lib4 will only be linked with lib3 and the group {lib1,lib2}
由于 lib1
是为 lib4
定义的组的一部分,因此该组随后会应用于 lib3
对 lib1
的使用。最终结果将如同 lib3
的链接关系已指定为
target_link_libraries(lib3 PUBLIC "$<LINK_GROUP:feature1,lib1,lib2>")
请注意,组优先于非组链接项可能会导致组之间出现循环依赖。如果发生这种情况,则会引发致命错误,因为组不允许循环依赖。
add_library(lib1A ...)
add_library(lib1B ...)
add_library(lib2A ...)
add_library(lib2B ...)
add_library(lib3 ...)
# Non-group linking relationships, these are non-circular so far
target_link_libraries(lib1A PUBLIC lib2A)
target_link_libraries(lib2B PUBLIC lib1B)
# The addition of these groups creates circular dependencies
target_link_libraries(lib3 PRIVATE
"$<LINK_GROUP:feat,lib1A,lib1B>"
"$<LINK_GROUP:feat,lib2A,lib2B>"
)
由于为 lib3
定义的组,lib1A
和 lib2B
的链接关系实际上扩展为等效于
target_link_libraries(lib1A PUBLIC "$<LINK_GROUP:feat,lib2A,lib2B>")
target_link_libraries(lib2B PUBLIC "$<LINK_GROUP:feat,lib1A,lib1B>")
这会在组之间创建循环依赖:lib1A --> lib2B --> lib1A
。
还应注意以下限制