为什么使用add_library({tgt} IMPORTED)与target_link_libraries(-l {.so | .a})?

Chi*_*672 6 cmake build-system libraries

使用该声明的目的是什么:

add_library(<tgt> [SHARED|STATIC] IMPORTED)
Run Code Online (Sandbox Code Playgroud)

根据我的发现,即使您在上面创建导入的库目标,您仍然需要指定实际的.so或.a的具体位置.这将需要至少3个cmake命令链接到可执行文件,编译器仍然不会自动搜索操作系统上的公共包含目录.

示例: 用于链接IMPORTED lib的cmake代码

从我理解的CMake文档中,有三种方法可以链接未在整个应用程序/库的子项目中构建为目标的库.

CMake target_link_libraries()文档

  1. 将CMake软件包用于其中一个随附的软件包脚本.
  2. 使用链接器标志:

    target_link_libraries(<tgt> [SHARED|STATIC|...] -lncursesw)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 或者使用IMPORTED库方法(在顶部的代码中展示).

使用第二种方法时的一个主要区别是它只需要一行代码,并将搜索您操作系统上所有编译器的预定义包含目录.任何人都可以帮我理解为什么使用add_library()方法?


其他相关的SO帖子:

包含IMPORTED库的目录

CMake导入的库行为

tho*_*s_f 10

您应该add_library(<tgt> [SHARED|STATIC] IMPORTED)在需要设置属性(如依赖项,编译定义,编译标志等<tgt>)和/或扩展时使用任何链接的目标时使用<tgt>.

假设你有两个静态库; libfoobar.a并且libraboof.a,在libfoobar.a需要的地方libraboof.a.我们还要说这些库包含一些启用的功能-DSOME_FEATURE.

add_library(raboof STATIC IMPORTED)
set_target_properties(raboof PROPERTIES
    IMPORTED_LOCATION <path-to-libraboof.a>
    INTERFACE_COMPILE_DEFINITIONS "SOME_FEATURE"
)

add_library(foobar STATIC IMPORTED)
set_target_properties(foobar PROPERTIES
    IMPORTED_LOCATION <path-to-libfoobar.a>
    INTERFACE_LINK_LIBRARIES raboof
)
Run Code Online (Sandbox Code Playgroud)

所以当你链接到libfoobar.a:

add_executable(my_app main.cpp)
target_link_libraries(my_app foobar)
Run Code Online (Sandbox Code Playgroud)

CMake将确保以正确的顺序链接所有依赖项,并且在这种情况下-DSOME_FEATURE,在构建时也会附加到编译标志my_app.请注意,由于我们添加libraboof.a了依赖项libfoobar.a,因此-DSOME_FEATURE会添加到libfoobar.a通过传递属性链接的任何目标.

如果您不在add_library(<tgt> <SHARED|STATIC> IMPORTED)这样的场景中使用,则必须自己为每个目标管理任何依赖项和所需的构建选项,这非常容易出错.

此方法通常也Config用于多组件库的模块中,以管理组件之间的依赖关系.

  • 看不懂你回答的很清楚,能举个真实代码的例子吗? (2认同)