target_link_libraries的作用本质
链接的本质
链接动态库
链接动态库时的本质是:
一个可执行文件通过target_link_libraries链接一个动态库,只会在可执行文件运行起来的时候,那么程序运行的时候,由什么工具主动加载这个动态库,这个工具需要知道去哪里加载这个动态库,加载的路径怎么设置的?
动态库加载工具
当一个可执行文件通过 target_link_libraries 链接到动态库(共享库)时,程序在运行时使用操作系统的动态链接器(或加载器)来加载这个动态库。
动态库的加载路径
动态链接器负责在程序运行时解析库的依赖关系并将所需的共享库加载到内存中。 加载动态库的工具 在大多数操作系统中,加载动态库的工具是操作系统提供的动态链接器。
例如:
在Linux系统中,通常是ld.so或ld-linux.so。
在Windows系统中,通常是kernel32.dll内的LoadLibrary函数。
动态库的加载路径 动态链接器需要知道去哪里查找动态库,通常通过以下几种方式来确定加载路径:
RPATH(运行时路径):在编译时,可以通过设置 INSTALL_RPATH 或者 RPATH 属性指定库的搜索路径。这些路径会被嵌入到可执行文件的元数据中。
RPATH 是可执行文件中的路径列表,指示程序在运行时从这些路径中查找动态链接库。在CMake中,设置 RPATH 可以使用 `set_target_properties()` 命令中的 `INSTALL_RPATH` 属性或 `BUILD_WITH_INSTALL_RPATH` 属性来进行设置。 例如: ``` set_target_properties(example PROPERTIES INSTALL_RPATH "/usr/local/lib")
LD_LIBRARY_PATH:在Linux系统中,可以通过设置环境变量 LD_LIBRARY_PATH 来指定动态库的搜索路径。该环境变量中列出了多个路径,动态链接器会在这些路径中查找所需的动态库。 系统默认路径:动态链接器还会检查系统的默认库路径。例如,在Linux系统中,常见的库路径包括 /lib 和 /usr/lib 等。
配置文件:在Linux中,还可以通过配置文件(如 /etc/ld.so.conf)来指定库的搜索路径。更新后,需要运行 ldconfig 来使其生效。
可执行文件的相对路径:如果可执行文件和动态库位于同一目录或子目录中,动态链接器通常也可以自动找到它。
加载和链接的区别
链接与加载的区别:
链接:target_link_libraries 指令主要用于指定可执行文件在编译和链接阶段需要依赖的库。这意味着在生成可执行文件时,编译器会将库的符号信息嵌入到可执行文件中,使得可执行文件在运行时能够找到这些库。
(运行)链接阶段:符号解析+重定位
可执行文件中有的只是动态库中的符号,并没有执行这个符号需要的地址,而这个地址需要自运行(链接)阶段通过从指定的路径中加载动态库到物理内存中之后才有。
加载:真正的加载是在程序运行时,由操作系统的动态链接器进行的。动态链接器会根据特定的搜索路径查找并加载这些库。
所以target_link_libraries的本质只是将可执行文件中需要用到的符号嵌入可执行文件,并不指定加载这个库的路径。
链接静态库
target_link_libraries链接的是动态库还是静态库
target_link_libraries和link_libraries
冒号
target_link_libraries(
test_exec
PUBLIC basic_hunk::basic_hunk
)
冒号的含义: