目录
一、准备工作
二.单一程序的编译
(1)预处理
)2)编译
(3)汇编
(4)链接
)5)开车
三.编译多个程序文件
四.检测错误
五.库文件链接
六. gcc编译工具集中的各软件
GCC
二进制
运行时库
七. ELF文件
反汇编ELF
八.总结
九、参考资料
另一方面,准备工作是首先生成test1文件,然后用文本编辑器生成用c语言写的简单的Hello.c程序的例子
#includestdio.hintmain(void ) ) printf ) Helloworld! n '; 返回0; (二、单程序编译)1)预处理终端中预处理命令的输入如下
gcc -E hello.c -o hello.i
)编译对预处理后的文档进行一系列词法分析、语法分析、语义分析以及
优化后,生成相应的汇编代码。
输入命令以编译文件并生成汇编代码
gcc -S hello.i -o hello.s
(3)汇编过程调用处理汇编代码,生成处理器可以识别的指令,保存在后缀. o中
请参阅。
在终端上输入以下命令
gcc -c hello.s -o hello.o
(4)链接输入终端
gcc hello.o -o hello
将以前的生成
的hello.与c标准库进行连接 (5)运行在终端中输入
./hello
运行程序
三、多个程序文件编译
当我们有多个文件需要进行编译的话,我们可以使用以下的命令
gcc test1.c test2.c -o test
然后程序同时进行预处理,编译,链接,最后生成可执行程序test,可以使用以下的命令
gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc test1.o test2.o -o test
四、检错-pedantic 编译选项并不能保证被编译程序与 ANSI/ISO C 标准的完全兼容,它仅仅只能用来帮助 Linux 程序员离这个目标越来越近。或者换句话说,-pedantic 选项能够帮助程序员发现一些不符合 ANSI/ISO C 标准的代码,但不是全部,事实上只有 ANSI/ISO C 语言标准中要求进行编译器诊断的 那些情况,才有可能被 GCC 发现并提出警告
gcc -pedantic illcode.c -o illcod
除了-pedantic 之外,GCC 还有一些其它编译选项也能够产生有用的警告信息。这些选项大多以-W 开头,其中最有价值的当数-Wall 了,使用它能够使 GCC 产生尽可能多的警告信息
gcc -Wall illcode.c -o illco
GCC 给出的警告信息虽然从严格意义上说不能算作错误,但却很可能成为错误的栖身之所。一个优 秀的 Linux 程序员应该尽量避免产生警告信息,使自己的代码始终保持标准、健壮的特性。所以将 警告信息当成编码错误来对待,是一种值得赞扬的行为!所以,在编译程序时带上-Werror 选项,那 么 GCC 会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改,如下:
gcc -Werror test.c -o test
Linux下的大多数函数都默认将头文件放到/usr/include/目录下,而库文件则放到/usr/lib/目录下,当我们使用自己的办法查找所需头文件和库文件时,例如我们的程序 test.c 是在 linux 上使用 c 连接 mysql,这个时候我们需要去mysql官网下载MySQL Connectors 的C库,下载下来解压之后,有一个include文件夹,里面包含mysql connectors的头 文件,还有一个lib文件夹,里面包含二进制 so 文件libmysqlclient.so其中inclulde文件夹的路径是/usr/dev/mysql/include,lib文件夹是/usr/dev/mysql/lib
首先将test.c编译为目标文件
gcc –c –I /usr/dev/mysql/include test.c –o test.o
然后将所有目标文件链接成可执行文件
gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test
linux环境下库文件分为静态库(.a)和动态库(.so),二者的区别仅在于程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。
GCC(GNU C Compiler)是编译工具。
Binutils一组二进制程序处理工具,包括:addr2line、ar、objcopy、objdump、as、ld、 ldd、readelf、 size 等。
(1) addr2line:用来将程序地址转换成其所对应的程序源文件及所对应的代码行,也可以得到所对应的函数。该工具将帮助调试器在调试的过程中定位对应的源代码位置。
(2) as:主要用于汇编。
(3) ld:主要用于链接。
(4) ar:主要用于创建静态库。
(5) ldd:可以用于查看一个可执行程序依赖的共享库。
(6) objcopy:将一种对象文件翻译成另一种格式,譬如将.bin 转换成.elf、或者将.elf 转换成.bin 等。
(7) objdump:主要的作用是反汇编。
(8) readelf:显示有关ELF文件的信息,请参见后文了解更多信息。
(9) size:列出可执行文件每个部分的尺寸和总尺寸,代码段、数据段、总大小等。
C 语言标准主要由两部分组成:一部分描述 C 的语法,另一部分描述 C 标准库。 C 标准库定义了一组标准头文件,每个头文件中包含一些相关的函数、变量、类 型声明和宏定义,譬如常见的 printf 函数便是一个 C 标准库函数,其原型定义 在 stdio 头文件中。 C 语言标准仅仅定义了 C 标准库函数原型,并没有提供实现。因此,C 语言编译 器通常需要一个 C 运行时库(C Run Time Libray,CRT)的支持。C 运行时库又 常简称为 C 运行库。
ELF代表Executable and Linkable Forma,是一种对可执行文件、目标文件和库使用的文件格式,跟Windows下的PE文件格式类似。ELF格式是是UNIX系统实验室作为ABI(Application Binary Interface)而开发和发布的,早已经是Linux下的标准格式了。
ELF 文件格式如下所示,位于ELF Header 和 Section Header Table之间的都是段(Section)。
一个典型的 ELF 文件包含下面几个段:
.text:已编译程序的指令代码段。
.rodata:ro 代表 read only,即只读数据(譬如常数 const)。
.data:已初始化的 C 程序全局变量和静态局部变量。
.bss:未初始化的 C 程序全局变量和静态局部变量。
.debug:调试符号表,调试器用此段的信息帮助调试
由于 ELF 文件无法被当做普通文本文件打开,如果希望直接查看一个 ELF 文件包 含的指令和数据,需要使用反汇编的方法。 使用 objdump -D 对其进行反汇编如下:
objdump -D hello
使用 objdump -S 将其反汇编并且将其 C 语言源代码混合显示出来:
gcc -o hello -g hello.c //要加上-g 选项
objdump -S hello
通过这次的实验对于gcc的了解有了更深的了解,学会了gcc的多个程序编译还有怎样的纠错,对于elf和反elf汇编有了一定的了解。
九、参考资料linux gcc常用命令_pink_lemon的博客-CSDN博客
g++/gcc编译选项_zhang2531的专栏-CSDN博客