指定要链接到目标的一组库,以及一个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的工具链时可用。在针对Windows平台时,如果使用GNU工具链,也可以使用它。
内置和自定义组特性根据以下变量定义
每个变量使用的值是在创建目标的目录范围结束时设置的值。用法如下
如果特定于语言的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
。
还应注意以下限制