编译过程:
- 每个xx.c分别编译为xx.o文件(这个可以利用CPU多核进行并行编译),gcc命令,
xx.o中包含有地址,调试,符号等信息。常用编译选项:
-c:只编译不链接为可执行文件,编译器将输入的.c 文件编译为.o 的目标文件。
-o:<输出文件名>用来指定编译结束以后的输出文件名,如果不使用这个选项的话 GCC 默
认编译出来的可执行文件名字为 a.out。
-g:添加调试信息,如果要使用调试工具(如 GDB)的话就必须加入此选项,此选项指示编
译的时候生成调试所需的符号信息。
-O:对程序进行优化编译,如果使用此选项的话整个源代码在编译、链接的的时候都会进
行优化,这样产生的可执行文件执行效率就高。
-O2:比-O 更幅度更大的优化,生成的可执行效率更高,但是整个编译过程会很慢。
-Wall: 打开所有需要注意的警告信息
-nostdlib: 不连接系统标准启动文件和标准库文件,只把指定的文件传递给连接器 - 对所有xx.o进行运行地址确定(链接),ld命令,得到xx.elf,运行阶段就是把这些程序在这些指定的地址上运行和跳转的。常用编译选项:
“-o”选项是指定编译产生的文件名字 - 将 xx.elf 文件转换为.bin 文件,objcopy 更像一个格式转换工具,去掉xx.elf中的符号信息什么的。常用编译选项:
“-O”选项指定以什么格式输出
“binary”表示以二进制格式输出
选项“-S”表示不要复制源文件中的重定位信息和符号信息
“-g”表示不复制源文件中的调试信息 - objdump 反汇编,大多数情况下我们都是用 C 语言写试验例程的,有时候需要查看其汇编代码来调试代码,因此就需要进行反汇编,一般可以将 elf 文件反汇编。常用编译选项:
“-D”选项表示反汇编所有的段。
"-m" machine,即对于什么架构处理器,可以填arm
反汇编完成以后就会在当前目录下出现一
个名为 xx.dis 文件
可以看到内存分配情况。在
0X87800000 处就是全局标号_start,也就是程序开始的地方。通过 led.dis 这个反汇编文件可以
明显的看出我们的代码已经链接到了以 0X87800000 为起始地址的区域。
总结一下我们为了编译 ARM 开发板上运行的 led.o 这个文件使用了如下命令:
arm-linux-gnueabihf-gcc -g -c led.s -o led.o
arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
arm-linux-gnueabihf-objdump -D led.elf > led.dis
如果我们修改了 led.s 文件,那么就需要在重复一次上面的这些命令,太麻烦了,这个时候
我们就可以使用Makefile 文件了。看我这篇文章gcc编译器使用总结和makefile基本知识