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

时间:2018-03-26 01:19:20

标签: cmake libraries build-system

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

add_library(<tgt> [SHARED|STATIC] IMPORTED)

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

实施例: cmake code to link IMPORTED lib

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

CMake target_link_libraries() documentation

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

    target_link_libraries(<tgt> [SHARED|STATIC|...] -lncursesw)
    
  3. 或使用IMPORTED库方法(在顶部的代码中展示)。
  4. 使用第二种方法时的一个主要区别是它只需要一行代码,并将搜索您操作系统上所有编译器的预定义包含目录。任何人都可以帮我理解为什么使用add_library()方法吗?


    其他相关的SO帖子:

    Include directories for IMPORTED libs

    CMake imported library behavior

1 个答案:

答案 0 :(得分:6)

每当需要设置add_library(<tgt> [SHARED|STATIC] IMPORTED)的依赖关系,编译定义,编译标志等属性时,都应该使用<tgt>,和/或扩展名为{{1}链接的任何目标}。

假设您有两个静态库; <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 )

libfoobar.a

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

如果你不在这样的场景中使用libfoobar.a,你必须自己为每个目标管理任何依赖项和所需的构建选项,这很容易出错。

此方法也常用于add_library(<tgt> <SHARED|STATIC> IMPORTED) - 多组件库的模块,以管理组件之间的依赖关系。