C++项目Makefile如何自动创建不存在的obj目录?
解决Makefile自动创建obj目录的问题
原始Makefile内容
SRC_DIR := ./src OBJ_DIR := ./obj INC_DIR := -I./include SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp) OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES)) CXXFLAGS := -Wall -g main.exe: $(OBJ_FILES) g++ $(LDFLAGS) -o $@ $^ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp g++ $(CPPFLAGS) $(CXXFLAGS) $(INC_DIR) -c -o $@ $<
问题描述
全新构建时,因为obj目录不存在,编译会报错:
Fatal error: can't create obj/Myclass.o: No such file or directory
需要实现让make自动检测并创建obj目录,无需手动操作。
解决方案
推荐使用order-only依赖(Makefile特有的依赖类型,仅当目标不存在时执行,不会因目录时间戳变化触发重新编译),具体修改如下:
修改后的完整Makefile
SRC_DIR := ./src OBJ_DIR := ./obj INC_DIR := -I./include SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp) OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES)) CXXFLAGS := -Wall -g # 定义obj目录的创建规则 $(OBJ_DIR): mkdir -p $@ # 为目标文件添加order-only依赖,确保编译前目录存在 main.exe: $(OBJ_FILES) $(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR) g++ $(CPPFLAGS) $(CXXFLAGS) $(INC_DIR) -c -o $@ $<
关键修改说明
- 添加
$(OBJ_DIR)的规则:使用mkdir -p确保目录创建(-p参数会忽略已存在的目录,避免报错)。 - 在目标文件的模式规则中,用
| $(OBJ_DIR)添加order-only依赖:表示编译.o文件前必须确保obj目录存在,但obj目录的时间戳更新不会触发.o文件的重新编译,比每次编译都执行mkdir更高效。
备选方案(简单但稍冗余)
如果不想用order-only依赖,也可以直接在编译命令前加入目录创建:
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp mkdir -p $(OBJ_DIR) g++ $(CPPFLAGS) $(CXXFLAGS) $(INC_DIR) -c -o $@ $<
这种方式每次编译.o文件都会执行mkdir -p,虽然不会报错,但存在不必要的重复执行,适合简单场景。
内容的提问来源于stack exchange,提问作者Engineer999
相关产品推荐
相关产品推荐

