5.编写recipes
用户使用不同的shell程序,但是在makefiles总是使用/bin/sh
执行recipe,除非makefile指定了其它的shell。
recipe语法¶
Makefile有两种语法:make语法和shell语法。make不会去理解shell语法,执行简单的翻译就交给shell去处理。recipe使用的是shell语法。
每个recipe所在行都要有tab开头,除了第一行recipe可能会被附加到目标行(分号隔开)。
分割recipe行¶
例1:
all :
@echo no\
space
@echo no\
space
@echo one \
space
@echo one\
space
输出:
nospace
nospace
one space
one space
例2:
all : ; @echo 'hello \
world' ; echo "hello \
world"
输出:
hello \
world
hello world
想要使用单引号,并且不想出现\
,那么可以将其转换为make变量:
HELLO = 'hello \
world'
all : ; @echo $(HELLO)
输出:
hello world
在recipes中使用变量¶
不会重新构建的目标不会被扩展,即不会调用新的recipe。
如果想要$
出现在recipe中,必须键入两个引用:$$
LIST = one two three
all:
for i in $(LIST); do \
echo $$i; \
done
recipe输出¶
正常情况下make在执行recipe之前会打印它。
如果recipe前加上了@
符号,就不会打印recipe,当传给shell处理的时候该符号会被丢弃掉。
给make-n
、--just-print
的flag时候,只会输出大部分recipe而不执行,带有@
符号的行也会被打印出来。
flag-s
、--silent
会阻止echoing,就像所有的行都加了@
符号。
recipe执行¶
执行recipe时,每行recipe都会调用一个新的sub-shell来执行,除非定义.ONESHELL
特殊目标。所以本行的shell变量和诸如cd的目录不会影响后续的recipe。
make的递归使用¶
意思就是在makefile文件中使用make作为命令。当你现要为子系统分离makefile的时候很有用。
subsystem:
cd subdir && $(MAKE)