(编程小白,欢迎大家一起探讨)
Linux环境中C++程序编译过程分为四个过程:预处理,编译,汇编,链接
-
编译预处理:处理以#开头的指令,头文件展开,宏定义替换,删除注释,生成.i文件;
-
编译、优化:词法检查,语法检查,权限检查, 代码优化,将.i文件翻译成.s汇编代码
-
汇编:将汇编代码.s翻译成机器指令二进制.o文件
-
链接:汇编程序生成的目标文件,并不会立即执行,因为可能存在以下情况:.cpp文件中的函数引用了另一个.cpp文件中定义的符号或者调用了某个库文件中的函数。链接的目的就是将这些文件对应的目标文件连接成一个整体,从而生成可执行的.out文件
链接分为两种: -
静态链接:代码从其所在的静态链接库中拷贝到最终的可执行程序中,在该程序被执行时,这些代码会被装入到该进程的虚拟地址空间中。
-
动态链接:代码被放到动态链接库或共享对象的某个目标文件中,链接程序只能在最终的可执行程序中记录了共享对象的名字等一些信息。在程序执行时,动态链接库的全部内容会被映射到运行时相应进行的虚拟地址的空间。
Linux环境下静态库、动态库制作:
//静态库
ar rcs lib库名.a *.o
g++ test.cpp lib库名.a -o a.out
//动态库
g++ -c *.c -o *.o -fPIC //-fPIC 生成与位置无关的代码
g++ -shared -o lib库名.so *.o
g++ test.cpp -o a.out -L./lib库名
//此时会报错,因为创建的动态库未添加到环境变量 LD_LIBRARY_PATH中
//cannot open shared object file: No such file or direct
//解决方法1 export LD_LIBRARY_PATH=pwd:$LD_LIBRARY_PATH 暂时性
//解决方法2 将动态链接库路径写入终端配置文件~/.bashrc中 sourse后永久有效
二者的优缺点:
- 静态链接:浪费空间,每个可执行程序都会有目标文件的一个副本,这样如果目标文件进行了更新操作,就需要重新进行编译链接生成可执行程序(更新困难);优点就是执行的时候运行速度快,因为可执行程序具备了程序运行的所有内容。
- 动态链接:节省内存、更新方便,但是动态链接是在程序运行时,每次执行都需要链接,相比静态链接会有一定的性能损失。