当一个大的项目由很多子程序组成,而每一个子程序包都有自己独立的Makefile
,这时候就需要一个总控Makefile
来一次性完成所有的编译工作。以下给出了一个例子,以说明如何构建总控Makefile
。
文件结构
项目PRJ包含了三个子程序包。每个子程序包都拥有自己的Makefile
,从而可以在各目录下使用Make
完成编译。但是这样很麻烦。通过构建总控Makefile
(PRJ/Makefile
),可以一次性编译prj_sub1
,prj_sub2
,prj_sub3
三个子程序包。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17PRJ/
├── prj_sub1/
│ ├── a.c
│ ├── b.c
│ ├── c.c
│ └── Makefile
|
├── prj_sub2/
│ ├── d.c
│ ├── e.c
│ └── Makefile
├── prj_sub3/
│ ├── f.c
│ ├── g.c
│ └── Makefile
├── ...
└── Makefile
子程序包Makfile
子程序包中的Makefile
包含了编译
,install
,clean
操作。以下例子中,有关函数foreach
,自动化变量$@ $<
,以及静态模式
的内容可以参见X。
需要注意的是变量BIN
并没有在Makefile
中声明赋值,而是通过总控Makefile
中的export
来传递。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#Makefile for prj_sub1/
CC = gcc
EXEC = a b c
OBJ = $(foreach exe, ${EXEC}, ${exe}.o)
all: ${OBJ} ${EXEC}
${EXEC}:%:%.o
${CC} -o $@ $<
${OBJ}:%.o:%.c
${CC} -c -o $@ $<
install:
cp ${EXEC} ${BIN}
clean:
rm ${EXEC} ${OBJ}
总控Makefile
1 | export BIN=../bin |
总控Makefile一次性编译了prj_sub1
,prj_sub2
,prj_sub3
三个子程序包。
首先对变量SUBS_make
赋值,为prj_sub1.make prj_sub2.make prj_sub3.make
。类似的,完成变量SUBS_clean
,SUBS_install
的赋值。
随后,在编译中,${SUBS_make}:%.make:%
声明从变量SUBS_make
中逐次提取以.make
结尾的字段作为编译目标,去掉.make
之后的内容作为编译依赖项目,进而利用make -C $<
完成编译。第10,11行等价于:
1 | prj_sub1.make: prj_sub1 |
make -C prj_sub1
等价于cd prj_sub1; make
。其相当于先进入目录prj_sub1
,然后执行make
命令。
与编译类似,install
与clean
操作一次性完成所有子程序包的安装及清理操作。
需要注意的是,利用export BIN=../bin
,将变量BIN
传递至被调用Makefile
。