Linux编译过程

1.安装gcc,g++

在终端输入以下命令:

sudo apt install gcc

sudo apt install g++

就本质而言,gcc和g++并不是编译器,也不是编译器的集合,它们只是一种驱动器,根据参数中要编译的文件类型,调用对应的GUN编译而已。

更准确的说法:gcc调用了C编译器,而g++调用了C++编译器。

gcc和g++的主要区别
    1)对于 *.c和*.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的);
    2) 对于 *.c和*.cpp文件,g++则统一当做cpp文件编译;
    3)使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL;
    4)gcc在编译C文件时,可使用的预定义宏是比较少的;
    5)gcc在编译cpp文件时或者g++在编译c文件和cpp文件时(这时候gcc和g++调用的都是cpp文件的编译器),会加入一些额外的宏,这些宏如下:
    #define __GXX_WEAK__ 1
    #define __cplusplus 1
    #define __DEPRECATED 1
    #define __GNUG__ 4
    #define __EXCEPTIONS 1
    #define __private_extern__ extern
    6)在用gcc编译c++文件时,为了能够使用STL,需要加参数 –lstdc++ ,但这并不代表 gcc –lstdc++ 和 g++等价,它们的区别不仅仅是这个,主要参数:
    -g - turn on debugging (so GDB gives morefriendly output)
    -Wall - turns on most warnings
    -O or -O2 - turn on optimizations
    -o - name of the output file
    -c - output an object file (.o)
    -I - specify an includedirectory
    -L - specify a libdirectory
    -l - link with librarylib.a

注意:gcc可以编译c++文件

gcc -o mainc++ mainc++.cpp -lstdc++(指明用c++的标准库)

2.编译链接的四步

启动进程:路径+可执行文件名

可以把可执行文件放到 /usr/bin 就可以省略路径了

(1)预编译:

gcc -E main.c -o main.i

(2)编译

gcc -S main.i -o main.s

(3)汇编

gcc -c main.s -o main.o

(4)链接

gcc main.o -o main

执行: ./main

或者:全路径/main

(5)一步执行,省略中间过程

1)三步合为一步

即不经过预编译,编译,汇编三步,直接一步生成.o文件

 gcc -c main.c -o main.o

gcc -o main main.o

2)四步合一步

跳过中间部分从main.c到main语句:

gcc -o main main.c

(6)多个源文件执行

1)两步两步:

gcc -c main.c

gcc -c add.c

gcc -c max.

gcc -o main main.o add.o max.o

2)一步完成

gcc -o main main.c add.c max.c

3.编译链接过程

main.c 通过预编译 生成main.i文件

main.i 通过编译生成main.s 文件

main.s 通过汇编生成main.o 文件

链接阶段:将所有的.o .a(静态库文件) .lib(库文件) .obj文件链接起来,生成.out文件 ELF格式的可执行文件 .out文件(Windows生成的是.ext文件)

4.各阶段执行过程

(1)预编译阶段:

1)删除所有的"#define",并且展开所有的宏定义;

2)处理所有的条件预编译指令,"#if","#ifdef","#endif"等;

3)处理"#include"预编译指令,将被包含的文件插入到该预编译指令的位置;

4)删除所有的注释;

5)添加行号和文件名标识,以便于编译器产生调试用的符号信息及编译时产生编译错 误和警告时显示行号;

6)保留所有的#pragma编译器指令,因为编译器需要使用它们;

(2)编译阶段

词法分析,语法分析,语意分析,代码优化,汇总符号;

(3)汇编阶段

将汇编指令翻译成二进制格式,生成各个section,生成符号表

(4)链接阶段

1)合并各个section,调整section的起始位置和段大小,合并符号表,进行符号解析,给符 号分配虚拟地址;

2)符号重定位,即在使用符号的地方全部替换成符号的虚拟地址;