当目标是静态库而目标链接是静态库时,target_link_libraries 会做啥
Posted
技术标签:
【中文标题】当目标是静态库而目标链接是静态库时,target_link_libraries 会做啥【英文标题】:What does target_link_libraries do when the target is a static library and the taarget link is a static library当目标是静态库而目标链接是静态库时,target_link_libraries 会做什么 【发布时间】:2021-07-12 02:07:54 【问题描述】:从下面的例子:
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 中设置它的最佳方法是什么?
谢谢大家。 真挚地, 来自 Old-School 的 Frank。
【问题讨论】:
【参考方案1】:总之
target_link_libraries
应用于静态库时,不会影响生成的库文件。但它以类似的方式影响目标,因为它会影响共享库的目标。
因此,您可以以相同的方式将target_link_libraries
用于静态库和共享库。
详细介绍
当应用于 static 库时,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 目标 将“意识到链接”。这在很多情况下都很有用:
如果您在同一个项目中创建可执行文件或共享库,并将其与静态库链接(使用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'
如果您在同一个项目中创建另一个静态库,并将其与静态库链接,则另一个静态库将“意识到”与初始静态库及其依赖项的链接。
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")
如果您安装您的库目标并使用命令install(TARGETS ... EXPORT ...)
导出它,则可以使用find_package
找到该库。 find_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'.
此外,如果您将静态库与 target(而不是普通文件)链接,并且该目标包含适用于编译阶段的编译定义或其他信息,则静态库将是编译使用该编译信息。
【讨论】:
以上是关于当目标是静态库而目标链接是静态库时,target_link_libraries 会做啥的主要内容,如果未能解决你的问题,请参考以下文章