编译工具gcc
gcc是在linux开发环境中使用最多的命令,下面是一些常用的选项:
选项说明
编译选项
-o
: 指定目标文件的名字;
-c
: 只编译成.o文件,不参与链接;
-D
: 可以动态定义宏,和#define xxx
效果是一样的;
-L
: 新增链接的依赖库路径,通常的形式是-Ldir -lxx
来链接dir目录下的libxx.so或libxx.a;
-I
: 新增头文件的搜索路径;
调试及优化选项
-v
: 编译的时候打印详细信息;
-g
: 增加gdb的调试信息;
-Wall
: 编译时打印出所有编译器的警告;
-O1
: 优化目标文件的大小;
-O2
: 在O1的基础上优化编译时间和执行效率;
依赖关系选项
-M
: 显示所有依赖的.o、.c和.h文件,这里的头文件包括系统头文件;
-MD
: 将-M的输出重定向到.d文件;
-MM
: 显示所有依赖的.o、.c和.h文件,这里的头文件不包括系统头文件;
-MMD
: 将-MM的输出重定向到.d文件;
库选项
-shared
: 用于编译生成库文件;
-static
: 在编译时将库链接到elf文件中,这样运行的时候就不需要依赖环境中是否有这个库;
实例一
arm-linux-gcc -DDO_DEPS_ONLY -g -Os -fno-common -ffixed-r8 \
-msoft-float -D__KERNEL__ -DCONFIG_SYS_TEXT_BASE=0x47f00000 -I/xxxx/boot/include -fno-builtin \
-ffreestanding -nostdinc -pipe -DCONFIG_ARM -D__ARM__ -marm -mno-thumb-interwork -mabi=aapcs-linux \
-march=armv5 -Wall -Wstrict-prototypes -fno-stack-protector \
-Wno-format-nonliteral -Wno-format-security -fstack-usage \
-o lib/asm-offsets.s lib/asm-offsets.c -c -S
选项解释
-DDO_DEPS_ONLY
: 等同于#define DO_DEPS_ONLY
;
-g
: 增加调试信息;
-Os
: 优化选项,相当于-O2.5
;
-fno-common
: 对未定义全局变量的位置优化;
-DCONFIG_SYS_TEXT_BASE=0x47f00000
: 等同于#define CONFIG_SYS_TEXT_BASE 0x47f00000
;
-I/xxxx/boot/include
: 增加头文件的搜索路径/xxxx/boot/include
;
链接工具ld
ld用于将多个目标和库文件链接成可执行文件,利用-Ttext 0x30000000
可以指定代码段的起始地址,所有的指令都基于这个偏移。当系统加载这个ELF文件时从0x30000000开始存放代码段,对于u-boot而言,将bootloader读取到内存的动作是由前4k的代码完成的。
-Ttext
: 正文段起始地址(存储运行指令)
-Tdata
: 数据段起始地址(存储以初始化的全局变量)
-Tbss
: bss段起始地址(存储未初始化的全局变量)
ELF文件的内部结构
程序本身内容包括
text
: 存储运行指令
data
: 存储以初始化的全局变量,记录变量标示和内容
bss
: 存储未初始化的全局变量,只记录变量标示
程序运行依赖
stack
: 系统分配,局部变量,用的不好会出现stack overflow
heap
: 堆,由程序员使用malloc和free进行操作
拷贝文件objcopy
裸板程序,包括bootloader都是需要手动将代码从flash上拷贝到SDRAM中,而最初使用gcc或ld得到的ELF文件确包含的这里不需要的ELF头以及相关的符号表信息,objcopy就时为了去除这些信息。
-O
: 指定目标文件的格式,二进制文件是binary
,s-record文件是srec
;
-S
: 不复制源文件的重定位信息和符号信息;
常用的形式是
objcopy -O binary -S elf_file bin_file
参考文献