Makefile学习
Makefile
1. 目标
目标就是我们要去make xxx的那个xxx,就是我们要生成的东西。
2 依赖
依赖就是生成目标的原材料
3. 命令
命令就是加工方法,所以make xxx的过程其实就是使用命令将依赖加工成目标的过程
通配符 %和makefile自动推导(规则)
(1) %号是我们makefile的通配符,代表一个或者几个字母
%.o就代表所有以.o为结尾的文件
(2) 所谓自动推导就是规则。当makefilr需要某一个目标时,它会把这个目标去套规则说明,一旦套上了则makefile会试图寻找这个规则中的依赖,如果能找到,则会执行这个规则,用依赖生成目标,如果找不到,它会去找别的规则。
(3) makefile中定义和使用变量
Makefile中定义和使用变量和shell脚本中非常相似,相似是说都没有变量类型,直接定义就使用,引用变量的时候用$加变量名
4. 伪目标(.PHONY)
伪目标的意思是这个目标本身不代表一个文件,执行这个目标不是为了得到某个文件或东西,而是单纯为了执行这个目标下面的动作,典型的伪目标就是clean,makefile的命令要跟我们目标相对应,不然他不知道什么时候执行这个命令,伪目标一般都没有依赖,执行我们的伪目标就是就是执行下面的命令,既然一定要执行命令那就不必加依赖,因为不加依赖意思就是无条件执行。伪目标可以直接写,不影响使用,但是有时候为了明确声明这个目标是伪目标会在伪目标前面用.PHONY来明确声明他是个伪目标 例子如下
.PHONY clean
clean :
rm *.o *.elf *.bin *.dis -f
Makefile的文件名
Makefile的文件名合法的一般有两个:Makefile或者makefile
Makefile引用其他的Makefile(include指令)
(1) Makefile有时候比较负责,有时候也分成好几个Makefile来写,然后在主Makefile中引用其他的,用include来引用。引用的效果也是原地展开,和C语言的头文件非常相识
例子
include $(obj)include/config.mk 这就是一个引用
Makefile中的注释是用#号完成的 跟shell是一样的
Makefile中 命令前面用@来表示静默执行
(1) 在Makefile的命令行中 前面的@表示静默执行
(2) Makefile 在默认情况下执行一行命令前,会先把这行命令打印出来,然后再执行这行命令,如果说你不想看到命令本身,只想看到命令执行就静默执行即可
Makefile中并不要求赋值运算符两边一定要有空格或者无空格,这一点比shell的格式要求要松一些
Makefile中几种变量赋值运算符
1. = 最简单的赋值
2. := 一般也是赋值
以上这两个大部分情况下效果是一样的,但是有时候不一样
3. ?= 如果我们变量在前面并没有赋值过则执行这条赋值,如果前面已经赋过值了,则本行被忽略
4. += 这个是给一个已经赋值的变量接续赋值,意思是把这次的值加到原来的值的后面,有点类似于strcat。在makefile和shell的文件中,可以认为所有的变量都是字符串,+=就相当于给字符串strcat接续内容。注意+=续接的内容和原来的内容直接会自动加一个空格隔开
Makefile的环境变量
(1)在Makefile 中用export导出的就是环境变量,一般情况下要求环境变量名用大写,普通变量用小写
(2)环境变量和普通变量不同,可以这样理解,环境变量类似于整个工程中所有makefile直接可以共享的全局变量,而普通变量只是当前makefile中使用的局部变量
。所以要注意,定义一个环境变量会影响到工程中别的Makefile文件,因此要小心
(3)Makefile中有一些环境变量可能是Makefile中自己定义的,内部的环境变量。这就好像我们C语言中,编译器预定义的宏,比如__LINE__,或者当前的执行环境提供的环境变量,比如我们在Make执行的时候给Makefile传参数。比如我们的make CC=arm-linux-gcc。我们在Make时给Makefile传的环境变量优先级是最高的,可以覆盖makefile中的赋值。
Makefile中使用通配符
(1) * 表示若干个任意字符
(2) ? 代表一个任意字符 这里要理解清楚,比如我1.c 2.c 12.c 你用?,这个?仅仅代表这个.c前面是1个字符,所以这里只能匹配到1.c 2.c不能匹配到12.c
(3) [] 中括号的匹配方法就是挨个的拿出来跟外面的匹配,匹配到哪一个就是哪一个
还有一个%,也叫通配符,表示任意多个字符,和*很相似,但是%一般只用于规则描述中,又叫做规则通配符
Makefile的自动变量
(1)为什么使用自动变量 在有些情况下文件集合中文件非常多,描述的时候很麻烦,所以我们Makefile就用一些特殊的符号来代替符合某种条件的文件集,这就形成了自动变量
(2)自动变量的含义:预定义的特殊意义的符号,就类似与C语言编译器中预支的那些,__FILE__一样。
(3)常见的自动变量
[email protected] 规则的目标文件名
$< 规则的依赖文件名 在规则中就不止是一个了
$^ 依赖的文件集合