嵌套执行make
在一些大的工程中,我们会把我们不同模块或是不同功能的源文件放在不同的目录中,我们可以在每个目录中都书写一个该目录的Makefile,这有利于让我们的Makefile变得更加地简洁,而不至于把所有的东西全部写在一个Makefile中,这样会很难维护我们的Makefile,这个技术对于我们模块编译和分段编译有着非常大的好处。
例如,我们有一个子目录叫subdir,这个目录下有个Makefile文件,来指明了这个目录下文件的编译规则。那么我们总控的Makefile可以这样书写:
- subsystem:
- cd subdir && $(MAKE)
其等价于:
- subsystem:
- $(MAKE) -C subdir
定义$(MAKE)宏变量的意思是,也许我们的make需要一些参数,所以定义成一个变量比较利于维护。这两个例子的意思都是先进入“subdir”目录,然后执行make命令。
我们把这个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 variable += value
其等价于:
- variable += value
- export variable
如果你要传递所有的变量,那么,只要一个export就行了。后面什么也不用跟,表示传递所有的变量。
需要注意的是,有两个变量,一个是 SHELL
,一个是 MAKEFLAGS
,这两个变量不管你是否export,其总是要传递到下层 Makefile中,特别是 MAKEFLAGS
变量,其中包含了make的参数信息,如果我们执行“总控Makefile”时有make参数或是在上层 Makefile中定义了这个变量,那么MAKEFLAGS
变量将会是这些参数,并会传递到下层Makefile中,这是一个系统级的环境变量。
但是make命令中的有几个参数并不往下传递,它们是 -C
, -f
, -h
, -o
和-W
(有关Makefile参数的细节将在后面说明),如果你不想往下层传递参数,那么,你可以这样来:
- subsystem:
- cd subdir && $(MAKE) MAKEFLAGS=
如果你定义了环境变量 MAKEFLAGS
,那么你得确信其中的选项是大家都会用到的,如果其中有-t
, -n
和 -q
参数,那么将会有让你意想不到的结果,或许会让你异常地恐慌。
还有一个在“嵌套执行”中比较有用的参数, -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
总是失效的。