当目标是静态库并且目标链接也是静态库时,“target_link_libraries”有什么作用?

What does 'target_link_libraries' do when the target is a static library and the target link is a static library too?

提问人:links4848 提问时间:7/12/2021 最后编辑:Foldalakelinks4848 更新时间:11/22/2023 访问量:4842

问:

从以下示例中:

CMakeList.txt 文件:

include_directories(inc)  

# Grab all the cpp and h files to be compile. 
file(GLOB SOURCES
    inc/*.h
    inc/*.hpp
    src/*.cpp
)

add_library(MyStaticLib STATIC ${SOURCES} )


target_link_libraries(MyStaticLib PUBLIC  "${OPENCV_LIBS}/opencv_world410.lib" )
target_link_libraries(MyStaticLib PUBLIC  "${OPENCV_LIBS}/opencv_world410d.lib" )

这会创建一个静态库吗?我以为你不能在 c++ 中将静态库链接到静态库?为什么这样做? 另外,最好的方法是什么?例如,如果我创建一个静态库的 API,即 MyStaticLib,并且它依赖于 opencv 的静态库,那么在 CMake 中设置它的最佳方法是什么?

C++ CMake 静态

评论


答:

6赞 Tsyvarev 7/12/2021 #1

总之

应用于静态库时,它不会影响生成的库文件。但它对目标的影响方式与对共享库目标的影响类似。target_link_libraries

因此,您可以以相同的方式将静态库和共享库一起使用。target_link_libraries

详细内容

应用于静态库时,不会立即影响此库的创建。也就是说,当创建静态库(作为文件)时,它不会存储该链接:target_link_libraries

add_library(MyStaticLib STATIC ${SOURCES} )
target_link_libraries(MyStaticLib PUBLIC  "${OPENCV_LIBS}/opencv_world410.lib")
# When file 'MyStaticLib.lib' will be created,
# it will NOT be linked with 'opencv_world410.lib'.

(您可能知道,静态库不存储有关链接的任何信息,静态库只是对象文件的集合。

但是,虽然具有静态库的文件不存储链接信息,但表示该静态库的 CMake 目标将“感知链接”。这在许多情况下都很有用:

  1. 如果在同一个项目中创建一个可执行文件或共享库,并将其与静态链接(使用 ),则该可执行文件实际上将与依赖库链接:target_link_libraries

    add_executable(myExe ...)
    target_link_libraries(myExe PRIVATE MyStaticLib)
    # When file 'myExe.exe' will be created, it WILL be linked with 'opencv_world410.lib'
    
  2. 如果在同一个项目中创建另一个静态库,并将其与静态库链接,则另一个静态库将与初始静态库及其依赖项“感知链接”。

    add_library(MyStaticLibAnother STATIC ..)
    target_link_libraries(MyStaticLibAnother PUBLIC MyStaticLib)
    # "As if" following line is executed
    # target_link_libraries(MyStaticLibAnother PUBLIC  "${OPENCV_LIBS}/opencv_world410.lib")
    
  3. 如果安装目标并使用命令 导出它,则可以使用 找到该库。这将创建一个静态库目标,该目标将意识到与其所有依赖项的链接install(TARGETS ... EXPORT ...)find_packagefind_package

    # [In main project]
    install(TARGETS MyStaticLib EXPORT MyProject)
    install(EXPORT MyProject NAMESPACE MyProject::)
    
    # [In another project]
    find_package(MyProject REQUIRED)
    # It creates the target MyProject::MyStaticLib which is
    # "aware of linkage" with 'opencv_world410.lib'.
    

此外,如果将静态库与目标(而不是纯文件)链接,并且该目标包含适用于编译阶段的编译定义或其他信息,则将使用该编译信息编译静态库。