目录
一、Gcc编译器(一)、Gcc简介
GCC(GNUCCompiler)是编译工具。将C/C++语言编撰的程序转换成为处理器才能执行的二补码代码的过程即由编译器完成。
GCC的意思也只是GNUCCompiler而已。经过了那么多年的发展,GCC早已不仅仅能支持C语言;它如今还支持Ada语言、C++语言、Java语言、ObjectiveC语言、Pascal语言、COBOL语言,以及支持函数式编程和逻辑编程的Mercury语言,等等。而GCC也不再单只是GNUC语言编译器的意思了,而是弄成了GNUCompilerCollection也即是GNU编译器家族的意思了。另一方面,说到GCC对于操作系统平台及硬件平台支持,概括上去就是一句话:无所不在。
(二)、Gcc编译语言:C运行库
C语言标准主要由两部份组成:一部份描述C的句型,另一部份描述C标准库。C标准库定义了一组标准头文件,每位头文件中包含一些相关的函数、变量、类型申明和宏定义,例如常见的printf函数便是一个C标准库函数,其原型定义在stdio头文件中。
C语言标准仅仅定义了C标准库函数原型,并没有提供实现。为此,C语言编译器一般须要一个C运行时库(CRunTimeLibray,CRT)的支持。C运行时库又常简称为C运行库。与C语言类似,C++也定义了自己的标准,同时提供相关支持库,称为C++运行时库。
(三)、Gcc相关命令说明:Binutils
1.addr2line:用来将程序地址转换成其所对应的程序源文件及所对应的代码行,也可以得到所对应的函数。该工具将帮助调试器在调试的过程中定位对应的源代码位置。
2.as:主要用于汇编。
3.ld:主要用于链接。
4.ar:主要用于创建静态库。
5.ldd:可以用于查看一个可执行程序依赖的共享库。
6.objcopy:将一种对象文件翻译成另一种格式,例如将.bin转换成.elf、或者将.elf转换成.bin等。
7.objdump:主要的作用是反汇编。
8.readelf:显示有关ELF文件的信息。
9.size:列举可执行文件每位部份的规格和总规格,代码段、数据段、总大小等。
关于ar创建静态库的说明:
1.倘若要将多个.o目标文件生成一个库文件,则存在两种类型的库,一种是静态库,另一种动态库。
2.在windows中静态库是以.lib为后缀的文件,共享库是以.dll为后缀的文件。在linu中静态库是以.a为后缀的文,共享库是以.so为后缀的文件。
3.静态库和动态库的不同点在于代码载入的时刻不同。静态库的代码在编译过程中早已被载入可执行程序,因而容积较大。共享库的代码在可执行程序运行时才载入显存的,在编译过程中仅简单的引用,因而代码容积较小。在Linux系统中,可以用ldd命令查看一个可执行程序依赖的共享库。
4.假如一个系统中存在多个须要同时运行的程序且这种程序之间存在共享库,这么采用动态库的方式将更节约显存。
二、使用Gcc编译实例1(一)、程序编撰
代码如下:
#include
int main(void)
{
printf("Hello World! n");
return 0;
}
(二)、使用Gcc编译
1.编译预处理
(1)将所有的#define删掉,但是展开所有的宏定义,但是处理所有的条件预编译指令,例如#if#ifdef#elif#else#endif等。
(2)处理#include预编译指令,将被包含的文件插入到该预编译指令的位置。
(3)删掉所有注释“//”和“/**/”。
(4)添加行号和文件标示,便于编译时形成调试用的行号及编译错误警告行号。
将源文件hello.c文件预处理生成hello.i;GCC的选项-E使GCC在进行完预处理后即停止。
gcc -E hello.c -o hello.i
注:hello.i是一个可打开文件。可以打开剖析其包含的具体内容
2.编译处理
编译过程就是对预处理完的文件进行一系列的词法剖析,句型剖析,语义剖析及优化后生成相应的汇编代码。
将预处理生成的hello.i文件编译生成汇编程序hello.s;GCC的选项-S使GCC在执行完编译后停止,生成汇编程序。
gcc -S hello.i -o hello.s
注:hello.s文件可打开,其中为hello.c对应的汇编语言。
3.汇编处理
汇编过程调用对汇编代码进行处理,生成处理器能辨识的指令,保存在后缀为.o的目标文件中。因为每一个汇编句子几乎都对应一条处理器指令,因而,汇编相对于编译过程比较简单,通过调用Binutils中的汇编器as按照汇编指令和处理器指令的对照表一一翻译即可。
当程序由多个源代码文件构成时,每位文件都要先完成汇编工作linux关机命令,生成.o目标文件后,才会步入下一步的链接工作。注意:目标文件早已是最终程序的某一部分了,并且在链接之前还不能执行。
将编译生成的hello.s文件汇编生成目标文件hello.o;GCC的选项-c使GCC在执行完汇编后停止,生成目标文件
gcc -c hello.s -o hello.o
或则使用Binutils中的as将hello.s文件汇编生成目标文件
as -c hello.s -o hello.o
注意:hello.o目标文件为ELF(ExecutableandLinkableFormat)格式的可重定向文件。
4.链接
链接的具体说明请参考资料“LinuxGCC常用命令.pdf”和“GCC编译器背后的故事.pdf”
gcc hello.c -o hello
size hello
ldd hello
(三)、对ELF文件进行剖析
1.认识并理解ELF文件的段
一个典型的ELF文件包含下边几个段:
.text:已编译程序的指令代码段。
.rodata:ro代表readonlyubuntu gcc 编译器,即只读数据(例如常数const)。
.data:已初始化的C程序全局变量和静态局部变量。
.bss:未初始化的C程序全局变量和静态局部变量。
.debug:调试符号表,调试器用此段的信息帮助调试。
可以采用下列代码具体查看段的信息
readelf -S hello
2.反汇编ELF
因为ELF文件难以被当作普通文本文件打开,假如希望直接查看一个ELF文件包含的指令和数据,须要使用反汇编的方式。
使用下列代码进行反汇编
objdump -D hello
使用objdump-S将其反汇编而且将其C语言源代码混和显示下来:
gcc -o hello -g hello.c
objdump -S hello
三、使用Gcc编译实例2(一)、程序编撰
HL.c
#include
int main(void)
{
printf("Hello World!n");
return 0;
}
(二)、程序编译
与实例1的操作方式相同,分别为预处理、编译、汇编、链接四个步骤。相关代码如下
gcc -E HL.c -o HL.i 或 gcc -E HL.c
gcc -S HL.i -o HL.s
gcc -c HL.s -o HL.o
gcc HL.o -o HL
执行./HL结果为:
(三)、多个程序文件的编译
将HL.c和hello.c同时编译linux空间,并生成test可执行文件:
gcc HL.c hello.c -o test
(四)、纠错
gcc -pedantic illcode.c -o illcode
-pedantic编译选项并不能保证被编译程序与ANSI/ISOC标准的完全兼容,它仅仅只能拿来帮助Linux程序员离这个目标越来越近。或则换句话说,-pedantic选项才能帮助程序员发觉一些不符合ANSI/ISOC标准的代码,但不是全部,事实上只有ANSI/ISOC语言标准中要求进行编译器确诊的这些情况,才有可能被GCC发觉并提出警告。
gcc -Wall illcode.c -o illc
不仅-pedantic之外,GCC还有一些其它编译选项也就能形成有用的警告信息。这种选项大多以-W开头,其中最有价值的当数-Wall了ubuntu gcc 编译器,使用它还能使GCC形成尽可能多的警告信息。
gcc -Werror test.c -o test
在编译程序时带上-Werror选项,那么GCC会在所有形成警告的地方停止编译,促使程序员对自己的代码进行更改。
(五)、库文件链接
1.编译成可执行文件
gcc –c –I /usr/dev/mysql/include HL.c –o HL
2.把所有目标文件链接成可执行文件
gcc –L /usr/dev/mysql/lib –lmysqlclient HL.o –o HL
3.制链接时使用静态链接库
gcc –L /usr/dev/mysql/lib –static –lmysqlclient HL.o –o HL
四、实验总结
通过本次实验,强化了我在Linux系统上进行编程的能力,使我回顾并深入了Linux系统上gcc的编译命令及操作流程,同时使我了解并熟悉了对库的链接的使用,深层次的理解了程序编撰到编译及最后执行的过程。
五、参考文献
浏览
%E7%BC%96%E8%AF%91%E5%99%A8%E8%83%8C%E5%90%8E%E7%9A%84%E6%95%85%E4%BA%8B.pdf浏览
%20GCC%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4.pdf基于Ubuntu实操三:认识Gcc编译器的使用_Lc-Yusheng的博客-CSDN博客一、认识Gcc编译器1.GCC的定义及发展GCC(GNUCCompiler)是编译工具。本文所要介绍的将C/C++语言编撰的程序转换成为处理器才能执行的二补码代码的过程即由编译器完成。GCC的意思也只是GNUCCompiler而已。经过了那么多年的发展,GCC早已不仅仅能支持C语言;它如今还支持Ada语言、C++语言、Java语言、ObjectiveC语言、Pascal语言、COBOL语言,以及支持函数式编程和逻辑编程的Mercury语言,等等。而
gcc生成静态库.a和动态库.so_Harriet的博客-CSDN博客请说明可执行程序是怎样被组装的?1)阅读、理解和学习材料“用gcc生成静态库和动态库.pdf”和“静态库.a与.so库文件的生成与使用.pdf”,请在Linux系统(Ubuntu)下如实仿做一遍。2)在第一次作业的程序代码基础进行改编,不仅x2x函数之外,再扩充写一个x2y函数(功能自定),main函数代码将调用x2x和x2y;将这3个函数分别写成单独的3个.c文件,并用gcc分别编译为3个.o目标文件;将x2x、x2y目标文件用ar工具生成1个.a静态库文件,之后用gcc将mai.