一、gcc常用命令
例子代码:
test.c
#include<stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
-
简单编译
gcc test.c -o test
-
实际编译
①预编译
gcc -E test.c -o test.i
部分test.i的内容:
②编译为汇编代码
gcc -S test.i -o test.s
test.s的内容:
③汇编
gcc -c test.s -o test.o
④连接
gcc test.o -o test
-
多个程序文件的编译
①gcc 源文件1 源文件2 -o 生成的可执行文件
举例:
②gcc -c 源文件1 -o 生成.o文件1
gcc -c 源文件1 -o 生成.o文件2
gcc 生成.o文件1 生成.o文件2 -o 生成的可执行文件
举例:
-
检错
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会在所有产生警告的地方停止编译,迫使进行代码的修改
-
库文件连接
库文件:动态链接库(.so),静态链接库(.a)
函数库:头文件(.h),库文件(.so)注意:头文件一般放在/usr/include目录下,库文件一般放在/usr/lib目录下
①编译
gcc -c -I /usr/include 源文件 -o 生成.o文件
②链接
gcc -L /usr/lib 动态链接库文件名 生成.o文件 -o 生成可执行文件
③强制性使用静态链接库
gcc链接时会优先使用动态链接库,想强制使用静态链接库执行在命令中加-static
gcc -L /usr/lib -static 静态链接库文件名 生成.o文件 -o 生成可执行文件静态链接时搜索路径顺序:
a、ld会去找gcc命令中的参数-L
b、gcc的环境变量LBRARY_PATH(指定程序静态链接库文件的搜索路径)
c、内定目录/lib /usr/lib /usr/local/lib
动态链接时搜索路径顺序:
a、编译目标代码时指定的动态库搜索路径
b、环境变量LD_LIBRARY_PATH(指定程序动态链接库文件的搜索路径)
c、配置文件/etc/ld.so.conf中指定的动态库搜索路径
d、默认的动态库搜索路径/lib
e、默认的动态库搜索路径/usr/lib
二、gcc的合作伙伴
这里只介绍部分工具
- addr21line
帮助调试器在调试过程中定位对应的源代码。 - ar
用于创建静态链接库。 - ld
用于链接。 - as
用于汇编。 - ldd
查看执行文件所用到的链接库。 - size
查看执行文件中各部分的大小。 - readelf
查看ELF各个部分的内容。 - objdump
进行反汇编。
举例:
采用动态链接库
采用静态链接库
通过上面两种方式的比较,可以看到采用动态链接库会时执行文件小很多。
查看ELF
readerlf -S test
反汇编ELF
objdump -D test
三、nasm编译
- 准备工作
在Ubuntu中安装nasm
- 编译过程
使用nasm -f elf hello.asm,会生成一个hello.o文件;接下来使用ld -s -o hello hello.o,会产生一个一个错误。
解决方法:由于nasm -f elf hello.asm产生的是一个32位的.o文件,所以将nasm -f elf hello.asm修改为nasm -f elf64 hello.asm。
- 查看生成可执行文件的大小
四、总结
nasm方式编译得到的可执行文件要比用gcc编译得到的文件要小很多。通过对gcc的进一步练习,已经非常熟悉gcc编译过程和该如何使用gcc进行编译。本次又认识与gcc相互合作的一些工具,了解到这些工具的具体使用方式和它的具体作用。总的来说,本次收获还不错。希望,你也能够有所收获。