在实际开发项目中,我们通常将一个工程划分为多个文件夹,每个文件夹代表不能的功能,如:我的一个项目cpl,它分为两个文件夹:src和test。当在cpl文件夹中运行make的时候,它的一级目录都会自动运行各自文件夹中的Makefile,cpl文件夹中的Makefile需要定义一些编译变量,如:包含的库,编译标志。这些变量需要通过export命令导出至子级Makefile文件中,如下:
CC = g++
INCLUDE = $(shell pwd)/src
CFLAGS = -I $(INCLUDE) -ggdb -Wall -Wextra -Werror --std=c++11
LIBS = -lpthread -lgtest
export
子级test文件夹makefile内容如下:
../test_graph.o:test_graph.cpp ${INCLUDE}/graph.h libgtest.a
@echo ${INCLUDE}
$(CC) -c $< -o $@ $(CFLAGS) $(LIBS)
子级src文件夹makefile内容如下:
../graph.o:graph.cpp graph.h
$(CC) -c $< -o $@ $(CFLAGS)
在上面的Makefile中,INCLUDE变量当通过{}引用为数组格式,()引用只读取第一个元素。$@为引用编译目标(target),$<引用依靠列表(dependent list)。对象文件输出至上一级文件夹,当然也可以输出至对应的目标文件夹。
整个cpl文件夹中的Makefile文件列表如下:
CC = g++
INCLUDE = $(shell pwd)/src
CFLAGS = -I $(INCLUDE) -ggdb -Wall -Wextra -Werror --std=c++11
LIBS = -lpthread -lgtest
export subdirs := $(shell find * -maxdepth 0 -type d)
objects := $(wildcard *.o) subdirs:
for dir in $(subdirs); do \
$(MAKE) -C $$dir; \
done all: main main:$(objects)
@echo ${objects}
$(CC) $(CFLAGS) ${objects} $(LIBS) -o $@ .PHONY: clean clean:
rm *.o
rm main
当输入make时,自动编译所有子目录的makefile,这样就实现了拆分编译。