美文网首页
GCC/G++编译过程

GCC/G++编译过程

作者: 不懂球的2大业 | 来源:发表于2019-10-16 13:37 被阅读0次

    1. gcc/g++简介

    • gcc / g++分别是GNU的c & c++编译器,常用于在Linux下编译C/C++程序,详细介绍
      gcc
    • gcc / g++执行编译的基本步骤主要有四步:
      第一步,由后缀为.c/.cpp的源程序生成后缀为.i的预处理文件,预处理文件本质也是c/cpp源程序,只是进行了头文件展开和宏替换;
      第二步,由后缀为.i的预处理文件生成后缀为.s的汇编文件,这一步是将源程序转化为汇编指令;
      第三步,由后缀为.s的汇编文件生成后缀为.o的机器代码,即二进制文件,但是这时候还不可以执行;
      第四步,把后缀为.o的机器代码链接生成可执行文件(默认后缀为.out)。
    • 简单表示:①test.cpp(第一步)—>②test.i(第二步)—>③test.s(第三步)—>④test.o(第四步)—>⑤test.out。

    2. gcc/g++基本命令

    下面,我们将运行实例演示上述过程。

    2.1 g++ -o

    • 作用:指定生成目标文件的名字,生成目标文件。若不加任何替他参数,则直接由源程序生成可执行文件。-o表示output name,后面输入指定生成文件的名字。
    • 例子:
    # 命令行输入:
    g++ test.cpp -o test.out 
    

    说明:该例子指定生成文件的名字为test.out,且没有加任何替他参数,因此最终生成可执行文件test.out,相当于上面由①test.cpp——>⑤test.out。其中test.cpp文件为:

    #include <iostream>
    
    using namespace std;
    
    int main(){
        cout << "Hello World" <<endl;
        return 0; 
    }
    

    结果:生成可执行文件test.out,对test.out文件运行:

    #当前目录下命令行输入:
    ./test.out
    #输出:
    Hello World
    

    2.2 g++ -E

    • 作用:相当于1中介绍的第一步,把头文件展开,宏替换,生成的目标文件为C文件。
    • 例子:
    # 命令行输入:
    g++ test.cpp -E -o test.i
    

    说明:该例子指定生成文件的名字为test.i,且有参数-E,因此经过预处理,由源程序test.cpp生成test.i预处理文件。相当于上面由①test.cpp—>②test.i。test.cpp文件与2.1相同。
    结果:生成预处理文件test.i。我这里生成的.i文件大约有20000多行代码。

    # test.i部分代码展示:
    # 1 "test.cpp"
    # 1 "<built-in>"
    # 1 "<command-line>"
    # 1 "/usr/include/stdc-predef.h" 1 3 4
    ......这里省略好多代码
    # 63 "/usr/include/c++/7/bits/memoryfwd.h" 3
      template<typename>
        class allocator;
      template<>
        class allocator<void>;
      template<typename, typename>
        struct uses_allocator;
    }
    ......这里省略好多代码
    

    接着对生成的test.i文件进行处理:

    # 命令行输入:
    g++ test.i -o test.out
    

    说明:相当于上面由②test.i—>⑤test.out,对test.out文件运行,与2.1结果相同。

    ./test.out
    #输出:
    Hello World
    

    2.3 g++ -S

    • 作用:相当于1中介绍的第一步和第二步,生成汇编文件。
    • 例子:
    # 命令行输入:
    g++ -S test.cpp -o test.s
    

    说明:该例子指定生成文件的名字为test.s,且有参数-S,因此经过1中所说的第一步、第二步,由源程序test.cpp生成test.s汇编文件。相当于上面由①test.cpp—>③test.s。test.cpp文件与2.1相同。
    结果:生成汇编文件test.s,约90行左右,如下所示:

    /*
    * test.s部分代码展示:
    */
        .file   "test.cpp"
        .text
        .section    .rodata
        .type   _ZStL19piecewise_construct, @object
        .size   _ZStL19piecewise_construct, 1
    _ZStL19piecewise_construct:
        .zero   1
        .local  _ZStL8__ioinit
        .comm   _ZStL8__ioinit,1,1
    .LC0:
        .string "Hello world"
        .text
        .globl  main
        .type   main, @function
    main:
    .LFB1493:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
    ......这里省略好多代码
    

    接着对生成的test.s文件进行处理:

    #命令行输入:
    g++ test.s -o test.out
    

    说明:相当于上面由③test.s——>⑤test.out。对生成的test.out文件运行,与2.1结果相同。

    ./test.out
    #输出:
    Hello World
    

    2.4 g++ -c

    • 作用:相当于1中的第一步、第二步和第三步合起来,生成二进制文件,有待进一步链接成可执行文件。
    • 例子:
    #命令行输入:
    g++ -c test.cpp -o test.o
    

    说明:该例子指定生成文件的名字为test.o,且有参数-c,因此相当于经过1中所说的第一步、第二步和第三步,由源程序test.cpp生成test.o二进制文件。相当于由①test.cpp—>④test.s。test.cpp文件与2.1相同。
    结果:生成二进制文件test.o,但是还不能执行。
    接着对生成的test.o文件进行处理:

    # 命令行输入:
    g++ test.o -o test
    

    说明:相当于上面由④test.o——>⑤test.out。对生成的test.out文件运行,与2.1结果相同。

    ./test.out
    #输出:
    Hello World
    

    相关文章

      网友评论

          本文标题:GCC/G++编译过程

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