基本结构
target : dependency1 dependency2 dependencyn
command 1
command 2
...
command n
target
有多个target的时候,执行最上面的那个target,makefile默认target都是文件。
makefile如果检测到当前目录有和target同名的文件,就不会再次执行,需要将其删除再次make。
$ make file1
make: 'file1' is up to date.
另一种方式是通过设置.PHONY。 .PHONY后面的target表示的也是一个伪造的target, 而不是真实存在的文件target,这样即使当前目录下有target文件,也不会影响make的执行。
dependency
dependency既可以是文件,也可以是另一个target(默认其实也是文件,但需要生成)
command
command在其dependency都执行完了之后才会执行自己的command
默认每次执行command都会显示出来。
对于echo命令,加上@echo可以取消回显
变量
makefile中的变量更像是宏定义,可以在引用他的地方进行完整展开
环境变量大写,其他变量小写
LD_LIBRARY_PATH=/usr/local/lib
PATH=/usr/bin
引用的时候需要加$(变量名)
变量的赋值
符号 | 名称 |
---|---|
= | 引用的值是最后一次赋值的变量 |
:= | 引用的值是被引用之前的赋值有效,引用之后的再次赋值与此无关 |
?= | 之前赋值过了就不执行,否则进行赋值 |
+= | 在原有变量后追加新的变量 |
A = c
B = $(A)
A = b
all:
echo $(B)
输出是c
A := c
B := $(A)
A := b
all:
echo $(B)
输出是c
自动变量
自动变量 | 意义 |
---|---|
$@ | target的名字 |
$< | 第一个dependency的名字 |
$^ | 所有dependency的名字名,去除重复项 |
$+ | 所有dependency的文件名,不去重,且保留顺序 |
环境变量
make运行时的系统环境变量可以在make开始运行时被载入到Makefile文件中,但是如果Makefile中已定义了这个变量,或是这个变量由make命令行带入,那么系统的环境变量的值将被覆盖。
-e参数可以保证系统的环境变量覆盖makefile中的环境变量
需要注意环境变量会被所有的makefile所共用。export导出的本质其实就是以环境变量的方式被下层的makefile可见
export
如果在嵌套的makefile里想把上层的变量传递到下层,可以使用export进行声明,这样下层就可以看到这个变量
export variable := value
如果传递所有变量,那么只需要一个export,什么都不用跟。
命令行传进来的变量是不需要export就可以传递到下层。
变量值的批量替换
模式是这样的:
$(var : a=b)
意思是将var变量中的值,以“a”字串“结尾”的“a”替换成“b”字串。这里的“结尾”意思是“空格”或是“结束符”。
file1 = a.o,b.o,c.o
file2 = $(file1 : .o=.c)
file2的最终结果是a.c b.c c.c
模式变量
%是用来进行匹配的模式变量,同时结合上面的替换方式可以有以下的用法:
args1=DEFINE1 DEFINE2 DEFINE3
args2=path1 path2 path3
args+=$(args1 : %=+define+%)
args+=$(args2 : %=-y %)
all:
@echo $(args)
输出结果:
+define+DEFINE1 +define+DEFINE2 +define+DEFINE3 -y path1 -y path2 -y path3
结果看出是将args1和args2中的每个变量都加上相应的前缀,%就是用来匹配原先的变量的,%这次没匹配哪一部分,而是直接匹配整个变量值