导航

  • 索引
  • 下一页 |
  • 上一页 |
  • CMake 4.2.0 »
  • 文档 »
  • cmake-commands(7) »
  • target_link_libraries

target_link_libraries¶

目录

  • target_link_libraries

    • 概述

    • 处理编译器驱动差异

    • 目标及其依赖项的库

    • 目标及其依赖项的库

    • 目标及其依赖项的库(旧版)

    • 仅用于依赖项的库(旧版)

    • 链接对象库

      • 通过 $<TARGET_OBJECTS> 链接对象库

    • 静态库的循环依赖

    • 创建可重定位包

    • 另请参阅

指定链接给定目标及/或其依赖项时使用的库或标志。链接库目标的 Usage requirements 将被传播。目标依赖项的 Usage requirements 会影响其自身源的编译。

概述¶

此命令有多个签名,在以下各节中详细介绍。它们都具有通用形式

target_link_libraries(<target> ... <item>... ...)

命名的 <target> 必须是由 add_executable() 或 add_library() 等命令创建的,并且不能是 别名目标。如果策略 CMP0079 未设置为 NEW,则目标必须在当前目录中创建。对同一 <target> 的重复调用会按调用顺序追加条目。

版本 3.13 中添加: <target> 不必在与 target_link_libraries 调用相同的目录中定义。

每个 <item> 可以是

  • 库目标名称:生成的链接行将包含与目标关联的可链接库文件的完整路径。构建系统将有一个依赖项,如果库文件发生更改,则重新链接 <target>。

    命名的目标必须由 add_library() 在项目内部创建,或者作为 导入库 创建。如果它是在项目内部创建的,则会在构建系统中自动添加一个排序依赖项,以确保命名的库目标在 <target> 链接之前是最新的。

    如果导入的库设置了 IMPORTED_NO_SONAME 目标属性,CMake 可能会要求链接器搜索该库而不是使用完整路径(例如,/usr/lib/libfoo.so 变为 -lfoo)。

    目标工件的完整路径将自动为 shell 进行引用/转义。

  • 库文件的完整路径:生成的链接行通常会保留文件的完整路径。构建系统将有一个依赖项,如果库文件发生更改,则重新链接 <target>。

    在某些情况下,CMake 可能会要求链接器搜索该库(例如,/usr/lib/libfoo.so 变为 -lfoo),例如当检测到共享库没有 SONAME 字段时。在 CMake 4.0 之前的版本中,请参阅策略 CMP0060 了解另一个情况的讨论。

    如果库文件位于 macOS 框架中,该框架的 Headers 目录也将作为 Usage requirements 进行处理。这与将框架目录作为包含目录传递的效果相同。

    版本 3.28 中添加: 库文件可能指向 Apple 平台上的 .xcframework 文件夹。如果是这样,目标将获得所选库的 Headers 目录作为 Usage requirements。

    版本 3.8 中添加: 在 Visual Studio Generators 中,对于 VS 2010 及以上版本,以 .targets 结尾的库文件将被视为 MSBuild 目标文件并导入到生成的项目文件中。其他生成器不支持此功能。

    库文件的完整路径将自动为 shell 进行引用/转义。

  • 裸库名称:生成的链接行将要求链接器搜索该库(例如,foo 变为 -lfoo 或 foo.lib)。

    库名称/标志被视为命令行字符串片段,并且将直接使用,不会进行额外的引用或转义。

  • 链接标志:以 - 开头(但不包括 -l 或 -framework)的项目名称被视为链接器标志。请注意,这些标志将像任何其他库链接项一样被处理,以用于传递依赖项,因此通常可以将它们仅指定为私有链接项,这样它们就不会传播给依赖项。

    此处指定的链接标志将插入到链接命令中,与链接库的位置相同。根据链接器的不同,这可能不正确。使用 LINK_OPTIONS 目标属性或 target_link_options() 命令来显式添加链接标志。这些标志随后将位于链接命令的工具链定义的标志位置。

    版本 3.13 中添加: LINK_OPTIONS 目标属性和 target_link_options() 命令。对于早期版本的 CMake,请改用 LINK_FLAGS 属性。

    链接标志被视为命令行字符串片段,并且将直接使用,不会进行额外的引用或转义。

  • 生成器表达式:一个 $<...> 生成器表达式 可以计算为上述任何项,或计算为它们的 分号分隔列表。如果 ... 包含任何 ; 字符(例如,在计算 ${list} 变量之后),请务必使用显式引用的参数 "$<...>",以便此命令将其作为单个 <item> 接收。

    此外,生成器表达式可以用作上述任何项的片段,例如 foo$<1:_d>。

  • 紧跟在另一个 <item> 后面的 debug、optimized 或 general 关键字。紧跟在这些关键字之后的项仅用于相应的构建配置。 debug 关键字对应于 Debug 配置(或在设置了 DEBUG_CONFIGURATIONS 全局属性时,对应于 DEBUG_CONFIGURATIONS 全局属性中命名的配置)。 optimized 关键字对应于所有其他配置。 general 关键字对应于所有配置,并且是纯粹可选的。这些关键字由该命令立即解释,因此当由生成器表达式生成时没有特殊含义。

    或者,像 $<CONFIG> 这样的生成器表达式提供了更细粒度的按配置链接 <item>。为了更结构化的方法,可以通过创建并链接到设置了 IMPORTED_CONFIGURATIONS 属性的 导入库目标 来实现更高的粒度,特别是在 find 模块中。

包含 :: 的项,例如 Foo::Bar,被假定为 导入 或 别名 库目标名称,如果不存在此类目标,则会导致错误。请参阅策略 CMP0028。

有关 CMake 如何在链接器命令行上对直接链接依赖项进行排序的详细信息,请参阅 CMAKE_LINK_LIBRARIES_STRATEGY 变量和相应的 LINK_LIBRARIES_STRATEGY 目标属性。

有关定义构建系统属性的更多信息,请参阅 cmake-buildsystem(7) 手册。

处理编译器驱动程序差异¶

4.0 版本新增。

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

例如,对于 Clang,"LINKER:-z,defs" 会变成 -Xlinker -z -Xlinker defs;对于 GNU GCC,则会变成 -Wl,-z,defs。

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

注意

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

目标及其依赖项的库¶

target_link_libraries(<target>
                      <PRIVATE|PUBLIC|INTERFACE> <item>...
                     [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)

PUBLIC、PRIVATE 和 INTERFACE 作用域 关键字可用于在单个命令中指定链接依赖项和链接接口。

跟随 PUBLIC 的库和目标被链接,并成为链接接口的一部分。跟随 PRIVATE 的库和目标被链接,但不是链接接口的一部分。跟随 INTERFACE 的库被追加到链接接口,并且不用于链接 <target>。

目标及其依赖项的库¶

target_link_libraries(<target> <item>...)

通过此签名,库依赖项默认是可传递的。当此目标链接到另一个目标时,链接到此目标的所有库也将出现在其他目标的链接行上。这个传递的“链接接口”存储在 INTERFACE_LINK_LIBRARIES 目标属性中,并且可以通过直接设置该属性来覆盖。

在 CMake 4.0 之前的版本中,如果 CMP0022 未设置为 NEW,则传递链接是内置的,但可以被 LINK_INTERFACE_LIBRARIES 属性覆盖。调用此命令的其他签名可能会设置该属性,使得仅由此签名链接的任何库成为私有库。

目标及其依赖项的库(旧版)¶

此签名仅用于兼容性。请优先使用 PUBLIC 或 PRIVATE 关键字。

target_link_libraries(<target>
                      <LINK_PRIVATE|LINK_PUBLIC> <lib>...
                     [<LINK_PRIVATE|LINK_PUBLIC> <lib>...]...)

LINK_PUBLIC 和 LINK_PRIVATE 模式可用于在单个命令中同时指定链接依赖项和链接接口。

跟随 LINK_PUBLIC 的库和目标将被链接,并成为 INTERFACE_LINK_LIBRARIES 的一部分。

在 CMake 4.0 之前的版本中,如果策略 CMP0022 不是 NEW,它们也将成为 LINK_INTERFACE_LIBRARIES 的一部分。跟随 LINK_PRIVATE 的库和目标将被链接,但不会成为 INTERFACE_LINK_LIBRARIES(或 LINK_INTERFACE_LIBRARIES)的一部分。

仅用于依赖项的库(旧版)¶

此签名仅用于兼容性。请优先使用 INTERFACE 模式。

target_link_libraries(<target> LINK_INTERFACE_LIBRARIES <item>...)

LINK_INTERFACE_LIBRARIES 模式将库追加到 INTERFACE_LINK_LIBRARIES 目标属性,而不是用于链接。

在 CMake 4.0 之前的版本中,如果策略 CMP0022 不是 NEW,则此模式还将库追加到 LINK_INTERFACE_LIBRARIES 及其每配置等效项。

链接对象库¶

3.12 版本新增。

对象库 可以用作 target_link_libraries 的 <target>(第一个)参数,以指定其源对其他库的依赖项。例如,代码

add_library(A SHARED a.c)
target_compile_definitions(A PUBLIC A)

add_library(obj OBJECT obj.c)
target_compile_definitions(obj PUBLIC OBJ)
target_link_libraries(obj PUBLIC A)

使用 -DA -DOBJ 编译 obj.c,并为 obj 建立 Usage requirements,该要求会传播给其依赖项。

常规库和可执行文件可以链接到 对象库 以获取其对象文件和 Usage requirements。继续上面的例子,代码

add_library(B SHARED b.c)
target_link_libraries(B PUBLIC obj)

使用 -DA -DOBJ 编译 b.c,使用 b.c 和 obj.c 的对象文件创建共享库 B,并将 B 链接到 A。此外,代码

add_executable(main main.c)
target_link_libraries(main B)

使用 -DA -DOBJ 编译 main.c,并将 main 可执行文件链接到 B 和 A。对象库的 Usage requirements 通过 B 传递,但其对象文件不传递。

对象库 可以“链接”到其他对象库以获取 Usage requirements,但由于它们没有链接步骤,因此不会处理它们的对象文件。继续上面的例子,代码

add_library(obj2 OBJECT obj2.c)
target_link_libraries(obj2 PUBLIC obj)

add_executable(main2 main2.c)
target_link_libraries(main2 obj2)

编译 obj2.c,使用 -DA -DOBJ,使用 main2.c 和 obj2.c 的对象文件创建可执行文件 main2,并将其链接到 A。

换句话说,当 对象库 出现在目标的 INTERFACE_LINK_LIBRARIES 属性中时,它们将被视为 接口库,但当它们出现在目标的 LINK_LIBRARIES 属性中时,它们的对象文件将被包含在链接中。

通过 $<TARGET_OBJECTS> 链接对象库¶

3.21 版本新增。

与对象库关联的对象文件可以通过 $<TARGET_OBJECTS> 生成器表达式引用。这些对象文件将放置在链接行的位置,位于所有库的 *前面*,无论它们的相对顺序如何。此外,将在构建系统中添加一个排序依赖项,以确保对象库在依赖目标链接之前是最新的。例如,代码

add_library(obj3 OBJECT obj3.c)
target_compile_definitions(obj3 PUBLIC OBJ3)

add_executable(main3 main3.c)
target_link_libraries(main3 PRIVATE a3 $<TARGET_OBJECTS:obj3> b3)

将可执行文件 main3 与来自 main3.c 和 obj3.c 的对象文件链接,然后是 a3 和 b3 库。 main3.c *未* 使用来自 obj3 的 Usage requirements(例如 -DOBJ3)进行编译。

这种方法可用于通过 Usage requirements 在链接行中实现对象文件的传递性包含。继续上面的例子,代码

add_library(iface_obj3 INTERFACE)
target_link_libraries(iface_obj3 INTERFACE obj3 $<TARGET_OBJECTS:obj3>)

创建了一个接口库 iface_obj3,它转发 obj3 的 Usage requirements,并将 obj3 的对象文件添加到依赖项的链接行中。代码

add_executable(use_obj3 use_obj3.c)
target_link_libraries(use_obj3 PRIVATE iface_obj3)

使用 -DOBJ3 编译 use_obj3.c,并使用来自 use_obj3.c 和 obj3.c 的对象文件链接可执行文件 use_obj3。

这也可以通过静态库进行传递。由于静态库不进行链接,因此它不会使用通过此方式引用的对象库的对象文件。相反,这些对象文件成为静态库的传递链接依赖项。继续上面的例子,代码

add_library(static3 STATIC static3.c)
target_link_libraries(static3 PRIVATE iface_obj3)

add_executable(use_static3 use_static3.c)
target_link_libraries(use_static3 PRIVATE static3)

使用 -DOBJ3 编译 static3.c,并仅使用其自身对象文件创建 libstatic3.a。use_static3.c 是在*不*使用 -DOBJ3 的情况下编译的,因为 Usage requirement 没有通过 static3 的私有依赖项传递。然而,static3 的链接依赖项被传播,包括 iface_obj3 对 $<TARGET_OBJECTS:obj3> 的引用。use_static3 可执行文件使用来自 use_static3.c 和 obj3.c 的对象文件创建,并链接到库 libstatic3.a。

使用此方法时,项目有责任避免将多个依赖二进制文件链接到 iface_obj3,因为它们都会在链接行中获得 obj3 对象文件。

注意

在 CMake 3.21 之前的版本中,在 target_link_libraries 调用中引用 $<TARGET_OBJECTS> 在某些情况下是有效的,但并非完全支持

  • 它没有在链接行中将对象文件放在库之前。

  • 它没有添加对对象库的排序依赖项。

  • 它在 Xcode 中与多架构不兼容。

静态库的循环依赖¶

库依赖图通常是无环的(DAG),但在相互依赖的 STATIC 库的情况下,CMake 允许图包含循环(强连通分量)。当另一个目标链接到其中一个库时,CMake 会重复整个连通分量。例如,代码

add_library(A STATIC a.c)
add_library(B STATIC b.c)
target_link_libraries(A B)
target_link_libraries(B A)
add_executable(main main.c)
target_link_libraries(main A)

将 main 链接到 A B A B。虽然通常一次重复就足够了,但病态的对象文件和符号排列可能需要更多。可以通过使用 LINK_INTERFACE_MULTIPLICITY 目标属性来处理这种情况,或者在最后一个 target_link_libraries 调用中手动重复该组件。然而,如果两个归档文件确实如此相互依赖,它们应该合并成一个归档文件,也许可以使用 对象库。

创建可重定位包¶

请注意,不建议使用指向依赖项的绝对路径来填充目标的 INTERFACE_LINK_LIBRARIES。这会将依赖项的库文件路径硬编码到安装的包中,这些路径是**在构建包的机器上找到的**。

有关创建可重定位包(relocatable packages)时在指定使用需求时需要注意的额外事项的讨论,请参阅 cmake-packages(7) 手册的 创建可重定位包 部分。

参见¶

  • target_compile_definitions()

  • target_compile_features()

  • target_compile_options()

  • target_include_directories()

  • target_link_directories()

  • target_link_options()

  • target_precompile_headers()

  • target_sources()

目录

  • target_link_libraries
    • 概述
    • 处理编译器驱动差异
    • 目标及其依赖项的库
    • 目标及其依赖项的库
    • 目标及其依赖项的库(旧版)
    • 仅用于依赖项的库(旧版)
    • 链接对象库
      • 通过 $<TARGET_OBJECTS> 链接对象库
    • 静态库的循环依赖
    • 创建可重定位包
    • 另请参阅

上一主题

target_link_directories

下一主题

target_link_options

本页

  • 显示源

快速搜索

导航

  • 索引
  • 下一页 |
  • 上一页 |
  • CMake 4.2.0 »
  • 文档 »
  • cmake-commands(7) »
  • target_link_libraries
© Copyright 2000-2025 Kitware, Inc. and Contributors. 使用 Sphinx 8.2.3 创建。