指定要链接到目标的库组,以及定义该组应如何链接的 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 是为 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。
还应注意以下限制