GCC编译

1.1 GCC编译C/C++的四个过程

gcc 是 GUN Compiler Collection的缩写。

取自网络.png
  • 预处理(pre-processing)E:插入头文件,替换宏
  • 编译(Compiling)S:编译成汇编
  • 汇编(Assembling) c:编译成目标文件
  • 链接 (Linking):链接到库中,变成可执行文件

gcc -E main.c -o main.i

gcc -S main.i –o main.s

gcc –c main.s –o main.o

gcc main.o –o main :链接,生成可执行文件

./main 

也可以一次性完成:

gcc main.c –o main

但一般情况下生成.o文件比较好,可以重定位文件,让别人使用

1.1.1 预处理

C语言代码在交给编译器之前,会先由预处理器进行一些文本替换方面的操作,例如宏展开、文件包含、删除部分代码等。

在正常的情况下,GCC 不会保留预处理阶段的输出文件,也即 .i 文件。然而,可以利用 -E 选项保留预处理器的输出文件,以用于诊断代码。-E选项指示 GCC 在预处理完毕之后即可停止。

a、默认情况下,预处理器的输出会被导入到标准输出流(也就是控制台)

gcc -E main.c 

b、可以利用-o选项把它导入到某个输出文件

gcc -E main.c -o main.i

或者

 gcc -E main.c > main.i 

表示把预处理的结果导出到 main.i 文件中。

c、使用-C选项阻止预处理器删除源文件和头文件中的注释。

注意,这里是大写的 -C,不是小写的 -c。小写的 -c 表示只编译不链接。

gcc -E -C main.c -o main.i 

对比之前的输出,可以发现,保留愿文件中的注释

1.1.2 编译阶段

编译器的核心任务是把C程序翻译成机器的汇编语言(assembly language)。

汇编语言是人类可以阅读的编程语言,也是相当接近实际机器码的语言。每种 CPU 架构都有不同的汇编语言。

实际上,GCC 是一个适合多种 CPU 架构的编译器,不会把C程序语句直接翻译成目标机器的汇编语言,而是在输入语言和输出汇编语言之间,利用一个中间语言,称为 RegisterTransfer Language(简称 RTL,寄存器传输语言)。借助于这个抽象层,在任何背景下,编译器可以选择最经济的方式对给定的操作编码。

通常情况下,GCC 把汇编语言输出存储到临时文件中,并且在汇编器执行完后立刻删除它们。但是可以使用-S选项,让编译程序在生成汇编语言输出之后立刻停止,而不删除临时文件。

-S可以理解为Save或者Stop,自己的理解仅供参考记忆。

如果没有指定输出文件名,那么采用-S选项的 GCC 编译过程会为每个被编译的输入文件生成以.s作为后缀的汇编语言文件。如下例所示:

gcc -S ts.c   

编译器预处理 ts.c,将其翻译成汇编语言,并将结果存储在 ts.s 文件中,可以用文本编辑器察看.

指定输出文件名

gcc -S main.i -o filename.s

1.1.3 汇编阶段

-c选项:只编译不链接,仅生成目标文件。

目标文件是一种中间文件或者临时文件,如果不设置该选项,gcc 一般不会保留目标文件,可执行文件生成完成后就自动删除了。

注意,使用-c选项表示只编译源文件,而不进行链接,因此,对于链接中的错误是无法发现的。

比如,调用一个不存在的函数,编译器会提示的错误。但是该命令不会输出错误信息。

gcc -c main.s -o main.o

1.1.4 链接阶段

gcc main.o -o main.exe

1.2 clang 分四步编译main.c

这里用的clang/clang++ 分四步编译main.c/main.cpp文件

1.2.1 预处理

clang++ -E main.cpp -o main.ii

1.2.2 编译阶段,生成汇编

clang++ -S main.ii -o main.s 

1.2.3 汇编阶段,生成目标文件

 clang++ -c main.s -o mian.o

1.2.4 连接阶段

 clang++ mian.o -o main

1.2.5 执行

 ./main

1.2.6 源文件

#include 

int main() {
    std::cout << "Hello Biter !" << std::endl;
    return 0;
}

1.2.7 四部曲之一步到胃

clang++在编译的过程中,保存所有编译过程中产生的文件

1.2.8 产生中间文件

 clang++ -save-temps main.cpp -o main

1.2.9 不保存中间文件

 clang++  main.cpp -o main

你可能感兴趣的:(GCC编译)