GCC编译

作者: ag4kd | 来源:发表于2019-10-13 23:03 被阅读0次

    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 <iostream>
    
    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编译

          本文链接:https://www.haomeiwen.com/subject/xcxlmctx.html