#上一条命令的结果应用在下一条命令时,你应该使用分 号分隔这两条命令
exec:
cd /home/hchen
pwd
#cd没有作用,pwd会打印出当前的Makefile
exec:
cd /home/hchen; pwd
#忽略命令的出错,我们可以在Makefile的命令行前加一个减号“-”
clean:
-rm -f *.o
#还有一个全局的办法是,给make加上“-i”或是“--ignore-errors”参数,Makefile中所有命令都会忽略错误。
#make的参数的是“-k”或是“--keep-going”,这个参数的意思是,如果某规则中的命令出错了,那么就终目该规则的执行,但继续执行其它规则
--------------------------------------------------------------
#子目录叫subdir,这个目录下有个Makefile 文件,来指明了这个目录下文件的编译规则。
#这两个例子的意思都是先进入“subdir”目录,然后执行 make 命令。
#定义$(MAKE)宏变量的意思是,也许我们的 make 需要一些参数,所以定义成一个变量比较 利于维护。
subsystem:
cd subdir && $(MAKE)
#等价于:
subsystem:
$(MAKE) -C subdir
#这个Makefile叫做“总控 Makefile”,总控 Makefile的变量可以传递到下级的 Makefile 中(如果你显示的声明),但是不会覆盖下层的 Makefile中所定义的变量,除非指定了“-e”参数。
#如果你要传递变量到下级 Makefile中,那么你可以使用这样的声明:
export <variable ...>
#如果你不想让某些变量传递到下级 Makefile 中,那么你可以这样声明:
unexport <variable ...>
export variable = value
等价于:
variable = value
export variable
export variable += value
其等价于:
variable += value
export variable
如果你要传递所有的变量,那么,只要一个export就行了。后面什么也不用跟,表示传递 所有的变量。
需要注意的是,有两个变量,一个是 SHELL,一个是MAKEFLAGS这两个变量不管你是否 export,其总是要传递到下层 Makefile 中,特别是MAKEFILES变量,其中包含了 make 的参数信息,如果我们执行“总控 Makefile”时有 make参数或是在上层 Makefile 中定义了这个变量,那么MAKEFILES变量将会是这些参数,并会传递到下层Makefile中,这是一个系统级的环境变量。
#如果你不想往下层传递参数,可以这样来:
subsystem:
cd subdir && $(MAKE) MAKEFLAGS=
--------------------------------------------------------------
#如果 Makefile 中出现一些相同命令序列,那么我们可以为这些相同的命令序列定义一个变 量。以“define”开始,以“endef”结束
define run-yacc
yacc $(firstword $^)
mv y.tab.c $@
endef
这里,“run-yacc”是这个命令包的名字,其不要和 Makefile 中的变量重名。在“define” 和“endef”中的两行就是命令序列。
#这个命令包中的第一个命令是运行 Yacc 程序,因为 Yacc 程序总是生成“y.tab.c”的文件,所以第二行的命令就是把这个文件改改名字。
foo.c : foo.y
$(run-yacc)
--------------------------------------------------------------
在 Makefile 中的定义的变量,就像是 C/C++语言中的宏一样,他代表了一个文本字串。其与 C/C++所不同的是,你可以在 Makefile 中改变其值。
变量可以使用在“目标”,“依赖目标”,“命令”或是 Makefile 的其它部分中。
变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有“:”、“#”、 “=”或是空字符(空格、回车等)。变量是大小写敏感的,推荐使用大小写搭配的变量名,如:MakeFlags。这样可以避免和系统的变量冲突,而发生意外的事情。
变量在声明时需要给予初值,而在使用时,需要给在变量名前加上“$”符号,但最好用小括号“()”或是大括号“{}”把变量给包括起来。如果你要使用真实的“$”字符,那么你需要用“$$”来表示。
objects = program.o foo.o utils.o program : $(objects)
cc -o program $(objects)
$(objects) : defs.h
--------------------------------------------------------------
在“=”左侧是变量,右侧是变量的值,右侧变量的值可以定义在文件的任何一处,也就是说,右侧中的变量不一定非要是已定义好的值, 其也可以使用后面定义的值。如:
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:
echo $(foo)
我们可以使用 make 中的另一种用变量来定义变量的方法。这种方法使用的是“:=”操作符.第一个例子中y的值是“bar”,而不是“foo bar”。
x := foo
y := $(x) bar
x := later
其等价于:
y := foo bar
x := later
ifeq (0,${MAKELEVEL})
cur-dir := $(shell pwd)
whoami := $(shell whoami)
host-type := $(shell arch)
MAKE := ${MAKE} host-type=${host-type} whoami=${whoami}
endif
#后面采用“#”注释符来表示变量定义的终止
nullstring :=
space := $(nullstring) # end of the line
dir := /foo/bar # directory to put the frobs in
FOO没有被定义过,那么变量 FOO 的值就是“bar”,如果 FOO 先前被定义过,那么这条语将什么也不做
FOO ?= bar
等价于:
ifeq ($(origin FOO), undefined)
FOO = bar
endif
--------------------------------------------------------------
#变量值的替换
先定义了一个“$(foo)”变量,而第二行的意思是把“$(foo)”中所有 以“.o”字串“结尾”全部替换成“.c”,所以我们的“$(bar)”的值就是“a.c b.c c.c”。
foo := a.o b.o c.o
bar := $(foo:.o=.c)
#把变量的值再当成变量
$(x)的值是“y”,所以$($(x))就是$(y),于是$(a)的值就是“z”。(注 意,是“x=y”,而不是“x=$(y)”)
x = y
y = z
a := $($(x))
x = $(y)
y = z
z = Hello
a := $($(x))
这里的$($(x))被替换成了$($(y)),因为$(y)值是“z”,所以,最终结果是:a:=$(z), 也就是“Hello”。
--------------------------------------------------------------
#$(objects)值变成:“main.o foo.o bar.o utils.o another.o” (another.o 被追加进去了)
objects = main.o foo.o bar.o utils.o objects += another.o
#override 指示符