gcc总结
gcc的编译流程
test.c
-
预处理
把宏定义展开、头文件包含、处理条件编译
gcc -E test.c -o test.i
(c语言 -- c语言) -
编译
生成汇编代码
gcc -S test.c -o test.S
(c语言 -- 汇编) -
汇编
生目标文件
gcc -c test.c -o test.o
(汇编 -- 二进制码) -
链接
将所有目标文件,链接在一起生成可执行文件。
gcc test.o -o test.out
动态库&&静态库制作
方法一:
将hello1.c和hello2.c编译成静态链接库.a
-
gcc -c hello1.c hello2.c
//将hello1.c和hello2.c分别编译为hello1.o和hello2.o,其中-c选项意为只编译不链接。 -
ar -r libhello.a hello1.o hello2.o
//将hello1.o和hello2.o组合为libhello.a这个静态链接库 -
cp libhello.a /usr/lib
//将libhello.a拷贝到/usr/lib目录下,作为一个系统共享的静态链接库 -
gcc -o hello hello.c -lhello
//将hello.c编译为可执行程序hello,这个过程用到了-lhello选项,这个选项告诉gcc编译器到/usr/lib目录下去找libhello.a的静态链接库
以上的过程类似于windows下的lib静态链接库的编译及调用过程。
方法二:将hello1.o和hello2.o组合成动态链接库.so
-
gcc -c -fpic hello1.c hello2.c
//将hello1.c和hello2.c编译成hello1.o和hello2.o,-c意为只编译不链接,-fpic意为位置独立代码,指示编译程序生成的代码要适合共享库的内容这样的代码能够根据载入内存的位置计算内部地址。 -
gcc -shared hello1.o hello2.o -o hello.so
//将hello1.o和hello2.o组合为shared object,即动态链接库 -
cp hello.so /usr/lib
//将hello.so拷贝到/usr/lib目录下 -
gcc -o hello hello.c hello.so
//将hello.c编译链接为hello的可执行程序,这个过程用到了动态链接库hello.so
GCC的选项
-E
进行预处理但不进行编译
-S
生成汇编代码
-c
生成二进制文件
-g
生成调试信息
例子
-o
生成文件名字
-O
生成目标文件
-I
-i
I./
-L
-l
gcc -L./ -llibname
-D
进行宏定义
【9】二进制工具
ar:建立、修改、提取归档文件。归档文件是包含多个文件内容的一个大文件,其结构保证了可以恢复原始文件内容。
as:主要用来编译GNU C编译器gcc输出的汇编文件,产生的目标文件由链接器ld连接。
ld:GNU链接器。它把一些目标和归档文件结合在一起,重定位数据,并链接符号引用。编译程序的最后一步就是调用ld。
ranlib:产生归档文件索引,并将其保存到这个归档文件中。在索引中列出了归档文件各成员所定义的可重分配目标文件。
readelf:显示elf格式可执行文件的信息。
size:列出目标文件每一段的大小以及总体的大小。默认情况下,对于每个目标文件或者一个归档文件中的每个模块只产生一行输出。
strings:打印某个文件的可打印字符串。默认情况下,只打印目标文件初始化和可加载段中的可打印字符;对于其它类型的文件它打印整个文件的可打印字符,这个程序对于了解非文本文件的内容很有帮助。
strip:丢弃目标文件中的全部或者特定符号,减小文件体积。
-
readelf
1-- elf :可执行、可重定位的二进制文件。(bin、exe、srec)
2-- readelf可以显示elf格式可执行文件的信息
3-- $ readelf –h hello
4-- readelf –S hello -
size
size列出目标文件每一段的大小以及总体的大小。 -
nm
nm可以列出目标文件中的符号。 -
strip
strip用来丢弃目标文件中的全部或者特定符号,减小文件体积。对于嵌入式系统,这个命令必不可少 -
objdump
objdump可以显示一个或者更多目标文件的信息,主要用来反汇编。
objdump –d nmdemo.o >nmdemo.dis -
objcopy
objcopy可以进行目标文件格式转换。
objcopy -O srec u-boot u-boot.srec
objcopy -O binary u-boot u-boot.bin -
addr2line
addr2line能够把程序地址转换为文件名和行号,前提是这个可执行文件包括调试符号。
调试前提: 编译时一定要加-g