一、gcc常用命令
1.简单编译
首先我们通过一个示例程序来进行编译,首先输入gedit test.c
创建一个test文件,然后输入以下代码
#include<stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
然后输入gcc test.c -o test
编译,编译后输入./test运行
2.实际编译
但是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
3.多个程序文件的编译
输入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.o
4.检错
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 | 进行反汇编 |
采用动态库连接时:
采用静态库连接时:
可以看到采用动态链接库时文件大小会小很多
三、分析ELF文件
1.ELF文件的段
段 | 含义 |
---|---|
.text | 已编译程序的指令代码段 |
rodata | ro 代表 read only,即只读数据(譬如常数 const) |
.data | 已初始化的 C 程序全局变量和静态局部变量 |
.bss | 未初始化的 C 程序全局变量和静态局部变量 |
.debug | 调试符号表,调试器用此段的信息帮助调试 |
输入readelf -S test
可以查看ELF(test为文件名,根据实际情况进行更改)
2.反汇编ELF
输入objdump -D
进行反汇编
四、总结
通过对gcc的进一步使用,了解到了gcc进行编译的整个过程,也有许多和gcc进行协同的工具,明白了gcc功能的强大。
五、参考资料
链接: 使用gcc和gcc的伙伴.