gcc编译过程概述

    本文对gcc编译器如何工作做一个概要描述更为详细的信息请参考编译器手册。gcc编译器是GNU的一个编译套件。  

一、概要描述:

当我们进行编译的时候要使用一系列的工具我们称之为工具链其中包括预处理器CPP编译器前端gcc/g++汇编器as连接器ld(在Linux中都是文件一个编译过程包括下面几个阶段:

  (1)预处理预处理器CPP将对源文件中的宏进行展开,并在其中插入#include文件所包含的内容,预处理为.i文件

  (2)编译编译器前端gcc/g++将.i文件编译成汇编文件(.s)。 

  (3)汇编汇编器as将汇编文件编译成目标文件(.o)[机器码(二进制文件)]。 

  (4)连接器ld将目标文件和外部符号进行连接,得到一个可执行二进制文件(.out)

以上文件后缀为默认后缀,可以使用-o或>自定义文件名及后缀(建议自定义)。

编译过程与(2)编译强调的是不同的概念,不要将两个编译混淆。

二、例题解述:

    下面以一个很简单的test.c来探讨这个过程。

    #define NUMBER  (1+2)

    int main() 

   {      

       int x=NUMBER;       

       return 0;  

1)预处理:gcc会首先调用CPP进行预处理——CPP test.c >test.i

或者gcc -E test.c -o test.i(使用-E选项告诉GCC预处理后停止编译过程) 

预处理的输出为文件test.i。 我们用cat test.i查看test.i的内容如下:

    int main() 

   {  

      int x=(1+2);    

      return 0; 

    }  

    我们可以看到,文件中宏定义NUMBER出现的位置被(1+2)替换掉了,其它的内容保持不变。 

 

     (2)编译编译器前端gcc/g++将.i文件编译成汇编文件(.s)——gcc -S test.i

    得到的输出文件为test.s [注意:S大写,否则生成默认可执行文件a.out]

 

     (3)汇编汇编器as将汇编文件编译成目标文件(.o)——as test.s -o test.o 

    得到输出文件为test.o。(test.o中为目标机器上的二进制文件。)用nm查看文件中的符号——nm test.o

    输出如下:   

    00000000 b .bss  

    00000000 d .data     

    00000000 t .text   

    U ___main     

    U __alloca  

    00000000 T _main 

    既然已经是二进制目标文件了,能不能执行呢?试一下./test.o提示cannot execute binary file.原来___main前面的U表示这个符号的地址还没有定下来,T表示这个符号属于代码段。ld连接的时候会为这些带U的符号确定地址。

    注:(2)(3)指令相当于 gcc -x i-output -c test.i -o test.o

-x 选项告诉GCC从指定的步骤开始编译,-c 选项告诉GCC编译、汇编后停止编译过程。

 

    (4)连接器ld将目标文件和外部符号进行连接,得到一个可执行二进制文件(.out)——gcc test.o>test

     链接需要指定库的位置。通常程序中会有很多的外部符号,因此需要指定的位置就会很多。不过,我们需要调用gcc即可,ld会自己去找这些库的位置——gcc test.o>test就得到了最终的可执行程序了。

    注:gcc test.o -o test 仅表示将目标文件链接生成可执行文件;

        gcc test.c -o test 表示经过整个编译过程后生成可执行文件

       (test.c是指真正意义上的c源文件,非用户自定义的后缀名为.c的其他属性的文件。)

三、综述:

万幸的是上述四步可由——gcc filemane -o outputfilename 语句执行完成。如下:

   CPP test.c >test.i + gcc -S test.i + as test.s >test.o + gcc test.o >test = gcc test.c -o test   (最后的可执行程序名自定义为test,不会默认生成a.out,自定义时文件名及后缀都由自己定。)['>'与'-o'效果一样]。

    最后输入./test(不能有空格) 运行该可执行文件。

四、流程图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值