指定一组要链接到目标的库,以及一个定义该组应如何链接的 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
变量为 true,则 feature
必须由相应的 CMAKE_<LANG>_LINK_GROUP_USING_<FEATURE>
变量定义。
如果不支持任何特定语言的 feature
,则 CMAKE_LINK_GROUP_USING_<FEATURE>_SUPPORTED
变量必须为 true,并且 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
定义的组,该组随后被应用于 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
。
还应注意以下限制