n熟练掌握Linux GCC的使用操作方法
1.2实验内容
n综合运用Linux GCC的技巧操作。
n利用GCC编译器编译程序
1、实验要求:
编写一个应用程序,使用gcc进行编译,并分别使用-o,-g,-static,-O2等选项,了解这些选项的作用。
2、实验器材:
软件:
安装了ubuntu的VMware虚拟机。
硬件:
PC机一台。
3、背景知识:
ügcc的概念:
GCC(GNU CompilerCollecti on,GNU编译器套装),是一套由GNU开发的编程语言编译器。它是一套以GPL及LGPL许可证所发行的自由软件,也是GNU计划的关键部分,亦是自由的类Unix及苹果电脑MacOSX操作系统的标准编译器。GCC原名为GNU C语言编译器,因为它原本只能处理C语言。GCC很快地扩展,变得可处理C++。之后也变得可处理For tr an、Pascal、Obj ecti v e-C、Jav a,以及Ada与其他语言。我们使用的gcc命令主要是用于处理c语言程序。
ügcc的执行过程:
虽然我们称Gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤∶预处理(也称预编译,Preprocessing)、编译( Compilation)、汇编( Assembly)和链接( Linki ng)。命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含( i
ncl ude)、预编译语句(如宏定义define等)进行分析。接着调用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的库中连到合适的地方。以上这些过程是gcc内部实现的机制,实际使用中,上述过程可以又通过gcc的选项实现,具体方法请通过实验体会。
4、实验步骤
ü先用vim编辑hello.c文件,内容如图所示:
图1vim编写hello.c
ügcc命令的一般格式为:gcc[选项]要编译的文件[选项][目标文件]。
下面使用命令gcchello.c–ohello,编译hello.c,并生成可执行文件hello,
图2直接生成可执行文件hello
注意:上面的命令将.c文件生成了可执行文件,实际上是将预处理、编译、汇编、连接一步完成,下面我们将介绍四个流程分别做了什么工作。
ü使用–E选项,执行预处理工作。使用命令gcc–E hello.c–o hello.i对hello.c进行预处理,生成文件hello.i,如图所示:
图3使用-E选项
使用命令cat
hello.i查看hello.i文件的内容,如图5-4所示,可以看到头文件
stdio.h中包含的内容替换掉了原先代码中的#include。
图4查看文件hello.i内容
ü使用–S选项,执行编译处理工作。使用命令gcc–S hello.i–o hello.s对hello.i进行编译,生成汇编文件hello.s,如图所示:
图5使用-S选项
使用命令cat
hello.s查看hello.s文件的内容,如图5-6所示,可以看到原来的
c语言代码已被转化为汇编代码。
图6查看文件hello.s内容
ü使用–c选项,执行编译工作。使用命令gcc–chello.s–o
hello.o对hello.s进行汇编,生成目标文件hello.o,如图所示:
图7执行使用-c选项
ü使用命令gcc hello.o–o hello将hello.o链接库,生成可执行文件hello,如图
所示,以上四个步骤就对应了gcc执行过程的四个基本步骤,下面我们来看看gcc其他一些重要的选项。
图8连接生成可执行文件
ü使用–static选项,静态链接库。使用命令gcchello.c–ohello和gcchello.c–static–ohello1分别生成两个可执行文件hello和hello1。头一个文件hello是不加-static选项,默认是链接动态库生成的,如图所示,试比较链接动态库生成的文件hello和链接静态库生成的文件hello1的大小。
图9使用-static选项
可以看到静态链接库的可执行文件hello1要比动态链接库的文件hello大很多,他们的执行效果是一样的。
注意:要使动态链接库的可执行文件能够在机器上运行,必须保证系统中安装有相关的动态链接库,这些库一般在/lib目录下。
ü使用–g选项,在可执行程序中包含标准调试信息。使用命令gcc–ghello.c–o
hello2生成包含调试信息的文件hello2,如图所示,带有调试信息的可执行文件可以使用gdb调试器进行调试,gdb的具体用法将在下节讨论。
图10使用-g选项
ü使用–D选项,在编译时进行宏定义。使用命令gcc–DLINUXhello.c–o
hello3生成定义了宏LINUX的的可执行文件hello3,如图所示,将hello3和原可执行文件hello进行比较。
图11修改源码,注释第三行代码
图12使用-D选项
ü使用–O2选项,完成程序的优化工作。为了能够看出优化效果,首先在源代码中添加如图所示内容
图13优化测试代码
使用命令rm
hello? hello–f,删除之前生成的文件,使用命令gcc–O2 hello.c–o hello1生成优化后的可执行文件hello1,使用命令gcc hello.c–o
hello生成未经优化的可执行文件hello。如图5-13所示,将hello1和未优化过的可执行文件hello进行比较。
图14使用-O2选项
提示:事实上gcc有四个优化等级,分别对应选项-O0、-O1、-O2和-O3,其中-O0代表不优化,这个是缺省值,-O1到-O3优化等级逐步提高。另外还有个特殊的优化选项-Os,它通常被称为是优化等级为2.5的优化选项,是在-O2的基础上对代码尺寸进行了进一步优化。另外,为了更好的验证优化的效果,可以使用time命令,如time./hello,可以测试当前目录下可执行文件hello的执行时间。由于实验代码过于简单,所以用time测试基本看不出差别,大家可以自己编写复杂耗时的程序用于这个实验。注意:虽然优化选项可以加速代码的运行速度,但对于调试而言将是一个很大的挑战。
因为代码在经过优化之后,原先在源程序中声明和使用的变量很可能不再使用,控制流也可能会突然跳转到意外的地方,循环语句也有可能因为循环展开而变得到处都有,所有这些对调试来讲都将是一场噩梦。所以笔者建议在调试的时候最好不使用任何优化选项,只有当程序在最终发行的时候才考虑对其进行优化。
网友评论