Makefile入门
相信大家对makefile都不陌生,在Linux下编写程序基本都离不开makefile的编写,我们都知道多个.c文件经过编译器编译后得到多个.o文件,这些文件是互相独立的,但最终我们要得到一个可正常运行的文件,很显然这个过程就是连接,将多个.o文件连接为一个文件,这个文件是.elf文件。下面来举个例子说明以下。
test.elf : part1.o part2.o gcc -o test.elf part1.o part2.o //这种写法虽然太过原始,但能说明问题即可 %.o : %.c gcc -o part1.o part2.o -c part1.c part2.c
上面gcc -o part1.o part2.o -c part1.c part2.c 这步将.c文件编译成对应的多个文件,注意-c表示只编译不连接,然后通过gcc -o test.elf part1.o part2.o连接为一个.elf文件,对于gcc而言,没有-c就意味着默认编译链接,这样就得到了一个文件,这是在PC机上运行的程序,但如果在ARM裸机上编写,那应该怎么实现了。
在ARM上裸机开发过程就变得复杂了,因为编译连接过程gcc已经帮你完成了,所以就不需要去管了,但是裸机就不一样了,这个连接过程我们还的去告诉编译器去做什么,幸运的是ARM开发下有一套完整的工具链,这个就是arm-linux-,这个工具链有三个最常用的工具,arm-linux-gcc arm-linux-linker arm-linux-objcopy
第一个工具是编译.c文件或者.s文件的,其输出文件为.o文件,第二个是连接器,是将多个.o文件连接为一个.elf文件的,最后一个工具是j将.elf文件转换为.bin文件以便烧录到Flash去的,下面用一个具体的例子说明三个工具的用法:
整个工程有.main.c hello.c hello.h main.lds文件:
#Makefile file src=main.o hello.o targ=main.bin #生成需要的二进制文件 armcc=arm-linux-gcc armlin=arm-linux-ld armobj=arm-linux-objcopy $(targ) : $(src) armlin -Tmain.lds -o main.elf $^ armobj -O binary -S main.elf $@ %o : %c armcc -o $@ -c $< .PHONY:clean clean: rm -f *.o *.elf
前面定义的变量就只替换的作用,其中
armlin -Tmain.lds -o main.elf $^
意思是将.main.o hello.o文件连接为一个main.elf文件,那按什么方式连接呢,这里用了-T就是说自定义连接过程,这个main.lds就是我们自己定义的连接方式,-o就是输出文件,这里需要注意的是-T后直接接着main.lds文件,中间没有空格,
armobj -O binary -S main.elf $@
意思是将main.elf文件转换为main,bin文件,-O表示输出文件格式,后面接的是binary表示二进制文件,-S是源文件,注意-O和-S都有大写,
armcc -o $@ -c $<
意思是将依赖文件的第一个文件编译为目标文件,其-c表示只编译不连接,因为连接过程在第一个。
下面来说main.elf文件:
SECTIONS{ . = 0X000; #表示起始地址,即连接时将该文件的首地址放在哪 . = ALIGN(4);#表示四个字节对齐,比如如果地址在0x3,则会自动移到0x4 .text : { *(.text) } . = 0x100; #注意.后面有空格 . = ALIGN(4); #注意.后面有空格 .data : #注意.后面没有空格 { *(.data) } .bss : { *(.bss) } } #特别注意 .text : 中text与:之间有空格,这个必须有空格,否则编译出错 #同样.data和.bss也是一样