跟我学Makefile(二)
命令出错:
每当命令运行完后, make 会检测每个命令的返回码,如果命令返回成功,那么 make 会执行下一条命令。
如果一个规则中的某个命令出错了(命令退出码非零),那么 make 就会终止执行当前规则,这将有可能终止所有规则的执行。
为了做到忽略命令的出错,我们可以在 Makefile 的命令行前加一个减号“-”(在Tab 键之后),标记为不管命令出不出错都认为是成功的。
clean:
-rm -f *.o
还有一个全局的办法是,给 make 加上“-i”或是“--ignore-errors”参数,那么,Makefile 中所有命令都会忽略错误。而如果一个规则是以“.IGNORE”作为目标的,那么这个规则中的所有命令将会忽略错误。这些是不同级别的防止命令出错的方法,你可以根据你的不同喜欢设置。
还有一个要提一下的 make 的参数的是“-k”或是“--keep-going”,意思是,如果某规则中的命令出错了,那么就终止该规则的执行,但继续执行其它规则。
嵌套makefile:
总控 Makefile 的变量可以传递到下级的Makefile 中(如果你显示的声明),但是不会覆盖下层的 Makefile 中所定义的变量,除非指定了“-e”参数 。
如果你要传递变量到下级 Makefile 中,那么你可以使用这样的声明:
export <variable ...>
如果你不想让某些变量传递到下级 Makefile 中,那么你可以这样声明:
unexport <variable ...>
eg:
export variable = value 其等价于: variable = value export variable 其等价于: export variable := value 其等价于: variable := value export variable
如果你要传递所有的变量,那么,只要一个 export 就行了。后面什么也不用跟,表示传递所有的变量。
make 命令中的有几个参数并不往下传递,它们是“-C” ,“-f” ,“-h”“-o”和“-W”,如果你不想往下层传递参数,那么,你可以这样来
subsystem:
cd subdir && $(MAKE) MAKEFLAGS=
“-w”或是“--print-directory”会在 make的过程中输出一些信息,让你看到目前的工作目录。
如,我们下级 make 目录是“/home/hchen/gnu/make”,如果我们使用“make -w”来执行,那么当进入该目录时,我们会看到:
make: Entering directory `/home/hchen/gnu/make'.
在完成下层 make 后离开目录时,我们会看到:
make: Leaving directory `/home/hchen/gnu/make'
当你使用“-C”参数来指定 make 下层 Makefile 时,“-w”会被自动打开的。如果参数中有“-s”(“--slient”)或是“--no-print-directory”,那么,“-w”总是失效的。
使用变量:(类似C中宏)
在 Makefile 中,变量可以使用在“目标”,“依赖目标”,“命令”或是 Makefile 的其它部分中 。
变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有“:”、“#”、“=”或是空字符(空格、回车等)。变量是大小写敏感的 。
变量在声明时需要给予初值,在使用时,需要给在变量名前加上“$”符号,但最好用小括号“()”或是大括号“{}”把变量给包括起来。如果你要使用真实的“$”字符,那么你需要用“$$”来表示。
objects = program.o foo.o utils.o program : $(objects) cc -o program $(objects) $(objects) : defs.h
变量会在使用它的地方精确地展开,就像 C/C++中的宏一样。
变量的定义:(两种方法)
方法1、使用“=”号,在“=”左侧是变量,右侧是变量的值,右侧变量的值可以定义在文件的任何一处,也就是说,右侧中的变量不一定非要是已定义好的值,其也可以使用后面定义的值 。
foo = $(bar) bar = $(ugh) ugh = Huh? all: echo $(foo)
执行“make all”将会打出变量$(foo)的值是“Huh?”
这种定义优点:变量的真实值推到后面来定义
方法2、使用“:=”操作符
x := foo y := $(x) bar x := later
等价于:
y := foo bar
x := later
这种方法的优点:前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。
y := $(x) bar
x := foo
那么, y 的值是“bar”,而不是“foo bar”。
系统变量“MAKELEVEL” 如果我们的 make 有一个嵌套执行的动作(参见前面的“嵌套使用 make”),那么,这个变量会记录了我们的当前 Makefile 的调用层数。
操作符是“?=”
FOO ?= bar
FOO 没有被定义过,那么变量 FOO 的值就是“bar”,如果 FOO 先前被定义过,那么这条语将什么也不做。