一般是
SUB_DIR = lib_src service .PHONY: subdirs $(SUB_DIR) subdirs: $(SUB_DIR) $(SUB_DIR): @+make -C $@ foo: baz或者
subdirs: for dir in $(SUB_DIR); do \ @+make -C $$dir; \ done使用循环的方式比较直观,但是会有这样的问题
当submake报错的时候不会停止,其他submake会继续执行不能体验到make的并行编译 即-j选项子目录之间的依赖不好表示所以,一般来说会选择第一种来写.但是,当用第一种书写时,怎么表达make子命令(即:make install)呢?
核心就是对子目录名字进行包裹一下,把包裹后的名字当作新的伪目标进行构建
以下是我从工作项目中拷出来的总共三个级别的目录
根目录lib_src service实际编译目录:game gate所以列举了3个makefile
目录做了一些删减bin输出目录:deploy/bin
├── deploy │ └── bin ├── deps │ └── tinyxml │ ├── include │ │ └── tinyxml │ │ └── tinyxml.h │ └── lib │ └── libtinyxml.a ├── lib_src │ ├── auth │ │ ├── auth.cpp │ │ └── auth.h │ ├── common │ │ ├── common.cpp │ │ └── common.h │ └── lib └── service ├── game │ └── game.cpp └── gate编译选项这些忽略吧
MKFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST))) include ../../global.mk TARGET := $(BIN_DIR)/game_svr$(BIN_TAG) CUR_INC_FLAGS := -I$(FRAME_INC) -I./ -I$(MYSQL_INC) CUR_LINK_FLAGS := $(LDFLAGS) -L$(MYSQL_LIB) CUR_CPPFLAGS := $(CPPFLAGS) $(CUR_INC_FLAGS) SUB_DIR := app bll dal db thread config ALL_OBJS = $(wildcard $(OBJ_DIR)/*.o) all : |$(OBJ_DIR) $(TARGET) $(TARGET) : $(TARGET_OBJS) $(SUB_DIR) $(CXX) -o $@ $(ALL_OBJS) $(CUR_LINK_FLAGS) @echo "#### compile ok "$(TARGET) "####" $(OBJ_DIR)/%.o : %.cpp $(CXX) $(CUR_CPPFLAGS) -c $< -o $@ $(OBJ_DIR): @mkdir $@ $(SUB_DIR): @echo "#### compile sub dir start ####" $@ @+make -C $@ @echo "#### compile sub dir end ####" $@ clean: @rm -f $(wildcard $(OBJ_DIR)/*.o) $(TARGET) test: @echo $(MKFILE_PATH) .PHONY: all test clean .PHONY: $(SUB_DIR)在真正执行命令的时候才会对变量求值,所以变量值可能会在中间因为其他引用的其他变量被改变而不是预期的
在赋值的时候直接对变量求值,以后如果不重新赋值是不会变化的