静态链接和动态链接
1.编译
- 预处理:处理一些#号定义的命令或语句(如宏、#include、预编译指令#ifdef等),生成*.i文件;
- 编译:主要是进行词法分析、语法分析和语义分析等,生成*.s的汇编文件;
- 汇编:这个过程将对应的汇编指令翻译成机器指令,生成可重定位的二进制目标*.o文件。
https://blog.csdn.net/kang___xi/article/details/80210717
2.链接
https://blog.csdn.net/qq_26079093/article/details/101175146
静态链接和动态链接两者最大的区别就在于链接的时机不一样,静态链接是在形成可执行程序前,而动态链接的进行则是在程序执行时。
//也就是说,生成.o文件后就要生成可执行程序。
- 静态链接的过程就已经把要链接的函数或过程已经链接到了生成的可执行文件中,可执行文件中包含了运行所需的全部代码,把静态库删除也不会影响执行;将相互依赖的*.o目标文件链接为可执行文件ELF。
- 动态链接没有把内容链接进去,连接时只是加入了一些重定位信息,而是在执行的过程中,再去找要链接的内容,生成的可执行文件中并没有要链接的内容,所以当删除动态库时,可执行程序就不能运行。
静态链接:空间浪费、更新困难。
静态链接重定位放在了生成可执行文件时,而动态链接将重定位放在了加载时。
静态链接库:win:.lib linux:.a
动态链接库:win:.ddl linux: .so
4.动态链接过程
http://chuquan.me/2018/06/03/linking-static-linking-dynamic-linking/
装载时重定位,不是在链接过程中将所有的.o文件合并。
但是如果所有的文件都共享一个文件的话,可能会产生相互修改影响的错误,不同函数修改同一个地址空间,这就需要地址无关代码的技术。
地址无关代码:
把指令中那些需要被修改的部分分离出来,跟数据部分放在一起,这样指令部分就可以保持不变,而数据部分可以在每个进程中拥有一个副本。
5.cmake中静态和动态
target_link_libraries(可执行文件名 静态库 动态库)
-
对于静态库(
.a
文件),链接时会将库的目标文件直接合并到最终生成的可执行文件中。这就意味着,最终的可执行文件包含了静态库中的代码,而不再依赖于外部的库文件。 -
对于动态库(
.so
文件),链接时只会在可执行文件中创建对动态库的引用。最终的可执行文件不包含动态库中的代码,而是在运行时动态加载动态库。在这种情况下,你的系统必须能够找到和加载动态库文件,通常是在运行时通过动态链接器进行。
这两种方式有各自的优缺点。静态库的优点是可执行文件独立于外部库,但缺点是可执行文件较大。动态库的优点是可执行文件较小,但缺点是在运行时需要确保系统能够找到正确版本的动态库。