1. 嵌套执行 make
在一个大的工程文件中,不同的文件按照功能被划分到不同的模块中,每个模块可能都会有自己的编译顺序和规则,如果在一个 Makefile
文件中描述所有模块的编译规则,就会很乱,执行时也会不方便,所以就需要在不同的模块中分别对它们的规则进行描述,也就是每一个模块都编写一个 Makefile
文件,这样不仅方便管理,而且可以迅速发现模块中的问题。这样我们只需要控制其他模块中的 Makefile
就可以实现总体的控制,这就是 make
的嵌套执行。
如何来使用呢?举例说明如下:
subsystem:
cd subdir && $(MAKE)
这个例子可以这样来理解,在当前目录下有一个目录文件 subdir
和一个 Makefile
文件,子目录 subdir
文件下还有一个 Makefile
文件,这个文件是用来描述这个子目录文件的编译规则。
使用时只需要在最外层的目录中执行 make
命令,当命令执行到上述的规则时,程序会进入到子目录中执行 make
。这就是嵌套执行 make
,我们把最外层的 Makefile
称为是总控 Makefile
。
上述的规则也可以换成另外一种写法:
subsystem
$(MAKE) -C subdir
在 make
的嵌套执行中,我们需要了解一个变量 CURDIR
,此变量代表 make
的工作目录。当使用 make
的选项 -C
的时候,命令就会进入指定的目录中,然后此变量就会被重新赋值。
总之,如果在 Makefile
中没有对此变量进行显式的赋值操作,那么它就表示 make
的工作目录。我们也可以在 Makefile
中为这个变量赋一个新的值,当然重新赋值后这个变量将不再代表 make
的工作目录。
2. export 的使用
使用 make
嵌套执行的时候,变量是否传递也是我们需要注意的。如果需要变量的传递,那么可以这样来使用:
export <variable>
如果不需要那么可以这样来写:
unexport <variable>
<variable>
是变量的名字,不需要使用 $
这个字符。如果所有的变量都需要传递,那么只需要使用 export
就可以,不需要添加变量的名字。
export VALUE1 := export.c <-- 用了 export, 此变量能够传递到 ./other/Makefile 中
...
@cd ./other && make
...
export
语法格式如下:
export variable = value
export variable := value
export variable += value
Makefile
中还有两个变量不管是不是使用关键字 export
声明,它们总会传递到下层的 Makefile
中。这两个变量分别是 SHELL
和 MAKEFLAGS
,特别是 MAKEFLAGS
变量,包含了 make
的参数信息。
如果执行总控 Makefile
时,make
命令带有参数或者在上层的 Makefile
中定义了这个变量,那么 MAKEFLAGS
变量的值将会是 make
命令传递的参数,并且会传递到下层的 Makefile
中,这是一个系统级别的环境变量。
make
命令中有几个参数选项并不传递,它们是:-C
、-f
、-o
、-h
和 -W
。如果我们不想传递 MAKEFLAGS
变量的值,在 Makefile
中可以这样来写:
subsystem:
cd subdir && $(MAKE) MAKEFLAGS=
3. 嵌套执行示例
目录结构如下:
wohu@ubuntu:~/cpp/func$ tree
.
├── demo.cpp
├── demo.h
├── Makefile
└── subdir
└── Makefile
1 directory, 4 files
wohu@ubuntu:~/cpp/func$
当前目录下的 Makefile
内容:
export GLOBAL_VAR = 123
SUBDIR = ./subdir
all:
echo "this is main Makefile"
echo $(GLOBAL_VAR)
cd $(SUBDIR) && $(MAKE)
subdir
目录下的 Makefile
内容:
all:
echo "this is subdir Makefile"
echo "display GLOBAL_VAR" $(GLOBAL_VAR)
在当前目录下执行 make
输出结果
wohu@ubuntu:~/cpp/func$ make
echo "this is main Makefile"
this is main Makefile
echo 123
123
cd ./subdir && make
make[1]: Entering directory '/home/wohu/cpp/func/subdir'
echo "this is subdir Makefile"
this is subdir Makefile
echo "display GLOBAL_VAR" 123
display GLOBAL_VAR 123
make[1]: Leaving directory '/home/wohu/cpp/func/subdir'
wohu@ubuntu:~/cpp/func$