首先我们通过一个示例程序来进行编译,首先输入gedit test.c创建一个test文件,然后输入以下代码
#includeint main(void) { printf("Hello World!n"); return 0; }
然后输入gcc test.c -o test编译,编译后输入./test运行
但是gcc实际的编译过程是通过4个步骤进行的,预处理,编译,汇编,连接
①预处理通过输入命令:gcc -E test.c -o test.i
输入命令:gcc -S test.i -o test.s
通过输入命令:gcc -c test.s -o test.o
④连接通过输入命令:gcc test.o -o test
连接完成后就生成程序test
输入gcc test1.c test2.c -o test进行执行文件的生成,如果是多个的文件,就需要执行更多命令。
gcc -c test1.c -o test1.o
gcc -c test2.c -o test1.o
gcc test1.o test2.o4.检错
gcc -pedantic test.c -o test1
-pedantic:帮助发现一些不符合ANSI/ISO C标准的代码,当出现不符合的代码,会发出警告信息
gcc -Wall test.c -o test2
-Wall:帮助发现一些不符合ANSI/ISO C标准的代码,当出现不符合的代码,gcc会发出尽可能多的警告信息
gcc -Werror test.c -o test3
-Werror:gcc会在所有产生警告的地方停止编译,迫使进行代码的修改
5.库文件连接库文件:动态链接库(.so),静态链接库(.a)
函数库:头文件(.h),库文件(.so)
编译:gcc -c -I /usr/include 源文件 -o 生成.o文件
链接:gcc -L /usr/lib 动态链接库文件名 生成.o文件 -o 生成可执行文件
强制性使用静态链接库:gcc -L /usr/lib -static 静态链接库文件名 生成.o文件 -o 生成可执行文件,如果动态库和静态库同时存在会优先使用动态库,这时就可以强制性使用静态库链接
| 工具 | 作用 |
|---|---|
| addr21line | 帮助调试器在调试过程中定位对应的源代码 |
| ar | 用于创建静态链接库 |
| ld | 用于链接 |
| as | 用于汇编 |
| ldd | 查看执行文件所用到的链接库 |
| size | 查看执行文件中各部分的大小 |
| readelf | 查看ELF各个部分的内容 |
| objdump | 进行反汇编 |
采用动态库连接时:
采用静态库连接时:
可以看到采用动态链接库时文件大小会小很多
| 段 | 含义 |
|---|---|
| .text | 已编译程序的指令代码段 |
| rodata | ro 代表 read only,即只读数据(譬如常数 const) |
| .data | 已初始化的 C 程序全局变量和静态局部变量 |
| .bss | 未初始化的 C 程序全局变量和静态局部变量 |
| .debug | 调试符号表,调试器用此段的信息帮助调试 |
输入readelf -S test可以查看ELF(test为文件名,根据实际情况进行更改)
输入objdump -D进行反汇编
通过对gcc的进一步使用,了解到了gcc进行编译的整个过程,也有许多和gcc进行协同的工具,明白了gcc功能的强大。
五、参考资料链接: 使用gcc和gcc的伙伴.



