C语言嵌入式Linux下最常用的C语言编译器GCC命令详解

GCC(GNU Compiler
Collection)是Linux下最为常用之C语言编译器,是GNU项目中称ANSI
C标准的编译系统,能够编译用C、C++和Object
C等语言编写的顺序。同时它可以由此不同之前端模块来支持各种语言,如Java、Fortran、Pascal、Modula-3和Ada等。

穿插一个玩笑: GNU意思是GNU’s not
Unix而无角马。然而GNU还是一个不拆分的连词,这其实是一个自hacker的诙谐:GNU是一个回文游戏,第一单字母G是凝聚的,你本可以于他做ANU或者BNU。下面开始。

一.CC编译顺序过程分四只号

◆ 预处理(Pre-Processing)

◆ 编译(Compiling)

◆ 汇编(Assembling)

◆ 链接(Linking)

Linux程序员可以根据自己之急需吃GCC在编译的别样等级了转去反省或者用编译器在该阶段的出口信息,或者对最后生成的二进制文件进行支配,以便通过参加不同数额以及类别之调节代码来为日后底调试做好准备。如同其他的编译器,GCC也供了灵活而强劲的代码优化功能,利用它好转执行效率还强之代码。

GCC提供了30基本上长警告信息以及老三单警示级别,使用她有助于增强程序的祥和和可移植性。此外,GCC还对专业的C和C++语言进行了大量的恢宏,提高程序的推行效率,有助于编译器进行代码优化,能够减轻编程的工作量。

二.简单编译命令

我们因为Hello world程序来起我们的读。代码如下:

/* hello.c */

#include 

int main(void)

{

printf (“Hello world!\n”);

return 0;

}

  1. 尽如下命令:$ gcc -o hello hello.c

运行而下 : $ ./hello

输出: Hello,world!

  1. 我们吧得分步编译如下:

(1) $ gcc –E hello.c -o hello.i

//预处理完

//这下你看一下hello.i ,可以看出插进去了好多东西。

(2) $ gcc –S hello.i

//生成汇编代码后了

(3) $ gcc –c hello.c

或者:

$ gcc -c hello.c –o hello.o

或者:

$ gcc -c hello.i -o hello.o

//编译结束

//生成 hello.o文件

(4) $ gcc hello.o –o hello.o

或者:

$ gcc –o hello hello.c

//链接了,生成可实行代码

  1. 咱得以拿几乎单公文并编译生成同一个可执行文件。

仍:一个工程来main.c foo.c def.c生成foo的可执行文件。

编译命令如下:

$ gcc –c main.c foo.c def.c –o foo

或者:

$ gcc –o foo main.c foo.c def.c

三.库依赖

函数库是一些匹文件(.h)和仓库文件(.so或者.a)的会师。Linux下的大多数函数都默认将头文件放到/usr/include/目录下,而储藏室文件则放/usr/lib/目录下,但不要绝对如此。因此GCC设有补加头文件和库房文件之编译选项开关。

  1. 填补加头文件:-I

如在/home/work/include/目录下出编译foo.c所需头文件def.h,为了吃GCC能找到她,就需要采取-I选项:

$ gcc foo.c -I /home/work/include/def.h -o foo

  1. 增补加库文件:-L

譬如在/home/work/lib/目录下出链接所需库文件libdef.so,为了让GCC能找到其,就需用-L选项:

$ gcc foo.c –L /home/work/lib –ldef.a –o foo

证明:-l选项指示GCC去连接库文件libdef.so。Linux下之库文件命名有一个预约,即库文件为lib三只假名开头,因为具有的库文件都随这约定,故在用-l选项指定链接的库文件名时可以省去lib三独假名。

题外语:

Linux下的库文件分为动态链接库(.so文件)和静态链接库(.a文件)。GCC默认为动态库优先,若想在动态库和静态库同时有的时刻链接静态库需要指明为-static选项。比如达例被设还有一个libdef.a而若想链接libdef.a时候吩咐如下:

$ gcc foo.c –L /home/work/lib –static –ldef.a –o foo

四.代码优化

GCC提供不同档次的代码优化功能。开关选项是:-On,n取值为0交3。默认为1。-O0意味不曾优化,而-O3凡是高优化。优化级别越强代码运行越快,但连无是装有代码都能加载最高优化,而当看到具体情况而早晚。但貌似还用-O2挑项,因为它们以优化长度、编译时间和代码大小之间,取得了一个较完美之平衡点。

以下就段说之可比详细:

编译时使用选择-O可以告知GCC同时减多少代码的尺寸及履时,其意义相当于价于-O1。在当时同级别达能进行的优化种虽然在目标电脑,但一般还见面席卷线程跳转(Thread
Jump)和延迟退栈(Deferred Stack
Pops)两种植优化。选项-O2告知GCC除了成功有着-O1级别的优化之外,同时还要开展有外加的调工作,如计算机指令调度等。选项-O3虽除外成功所有-O2级别之优化之外,还包循环展开和另一些及电脑特性相关的优化办事。通常来说,数字越充分优化的号越强,同时为不怕表示程序的运行速度越来越快。

脚通过具体实例来感受一下GCC的代码优化功能,所用程序一旦清单3所著。

/* optimize.c */

#include

int main(void)

{

double counter;

double result;

double temp;

for (counter = 0;

counter < 2000.0 * 2000.0 * 2000.0 / 20.0 + 2020;

counter += (5 – 1) / 4) {

temp = counter / 1979;

result = counter;

}

printf(“Result is %lf\n”, result);

return 0;

}

先是不加其它优化增选进行编译:

# gcc -Wall optimize.c -o optimize

借助Linux提供的time命令,可以约统计出该次在运作时所用之日子:

# time ./optimize

Result is 400002019.000000

real 0m14.942s

user 0m14.940s

sys 0m0.000s

联网下使用优化增选来针对代码进行优化处理:

# gcc -Wall -O optimize.c -o optimize

以平的尺度下再也测试一下周转时刻:

# time ./optimize

Result is 400002019.000000

real 0m3.256s

user 0m3.240s

sys 0m0.000s

对比两不成执行的出口结果不难看出,程序的性质的确得到了异常特别开间的改良,由原来的14秒缩短至了3秒。这个事例是专门对GCC的优化作用要计划的,因此优化前后程序的实践进度发出了颇怪之改观。尽管GCC的代码优化功能很有力,但当一如既往名叫好的Linux程序员,首先还是一旦力求能手工编制出大质量之代码。如果编写的代码简短,并且逻辑性强,编译器就无见面开还多之做事,甚至从来用不着优化。

优化虽然能被程序带来双重好之履行性,但当如下一些场地着应当避免优化代码:


程序开发之下优化等越强,消耗以编译上的光阴就是进一步长,因此在付出的时刻太不用以优化增选,只出到软件发行或开发了之时光,才考虑针对终极生成的代码进行优化。


资源受限的时节有的优化增选会多而实行代码的体积,如果程序在运作时亦可申请到的内存资源异常紧张(如有些实时嵌入式设备),那就毫无对代码进行优化,因为由当时带来的负面影响可能会见时有发生十分重的后果。


跟踪调试之时在针对代码进行优化的上,某些代码可能会见吃删去或改写,或者为获得更了不起之属性而展开重组,从而使跟踪及调试变得死去活来困难。