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

lin*_*848 6 c++ static cmake lib

从下面的例子来看:

\n

CMakeList.txt 文件:

\n
include_directories(inc)  \n\n# Grab all the cpp and h files to be compile. \nfile(GLOB SOURCES\n    inc/*.h\n    inc/*.hpp\n    src/*.cpp\n)\n\nadd_library(MyStaticLib STATIC ${SOURCES} )\n\n\ntarget_link_libraries(MyStaticLib PUBLIC  "${OPENCV_LIBS}/opencv_world410.lib" )\ntarget_link_libraries(MyStaticLib PUBLIC  "${OPENCV_LIBS}/opencv_world410d.lib" )\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

Tsy*_*rev 6

简而言之

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

因此,您可以target_link_libraries以相同的方式将两者用于静态库和共享库。

详细信息

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

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'.
Run Code Online (Sandbox Code Playgroud)

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

但是,虽然带有静态库的文件不存储链接信息,但代表该静态库的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'
    
    Run Code Online (Sandbox Code Playgroud)
  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")
    
    Run Code Online (Sandbox Code Playgroud)
  3. 如果您安装库目标并使用命令导出install(TARGETS ... EXPORT ...)它,则可以使用 找到该库find_package。这find_package将创建一个静态库目标,它将意识到与其所有依赖项的链接:

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

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