购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.3 嵌入式编译器gcc

在开始学习阶段,我们接触最多的工具是编译工具,其中gcc(GNU Compiler Collection,GNU编译器套件)是一个功能强大、结构灵活的编译工具。最值得称道的一点就是,gcc编译器可以通过不同的前端模块来支持各种语言,如Java、Fortran、Pascal和Ada等。开放、自由和灵活是Linux系统的魅力所在,这一点在gcc编译器上得到了完美的展现。

2.3.1 初识gcc编译器

gcc编译器是GNU发布的最著名的软件之一,其强大的功能体现在以下两个方面:

(1)gcc编译器可以支持x86、ARM、MIPS等不同体系结构的硬件平台。

(2)gcc编译器可以支持C、C++、Pascal、Java等高级语言。

gcc编译器对嵌入式应用的开发极其重要,其编译效率也非常高(比其他编译工具高20%~30%),在嵌入式Linux C开发中,基本上都使用gcc编译器。

2.3.2 gcc命令的常用选项及编译过程

1.gcc命令的常用选项

gcc命令的格式为:

gcc命令拥有数量庞大的选项,按类型可以把这些选项分为以下几类。

1)总体选项

总体选项用于控制编译的整个过程,常用的总体选项如表2.1所示。

表2.1 gcc命令中常用的总体选项

2)语言选项

语言选项用于支持各种版本的C语言程序,常用的语言选项如表2.2所示。

表2.2 gcc命令中常用的语言选项

3)警告选项

警告选项用于控制编译过程中产生的各种警告信息,常用的警告选项如表2.3所示。

表2.3 gcc命令中常用的警告选项

4)调试选项

调试选项用于控制调试信息,常用的调试选项如表2.4所示。

表2.4 gcc命令中常用的调试选项

5)优化选项

优化选项用于对目标文件进行优化,常用的优化选项如表2.5所示。

表2.5 gcc命令中常用的优化选项

6)链接器选项

链接器选项用于控制链接过程,常用的链接器选项如表2.6所示。

表2.6 gcc命令中常用的链接器选项

7)目录选项

目录选项用于指定编译器的文件搜索目录,常用的目录选项如表2.7所示。

表2.7 gcc命令中常用的目录选项

此外,还有配置选项等其他选项,读者可以在gcc的官方网站中查找全部配置选项,网址为https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc/Option-Index.html。

2.gcc命令的编译流程

在使用gcc编译器时,编译过程可以分为4个阶段:

(1)预处理(Pre-Processing):生成后缀名为.i的文件。

(2)编译(Compiling):生成后缀名为.s的汇编文件。

(3)汇编(Assembling):把汇编文件翻译成计算机可以识别的二进制文件,生成后缀名为.o的目标文件。

(4)链接(Linking):把程序中所有的目标文件和所需的库文件链接在一起,最终生成一个可以直接运行的文件。

gcc编译器生成的可执行文件有三种格式:a.out(Assembler and Link editor output)、COFF(Common object file format)、ELF(Executable and linkable format),其中,a.out和COFF格式都是比较旧的格式,现阶段的主流格式是ELF。

下面通过一个例子来说明编译过程,代码如下:

使用gcc编译器进行编译时,输入命令:

编译后生成名为test2.1的可执行程序。如果不使用选项-o,那么默认生成的可执行程序是a.out文件。

需要注意的是,编程的文件名不要用test,因为test命令是Linux系统的内置命令。为了验证这一点,可以通过which命令找到test命令的文件位置,命令如下:

2.3.3 库的使用

为了增加编程的效率,常见的一些函数会以工具包的形式提供给开发者,开发者直接调用这些函数即可。常见的函数有信息打印函数、文件打开或关闭函数、内存空间申请与释放函数,以及数学计算函数等。通常将这些函数的集合称为函数库,其中的函数往往都是由经验丰富的资深程序员编写的,具有出色的运行性能和工作效率。

函数库的使用方式分为静态链接和动态链接两种。静态链接是指系统在链接阶段把程序的目标文件和所需的函数库文件链接在一起,由此生成的可执行文件可以在没有函数库的情况下运行。动态链接是指系统在链接阶段并没有把目标文件和函数库文件链接在一起,程序在运行过程中需要使用函数库中的函数时才链接函数库。

相比较而言,使用静态链接方式产生的可执行文件比较大,但运行效率较高;使用动态链接方式产生的可执行文件比较小,但由于需要动态加载函数库,所以运行效率会低一点。特别要注意一点,在使用动态链接时,需要同时将函数库复制到将要运行程序(使用动态链接生成的可执行文件)的计算机中。如果将要运行程序的计算机中没有对应的函数库,那么程序是无法运行的。

在具体应用中,如果多个源文件都需要调用函数库,则应该选择动态链接的方式;如果只有少数源文件需要调用函数库,则应该选择静态链接的方式。通常可以被静态链接的函数库称为静态库,可以被动态链接的函数库称为动态库或共享库。

Glibc(GNU Library C)是GNU推出的C语言函数库,包含了大量的函数库,其中的libc是最基本的函数库,每个C语言程序都需要使用libc。此外,常用的函数库还有数学库libm、加密库libcrypt、POSIX线程库libpthread、网络服务库libnsl、IEEE浮点运算库libieee等。Glibc为C语言程序提供了大量的功能强大的函数,包括输入/输出函数、字符串处理函数、数学函数、中断处理函数、错误处理函数、日期时间函数等。

当C语言程序调用Glibc中的函数库时,需要引用与函数库对应的头文件,如stdio.h、string.h、time.h等。这些头文件都存放在目录“/usr/include”下。同时,在编译命令中需要加入某些函数库的链接参数(在函数库的使用文档中会列出具体的链接库名称参数),并使用符号“-l”进行链接。下面的例子使用到了数学函数库,读者可以和2.3.2节中的例子进行比较。

由于使用了正弦函数,需要引用math.h头文件,因此需要在编译命令中加入“-lm”。通过下面的命令:

可得到可执行文件test2.2。在使用动态链接方式链接程序时,动态库的符号链接文件会写入二进制文件中,程序在运行时可以通过符号链接文件找到指定的动态库文件。

通过file命令可以查看文件test2.2的相关信息,如下所示:

其中,“dynamically linked”表明文件test2.2使用了动态库。通过选项static可以使用静态链接方式对程序进行链接。通过下面的命令:

可生成可执行文件test2.2s,该文件的相关信息如下所示:

其中,“statically linked”表明test2.2s文件使用了静态库。

为了比较动态链接方式和静态链接方式生成的可执行文件大小,可使用命令“ls -al”来查看不同链接方式生成的可执行文件大小。

结果显示,test2.2文件的大小是8 KB左右,而test2.2s文件的大小是900 KB左右。可见,采用动态链接方式生成的可执行文件要小于静态链接方式生成的可执行文件。 ckg27MWs//VpvQxmhZRX6IRC3kR7TvCucQ7gnGwJDi6ALB2zNrAUcDYTWESQAg7s

点击中间区域
呼出菜单
上一章
目录
下一章
×