导航

  • 索引
  • 下一个 |
  • 上一个 |
  • CMake 4.0.0 »
  • 文档 »
  • cmake-variables(7) »
  • CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>

CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>¶

在 3.24 版本中添加。

此变量定义了当 LINK_LIBRARY 生成器表达式被使用,且目标的链接语言为 <LANG> 时,如何为指定的 <FEATURE> 链接库或框架。为了使此变量生效,相关的 CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED 变量必须设置为 true。

对于独立于链接语言的功能,应该定义 CMAKE_LINK_LIBRARY_USING_<FEATURE> 变量。

功能名称区分大小写,并且只能包含字母、数字和下划线。所有大写字母定义的功能名称都为 CMake 内置功能保留(请参阅下方的 预定义功能)。

功能行为的某些方面可以通过 CMAKE_<LANG>_LINK_LIBRARY_<FEATURE>_ATTRIBUTES 和 CMAKE_LINK_LIBRARY_<FEATURE>_ATTRIBUTES 变量来定义。

功能定义¶

库功能定义是一个包含一个或三个元素的列表

[<PREFIX>] <LIBRARY_EXPRESSION> [<SUFFIX>]

当指定 <PREFIX> 和 <SUFFIX> 时,它们分别位于 LINK_LIBRARY 表达式中指定的整个库列表的前面和后面,而不是每个库项单独。不能保证指定的库列表将保持分组在一起,因此如果 CMake 为了满足其他约束而重新组织库列表,则 <PREFIX> 和 <SUFFIX> 可能会多次出现。这意味着像 GNU ld 链接器支持的 --start-group 和 --end-group 这样的构造不能以这种方式使用。应该使用 LINK_GROUP 生成器表达式来代替此类构造。

<LIBRARY_EXPRESSION> 用于指定在链接器命令行上为每个库构造相应片段的模式。以下占位符可以在表达式中使用

  • <LIBRARY> 扩展为 CMake 目标的库的完整路径,或者基于项目本身的平台特定值(与 Windows 上的 <LINK_ITEM> 相同,或者其他平台上的库基本名称)。

  • <LINK_ITEM> 扩展为库通常在链接器命令行上的链接方式。

  • <LIB_ITEM> 扩展为 CMake 目标的库的完整路径,或者项目本身完全按照 <LIBRARY_EXPRESSION> 中指定的方式。

除了上述内容之外,还可以为路径(CMake 目标和使用文件路径指定的外部库)使用一种模式,为仅按名称指定的其他项目使用另一种模式。PATH{} 和 NAME{} 包装器可分别用于为这两种情况提供扩展。当使用包装器时,两者都必须存在。例如

set(CMAKE_LINK_LIBRARY_USING_weak_library
    "PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}"
)

对于此变量的所有三个元素(<PREFIX>、<LIBRARY_EXPRESSION> 和 <SUFFIX>),可以使用 LINKER: 前缀。

为了将选项传递给链接器工具,每个编译器驱动程序都有自己的语法。LINKER: 前缀和 , 分隔符可以用于以可移植的方式指定要传递给链接器工具的选项。LINKER: 被适当的驱动程序选项替换,, 被适当的驱动程序分隔符替换。驱动程序前缀和驱动程序分隔符由 CMAKE_<LANG>_LINKER_WRAPPER_FLAG 和 CMAKE_<LANG>_LINKER_WRAPPER_FLAG_SEP 变量的值给出。

例如,"LINKER:-z,defs" 对于 Clang 变为 -Xlinker -z -Xlinker defs,对于 GNU GCC 变为 -Wl,-z,defs。

LINKER: 前缀可以指定为 SHELL: 前缀表达式的一部分。

LINKER: 前缀支持使用 SHELL: 前缀和空格作为分隔符来指定参数的替代语法。之前的示例变为 "LINKER:SHELL:-z defs"。

注意

不支持在 LINKER: 前缀的开头以外的任何位置指定 SHELL: 前缀。

示例¶

加载整个静态库¶

一个常见的需求是防止链接器丢弃静态库中的任何符号。不同的链接器使用不同的语法来实现此目的。以下示例展示了如何为某些链接器实现此目的。请注意,这仅用于说明目的。项目应使用内置的 WHOLE_ARCHIVE 功能(请参阅 预定义功能),该功能提供了更完整和更健壮的此功能实现。

set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED TRUE)
if(CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
  set(CMAKE_C_LINK_LIBRARY_USING_load_archive "-force_load <LIB_ITEM>")
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
  set(CMAKE_C_LINK_LIBRARY_USING_load_archive
    "LINKER:--push-state,--whole-archive"
    "<LINK_ITEM>"
    "LINKER:--pop-state"
  )
elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
  set(CMAKE_C_LINK_LIBRARY_USING_load_archive "/WHOLEARCHIVE:<LIBRARY>")
else()
  # feature not yet supported for the other environments
  set(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED FALSE)
endif()

add_library(lib1 STATIC ...)
add_library(lib2 SHARED ...)

if(CMAKE_C_LINK_LIBRARY_USING_load_archive_SUPPORTED)
  # The -force_load Apple linker option requires a file name
  set(external_lib
    "$<IF:$<LINK_LANG_AND_ID:C,AppleClang>,libexternal.a,external>"
  )
  target_link_libraries(lib2 PRIVATE
    "$<LINK_LIBRARY:load_archive,lib1,${external_lib}>"
  )
else()
  target_link_libraries(lib2 PRIVATE lib1 external)
endif()

CMake 将生成以下链接表达式

  • AppleClang: -force_load /path/to/lib1.a -force_load libexternal.a

  • GNU: -Wl,--push-state,--whole-archive /path/to/lib1.a -lexternal -Wl,--pop-state

  • MSVC: /WHOLEARCHIVE:/path/to/lib1.lib /WHOLEARCHIVE:external.lib

将库作为弱链接¶

在 macOS 上,可以以弱模式链接库(库和所有引用都标记为弱导入)。对于按文件路径指定的库和按名称指定的库,必须使用不同的标志。可以使用 PATH{} 和 NAME{} 包装器来解决此约束。同样,以下示例展示了如何为某些链接器实现此目的,但这仅用于说明目的。项目应使用内置的 WEAK_FRAMEWORK 或 WEAK_LIBRARY 功能(请参阅 预定义功能),这些功能提供了更完整和更健壮的此功能实现。

if (CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
  set(CMAKE_LINK_LIBRARY_USING_weak_library
      "PATH{-weak_library <LIBRARY>}NAME{LINKER:-weak-l<LIB_ITEM>}"
  )
  set(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED TRUE)
endif()

add_library(lib SHARED ...)
add_executable(main ...)
if(CMAKE_LINK_LIBRARY_USING_weak_library_SUPPORTED)
  target_link_libraries(main PRIVATE "$<LINK_LIBRARY:weak_library,lib,external>")
else()
  target_link_libraries(main PRIVATE lib external)
endif()

当使用 AppleClang 工具链链接 main 时,CMake 将生成以下链接器命令行片段

-weak_library /path/to/lib -Xlinker -weak-lexternal.

预定义功能¶

以下内置库功能由 CMake 预定义

DEFAULT

此功能对应于标准链接,本质上等同于根本不使用任何功能。它通常仅与 LINK_LIBRARY_OVERRIDE 和 LINK_LIBRARY_OVERRIDE_<LIBRARY> 目标属性一起使用。

WHOLE_ARCHIVE

强制包含静态库的所有成员,当作为消耗 可执行文件、共享库 和 模块库 的依赖项链接时。此功能仅在以下平台中受支持,并带有如下所述的限制

  • Linux。

  • 所有 BSD 变体。

  • SunOS。

  • 所有 Apple 变体。库必须指定为 CMake 目标名称、库文件名(例如 libfoo.a)或库文件路径(例如 /path/to/libfoo.a)。由于 Apple 链接器的限制,它不能指定为像 foo 这样的纯库名称,其中 foo 不是 CMake 目标。

  • Windows。当使用 MSVC 或类 MSVC 工具链时,MSVC 版本必须大于 1900。

  • Cygwin。

  • MSYS。

注意

由于 静态库 是归档文件而不是链接的二进制文件,因此 CMake 记录了它们的链接依赖项,以便在链接消耗二进制文件时进行传递使用。因此,WHOLE_ARCHIVE 不会导致静态库的对象包含在其他静态库中。使用 对象库 来实现该目的。

FRAMEWORK

此选项告诉链接器使用 -framework 链接器选项搜索指定的框架。它只能在 Apple 平台上使用,并且只能与理解所用选项的链接器一起使用(即 Xcode 提供的链接器,或与其兼容的链接器)。

框架可以指定为 CMake 框架目标、裸框架名称或文件路径。如果给定目标,则该目标必须将其 FRAMEWORK 目标属性设置为 true。对于文件路径,如果它包含目录部分,则该目录将添加为框架搜索路径。

add_library(lib SHARED ...)
target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:FRAMEWORK,/path/to/my_framework>")

# The constructed linker command line will contain:
#   -F/path/to -framework my_framework

文件路径必须符合以下模式之一(* 是通配符,可选部分显示为 [...])

  • [/path/to/]FwName[.framework]

  • [/path/to/]FwName.framework/FwName[suffix]

  • [/path/to/]FwName.framework/Versions/*/FwName[suffix]

请注意,即使不使用 $<LINK_LIBRARY:FRAMEWORK,...> 表达式,CMake 也能识别并自动处理框架目标。如果项目希望显式声明,生成器表达式仍然可以与 CMake 目标一起使用,但这不是必需的。使用生成器表达式或不使用生成器表达式,链接器命令行可能存在一些差异,但最终结果应该是相同的。另一方面,如果给出了文件路径,CMake 将自动识别某些路径,但不是所有情况。项目可能希望对文件路径使用 $<LINK_LIBRARY:FRAMEWORK,...>,以便预期行为清晰。

3.25 版本新增: FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG> 目标属性以及框架库名称的 suffix 现在受 FRAMEWORK 功能支持。

NEEDED_FRAMEWORK

这与 FRAMEWORK 功能类似,但它强制链接器与框架链接,即使没有使用框架中的任何符号。它使用 -needed_framework 选项,并且具有与 FRAMEWORK 相同的链接器约束。

REEXPORT_FRAMEWORK

这与 FRAMEWORK 功能类似,但它告诉链接器,框架应该可供链接到正在创建的库的客户端使用。它使用 -reexport_framework 选项,并且具有与 FRAMEWORK 相同的链接器约束。

WEAK_FRAMEWORK

这与 FRAMEWORK 功能类似,但它强制链接器将框架和对它的所有引用标记为弱导入。它使用 -weak_framework 选项,并且具有与 FRAMEWORK 相同的链接器约束。

NEEDED_LIBRARY

这与 NEEDED_FRAMEWORK 功能类似,但它用于非框架目标或库(仅限 Apple 平台)。它根据需要使用 -needed_library 或 -needed-l 选项,并且具有与 NEEDED_FRAMEWORK 相同的链接器约束。

REEXPORT_LIBRARY

这与 REEXPORT_FRAMEWORK 功能类似,但它用于非框架目标或库(仅限 Apple 平台)。它根据需要使用 -reexport_library 或 -reexport-l 选项,并且具有与 REEXPORT_FRAMEWORK 相同的链接器约束。

WEAK_LIBRARY

这与 WEAK_FRAMEWORK 功能类似,但它用于非框架目标或库(仅限 Apple 平台)。它根据需要使用 -weak_library 或 -weak-l 选项,并且具有与 WEAK_FRAMEWORK 相同的链接器约束。

目录

  • CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>
    • 功能定义
    • 示例
      • 加载整个静态库
      • 将库作为弱链接
    • 预定义功能

上一主题

CMAKE_<LANG>_LINK_LIBRARY_FLAG

下一主题

CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>_SUPPORTED

本页

  • 显示源代码

快速搜索

导航

  • 索引
  • 下一个 |
  • 上一个 |
  • CMake 4.0.0 »
  • 文档 »
  • cmake-variables(7) »
  • CMAKE_<LANG>_LINK_LIBRARY_USING_<FEATURE>
© 版权所有 2000-2025 Kitware, Inc. 和贡献者。使用 Sphinx 7.3.7 创建。