1、多个if判断
DEMO := 2 all: ifeq ($(DEMO), 1) @echo "DEMO 1" else ifeq ($(DEMO), 2) @echo "DEMO 2" else ifeq ($(DEMO), 3) @echo "DEMO 3" else @echo "DEMO Other" endif
输出:
DEMO 2 DEMO2
2、打印变量
可以使用 ${} 或者$() 或者 $ ,其中 $ 用于单字符变量,对于多字符变量,只能用前面两个
DEMO := 1
X := 1
all:
@echo \$$\{DEMO\} = ${DEMO}
@echo \$$\(DEMO\) = $(DEMO)
@echo \$$\X = $X
输出:
${DEMO} = 1
$(DEMO) = 1
$X = 1
3、=、:= 和 ?=
x := 1 y = 1 x ?= 2 all: @echo x=$(x) @echo y=$(y) y = 2 y ?= 3
输出:
x=1 y=2
4、ifdef和ifndef使用
X := 1 Y := Z := 2 all: ifndef X @echo "X = $(X)" else ifdef Y @echo "Y = ${Y}" else ifdef Z @echo "Z = ${Z}" endif
输出:
Z = 2
5、origin获得变量来源
w1 := $(origin W) x1 := $(origin X) y1 := $(origin Y) Z := 1 z1 := $(origin Z) c := $(origin CC) all: @echo "W: ${w1}" @echo "X: ${x1}" @echo "Y: ${y1}" @echo "Z: ${z1}" @echo "CC: ${c}"
运行:
$ X=1 make -f mk5 Y=2 W: undefined X: environment Y: command line Z: file CC: default
6、递归编译的三种方式
目录结构:
.
├── Makefile
├── sub1
│ └── Makefile
├── sub2
│ └── Makefile
├── sub3
│ └── Makefile
├── sub4
│ └── Makefile
└── sub5
└── Makefile
子目录的Makefile内容只输出一句话:
sub1/Makefile内容: all: @echo "\tThis is sub1" sub2/Makefile内容: all: @echo "\tThis is sub2" sub3/Makefile内容: all: @echo "\tThis is sub3" sub4/Makefile内容: all: @echo "\tThis is sub4" sub5/Makefile内容: all: @echo "\tThis is sub5"
顶层Makefile内容如下:
SUB_DIRS := $(sort $(wildcard sub*)) all: subdir @echo "\t\t**** method 2 ****" @echo "In top dir" @cd sub1 && make -s @cd sub2 && make -s @cd sub3 && make -s @cd sub4 && make -s @cd sub5 && make -s @echo "\n\t\t**** method 3 ****" @echo "In top dir" @for dir in $(SUB_DIRS); do \ make -s -C $$dir; \ done .PHONY: log $(SUB_DIRS) subdir:log $(SUB_DIRS) log: @echo "SUB_DIRS: \n\t$(SUB_DIRS)" @echo "\n\t\t**** method 1 ****" @echo "In top dir" $(SUB_DIRS): @make -s -C $@
输出:
SUB_DIRS: sub1 sub2 sub3 sub4 sub5 **** method 1 **** In top dir This is sub1 This is sub2 This is sub3 This is sub4 This is sub5 **** method 2 **** In top dir This is sub1 This is sub2 This is sub3 This is sub4 This is sub5 **** method 3 **** In top dir This is sub1 This is sub2 This is sub3 This is sub4 This is sub5
7、make -n 或者 make --just-print
可以用于调试Makefile的一些问题,此时make执行时只显示所要执行的命令,但不会真正的去执行这些命令
8、make -s 或者 make --slient
禁止所有执行命令的显示,就好像所有的命令行均使用"@"开始一样
9、.PHONY
使用这个修饰的目标,对应的命令会被无条件执行。而如果没有修饰的话,对于没有依赖文件的目标,只要目标文件不存在时才会执行定义的命令。
实例:
all: @echo "all is compiled" .PHONY:clean clean: @echo "clean is compiled"
体会下面的输出:
//此时当前目录只有一个Makefile文件 $ ls Makefile //执行make后,all作为第一个目标,由于当前目录下不存在all这个文件,所以all的命令被执行 $ make all is compiled $ make all all is compiled // clean由于是PHONY的,所以每次都执行 $ make clean clean is compiled // 然后在当前目录下分别创建all和clean两个文件 $ touch all $ touch clean $ ls all clean Makefile // 此时在编译all时,all的命令就不会执行了,因为当前目录已经存在all文件,并且all没有任何依赖文件 $ make make: 'all' is up to date. $ make all make: 'all' is up to date. // clean由于是PHONY的,命令无条件执行 $ make clean clean is compiled // 将all删除,发现all又可以执行了 $ rm all $ ls clean Makefile $ make all all is compiled // clean由于是PHONY的,命令无条件执行 $ make clean clean is compiled
如果在对Makefile做个修改:
all:clean @echo "all is compiled" .PHONY:clean clean: @echo "clean is compiled"
即,将all的依赖文件设置为clean,那么此后,all也会被无条件执行了
$ ls all clean Makefile $ make all clean is compiled all is compiled $ make clean is compiled all is compiled
10、模式匹配
- %
当前目录下有如下几个文件:
$ ls abc.A.abc a.c demo2.y demo.sh donglin.w Makefile
Makefile内容如下:
all:demo demo2.x pengdonglin.w helloAworld
@echo "all command"
%:%.c
@echo generate $@ through $<
%:%.sh
@echo generate $@ through $<
%.x:%.y
@echo generate $@ through $<
hello%world:abc.%.abc
@echo generate $@ through $<
peng%:%
@echo generate $@ through $<
下面是运行结果:
generate demo through demo.sh generate demo2.x through demo2.y generate pengdonglin.w through donglin.w generate helloAworld through abc.A.abc all command
11、make -p 或 make --print-data-base
可以查看在当前环境下make内置了那些规则
12、 $(if $(KBUILD_VERBOSE:1=),@) 语法释疑
https://blog.csdn.net/lcw_202/article/details/6656633
等价于:
$(if $(patsubst %1,%,$(KBUILD_VERBOSE)),@)
也就是,如果KBUILD_VERBOSE为1,那么上面的表达式就是空,否则的话,就是@,这样后面的命令就会静默输出
13、调用shell脚本
Makefile中的shell用法
makefile中的shell编程注意点
Shell脚本——make命令和Makefile文件
https://www.jb51.net/article/109797.htm
shell 文件内调用makefile文件:
#!/bin/bash cd ctemplate-2.1 ./configure sudo make -f install cd ../ cd TemplateProcesser make
说明:./configure文件是shell脚本文件,即shell内调用shell文件是很容易的;TemplateProcesser目录内有Makefile文件,调用方式,直接:make
makefile文件内调用shell脚本文件:
SHELL := /bin/bash test: @pwd cd ./TemplateProcesser && pwd sh ./build.sh @pwd
说明:build.sh为shell脚本文件。
调用perl文件 /usr/bin/perl *.pl 调用python文件 /usr/bin/env *.py
13、X:Y:Z
X := 1.o 2.o 3.o Y := 4.o 5.o 6.o all:$(X) $(Y) X_c := $(patsubst %.o,%.c,$(X)) Y_c := $(patsubst %.o,%.c,$(Y)) $(X):%.o:%.c @echo "$@ <---- $<" $(Y):%.o:%.c @echo "$@ <==== $<" .PHONY:$(X_c) $(Y_c)
输出:
1.o <---- 1.c 2.o <---- 2.c 3.o <---- 3.c 4.o <==== 4.c 5.o <==== 5.c 6.o <==== 6.c
===