早期在裸机部分学习了有关Makefile的阅读和编写,算是刚刚入门对Makefile有一个基本的了解,在这里对Makefile的知识做一些补充
对Makefile的大概认识:
是用来管理大型文件的一个工具,特别是工程文件较多时使用Makefile能够快速的对文件进行编译、链接、删除等等操作
Makefile文件下三个重要的概念:目标、依赖、命令
(1)目标就是我们要去make xxx的那个xxx,就是我们最终要生成的东西。
(2)依赖是用来生成目录的原材料
(3)命令就是加工方法,所以make
通配符%和Makefile自动推导(规则)
(1)%是Makefile中的通配符,代表一个或几个字母。也就是说%.o就代表所有以.o为结尾的文件。类似于Linux命令下的参数*( rm -rf /* 呵呵,这里删除的是根目录下的所有文件,赶紧跑路!如果是执行 rm -rf /*.c 的话是表示删除根目录下所有的.c文件,应该就不用跑路了呵呵)
(2)所谓自动推导其实就是Makefile的规则。当Makefile需要某一个目标时,他会把这个目标去套规则说明,一旦套上了某个规则说明,则Makefile会试图寻找这个规则中的依赖,如果能找到则会执行这个规则用依赖生成目标。
led.bin: led.o
arm-linux-ld -Ttext 0x0 -o led.elf $^
arm-linux-objcopy -O binary led.elf led.bin
arm-linux-objdump -D led.elf > led_elf.dis
gcc mkv210_image.c -o mkx210
./mkx210 led.bin 210.bin
%.o : %.S
arm-linux-gcc -o $@ $< -c
%.o : %.c
arm-linux-gcc -o $@ $< -c
clean:
rm *.o *.elf *.bin *.dis mkx210 -f
Makefile中定义和使用变量
(1)Makefile中定义和使用变量,和shell脚本中非常相似。相似是说:都没有变量类型,直接定义使用,引用变量时用$var
伪目标(.PHONY)
(1)伪目标意思是这个目标本身不代表一个文件,执行这个目标不是为了得到某个文件或东西,而是单纯为了执行这个目标下面的命令。
(2)伪目标一般都没有依赖,因为执行伪目标就是为了执行目标下面的命令。既然一定要执行命令了那就不必加依赖。
(3)伪目标可以直接写,不影响使用;但是有时候为了明确声明这个目标是伪目标会在伪目标的前面用.PHONY来明确声明它是伪目标。
%.o : %.c
arm-linux-gcc -o $@ $< -c
.PHONY clean(这一句可加可不加)
clean:
rm *.o *.elf *.bin .dis mkx210 -f
Makefile的文件名
一般使用Makefile或者makefile或者是以.mk结尾的文件
Makfile中引用其他Makefile(include指令)
(1)有时候Makefile总体比较复杂,因此分成好几个Makefile来写。然后在主Makefile中引用其他的,用include指令来引用。引用的效果也是原地展开,和C语言中的头文件包含非常相似。
Makefile的几种变量赋值
(1)= 最简单的赋值;值取决于最后一次赋值时的值
(2):= 一般也是赋值;就地直接解析,只用往前看所赋的值即可
(3)?= 如果变量前面并没有赋值过则执行这条赋值,如果前面已经赋值过了则本行被忽略。(实验可以看出:所谓的没有赋值过其实就是这个变量没有被定义过)
(4)+= 用来给一个已经赋值的变量接续赋值,意思就是把这次的值加到原来的值的后面,有点类似于strcat。(在shell makefile等文件中,可以认为所有变量都是字符串,+=就相当于给字符串stcat接续内容)(注意一个细节,+=续接的内容和原来的内容之间会自动加一个空格隔开)
Makefile的环境变量
(1)makefile中用export导出的就是环境变量。一般情况下要求环境变量名用大写,普通变量名用小写。
(2)环境变量和普通变量不同,可以这样理解:环境变量类似于整个工程中所有Makefile之间可以共享的全局变量,而普通变量只是当前本Makefile中使用的局部变量。所以要注意:定义了一个环境变量会影响到工程中别的Makefile文件,因此要小心。
(3)Makefile中可能有一些环境变量可能是makefile本身自己定义的内部的环境变量或者是当前的执行环境提供的环境变量(譬如我们在make执行时给makefile传参。make CC=arm-linux-gcc,其实就是给当前Makefile传了一个环境变量CC,值是arm-linux-gcc。我们在make时给makefile传的环境变量值优先级最高的,可以覆盖makefile中的赋值)。这就好像C语言中编译器预定义的宏__LINE__ __FUNCTION__等一样。
Makefile中使用通配符
(1)* 若干个任意字符
(2)? 1个任意字符
(3)[ ] 将[ ]中的字符依次去和外面的结合匹配
还有个%,也是通配符,表示任意多个字符,和很相似,但是%一般只用于规则描述中,又叫做规则通配符。
Makefile的自动变量
(1)为什么使用自动变量。在有些情况下文件集合中文件非常多,描述的时候很麻烦,所以我们Makefile就用一些特殊的符号来替代符合某种条件的文件集,这就形成了自动变量。
(2)自动变量的含义:预定义的特殊意义的符号。就类似于C语言编译器中预制的那些宏__FILE__一样。
(3)常见自动变量:
小细节
注释符:和shell中的一样#