文章目录
一、Linux Gcc常用命令
示例程序:
#include<stdio>
int main(void)
{
printf("hello word\n");
return 0;
}
1、简单编译
(1)、预处理
gcc -E test.c -o test.i或gcc -E test.c
(2)、编译为汇编代码
gcc -S test.i -o test.s
gcc的-S选项,表示在程序编译期间,在生成汇编代码后,停止,-o输出汇编代码文件。
(3)、汇编
gcc -c test.s -o test.o
(4)、链接
gcc test.o -o test
实际上上述四个编译阶段可以一步到位:
gcc test.c -o test
最后生成可执行文件test,输入./test
执行:
2、检错
(1)、-pedantic
gcc -pedantic illcode.c -o illcode
-pedantic 选项能够帮助程序员发现一些不符合ANSI/ISO C 标准的代码,但不是全部。
(2)、-Wall
gcc -Wall illcode.c -o illcode
除了-pedantic 之外,GCC 还有一些其它编译选项也能够产生有用的警告信息。这些选项大多以-W开头,其中最有价值的当数-Wall 了,使用它能够使 GCC 产生尽可能多的警告信息。
(3)、-Werror
gcc -Werror test.c -o test
在编译程序时带上-Werror 选项,那么 GCC 会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改。
3、库文件连接
例如我们的程序 test.c 是在 linux 上使用 c 连接 mysql,这个时候我们需要去 mysql 官网下载MySQLConnectors 的 C 库,下载下来解压之后,有一个 include 文件夹,里面包含 mysql connectors 的头文件,还有一个 lib 文件夹,里面包含二进制 so 文件 libmysqlclient.so。其中 inclulde 文件夹的路径是/usr/dev/mysql/include,lib 文件夹是/usr/dev/mysql/lib
(1)编译成可执行文件
首先我们要进行编译 test.c 为目标文件,这个时候需要执行
gcc –c –I /usr/dev/mysql/include test.c –o test.o
(2)、链接
最后我们把所有目标文件链接成可执行文件:
gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test
Linux 下的库文件分为两大类分别是动态链接库(通常以.so 结尾)和静态链接库(通常以.a 结尾),二者的区别仅在于程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。
二、关于gcc
1、GCC:
GCC(GNU C Compiler)是编译工具。本文所要介绍的将 C/C++语言编写的程序转换成为处理器能够执行的二进制代码的过程即由编译器完成。
2、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:列出可执行文件每个部分的尺寸和总尺寸,代码段、数据段、总大小等。
3、ELF 文件的段
ELF 文件格式如下图所示,位于 ELF Header 和 Section Header Table 之间的都是段(Section)。一个典型的 ELF 文件包含下面几个段:
.text:已编译程序的指令代码段。
.rodata:ro 代表 read only,即只读数据(譬如常数 const)。
.data:已初始化的 C 程序全局变量和静态局部变量。
.bss:未初始化的 C 程序全局变量和静态局部变量。
.debug:调试符号表,调试器用此段的信息帮助调试。
三、总结
通过学习材料学习材料“Linux GCC常用命令”和“GCC编译器背后的故事”,让我了解到了许多关于gcc的基础知识,并让我知道了gcc的强大功能,并熟练使用gcc的一些基本指令。