项目编译过程
- 预处理
- 编译
- 汇编
- 链接
1.预处理
首先新建preprocess.cpp文件,输入代码:
#include<iostream>
#define add(a,b) a+b
int main()
{
int c = 1;
int d = 2;
int e = add(c,d);
std::cout<<e<<std::endl;
return 0;
}
其中#define add(a,b) a+b为宏定义了两个数相加。生成预处理文件看看:
命令框输入
g++ --help
-E是生产预处理选项
输入命令:
g++ -o preprocess.i -E preprocess.cpp
生成preprocess.i预处理文件,vim打开后,非编辑模式下:/int main() ,然后回车可以找到main函数
add被替换了,这就是预处理的主要工作。
总结:预处理主要进行宏的展开,以及把头文件包进来,所以.i文件开起来很大,事实上.i文件依然是源文件,只不过做了一些符合计算机下一步工作的处理,因此叫做预处理。
2.编译
编译阶段是编译器将.i文件转换为.s文件,可以通过命令:
g++ -o preprocess.s -S preprocess.i
生产preprocess.s文件,打开可以看到都是汇编代码
另外:不同编译器有着不同的约定(比如__cdecl和__stdcall的约定;__fastcall约定)
编译器也做一些优化,gcc/g++编译时可以通过-O配置,有0,1,2,3,s共5中级别,0就是不做优化。
总结:编译过程就是通过语法分析,将其翻译成汇编代码
3.汇编
汇编阶段是汇编器将汇编代码翻译成机器指令,可以通过命令:
g++ -o preprocess.o -c preprocess.s
生成目标文件preprocess.o,其实就是二进制文件。
通过下面命令查看:
objdump -s -d preprocess.o
查看文件结构(符合ELF格式,参考https://blog.****.net/xuehuafeiwu123/article/details/72963229)
objdump -h preprocess.o
4.链接
由目标文件生成可执行文件,链接包括静态链接和动态链接。
g++ -o preprocess preprocess.o
生成可执行文件preprocess,./preprocess可直接执行。
静态链接:将静态库拷贝到可执行文件中;(文件较大)
动态链接:只记录相关信息,动态链接库的内容会映射到虚拟地址,通过映射关系来找到对应的代码。
-fPIC
http://blog.sina.com.cn/s/blog_54f82cc201011op1.html