为什么使用add_library({tgt} IMPORTED)与target_link_libraries(-l {.so | .a})? [英] Why use add_library({tgt} IMPORTED) versus target_link_libraries( -l {.so | .a})?

查看:1313
本文介绍了为什么使用add_library({tgt} IMPORTED)与target_link_libraries(-l {.so | .a})?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用该语句的目的是什么

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

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

示例: 制作链接到导入的lib的代码

从CMake文档中可以理解,实际上有3种方法可以链接未在整体应用程序/库的子项目中作为目标构建的库.

CMake target_link_libraries()文档

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

    target_link_libraries(<tgt> [SHARED|STATIC|...] -lncursesw)
    

  3. 或使用导入的库方法(在顶部的代码中显示).

使用第二种方法时的主要区别在于,它仅需一行代码,并且将在OS上搜索所有编译器的预定义包含目录.有人可以帮助我了解为什么使用add_library()方法吗?


其他已实现的SO帖子:

包含已导入库的目录

CMake导入的库行为

解决方案

只要需要设置属性,例如<tgt>的依赖项,编译定义,编译标志等,和/或通过扩展名,都应使用add_library(<tgt> [SHARED|STATIC] IMPORTED),与<tgt>链接的所有目标.

假设您有两个静态库; libfoobar.alibraboof.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将确保以正确的顺序链接所有依赖项,并且在这种情况下,还将在构建my_app时将-DSOME_FEATURE附加到编译标志中.请注意,由于我们添加了libraboof.a作为对libfoobar.a的依赖,因此-DSOME_FEATURE被添加到通过传递属性链接到libfoobar.a的任何目标.

如果在这种情况下不使用add_library(<tgt> <SHARED|STATIC> IMPORTED),则必须自己管理每个目标的任何依赖项和所需的构建选项,这很容易出错.

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

What is the purpose of using the statement:

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

From what I have found even if you create an imported library target above you still would need to specify the specific location of the actual .so or .a. This would take at least 3 cmake commands to link to an executable and the compiler still would not automatically search through the common include directories on your OS.

Example: cmake code to link IMPORTED lib

From the CMake documentation I understand there are really 3 ways to link a library that is not built as a target in a subproject of your overall application/library.

CMake target_link_libraries() documentation

  1. Using a CMake package for one of the shipped package scripts.
  2. Using a linker flag:

    target_link_libraries(<tgt> [SHARED|STATIC|...] -lncursesw)
    

  3. Or using the IMPORTED library method (showcased in code at top).

A major difference when using the second method is that it only takes a single line of code and will search through all of your compiler's predefined include directories on you OS. Could anyone help me understand why the add_library() method is used?


Additional Realated SO Posts:

Include directories for IMPORTED libs

CMake imported library behavior

解决方案

You should use add_library(<tgt> [SHARED|STATIC] IMPORTED) whenever you need to set properties such as dependencies, compile definitions, compile flags etc for <tgt>, and/or by extension, any targets that are linking against <tgt>.

Let's say you have two static libraries; libfoobar.a and libraboof.a, where libfoobar.a requires libraboof.a. Let's also say that these libraries contain some features that are enabled by -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
)

So when you link against libfoobar.a:

add_executable(my_app main.cpp)
target_link_libraries(my_app foobar)

CMake will make sure to link all dependencies in the correct order and will in this case also append -DSOME_FEATURE to the compile flags when you build my_app. Note that since we added libraboof.a as a dependency to libfoobar.a, -DSOME_FEATURE is added to any target that link against libfoobar.a through the transitive property.

If you don't use add_library(<tgt> <SHARED|STATIC> IMPORTED) in a scenario like this, you would have to manage any dependencies and required build options yourself for each target, which is quite error-prone.

This method is also often used in Config-modules for multi-component libraries to manage dependencies between the components.

这篇关于为什么使用add_library({tgt} IMPORTED)与target_link_libraries(-l {.so | .a})?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆