项目编译过程

  • 预处理
  • 编译
  • 汇编
  • 链接

项目编译过程

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