单Makefile编译src多子目录C/C++混合源码问题咨询
可行实现方案
你之前的规则报错是因为多依赖的模式规则要求每个.o对应的三个源文件必须同时存在,无法匹配仅存在于单个路径下的源文件。以下是无需shell find、仅用单个Makefile的实现方案:
1. 核心配置思路
- 用Make内置的
VPATH变量定义源码搜索路径,新增子目录手动更新即可,无需遍历 - 分开编写C和C++的模式编译规则,避免两类文件编译参数冲突
- 编译时自动创建OBJ目录下对应的子目录结构,避免路径不存在报错
2. 完整Makefile示例
基础变量定义
# 目录配置 SRC_DIR := src OBJ_DIR := obj # 手动添加所有源码存放的子目录,新增目录直接追加到此处即可 SRC_SUBDIRS := $(SRC_DIR) $(SRC_DIR)/common # 告诉Make在指定路径下搜索源文件 VPATH := $(SRC_SUBDIRS) # 编译工具与参数配置 CC := gcc CXX := g++ # 头文件搜索路径,按需新增 CPPFLAGS := -I$(SRC_DIR) -I$(SRC_DIR)/common # C语言专属编译参数 CFLAGS := -Wall -O2 -g # C++专属编译参数 CXXFLAGS := -Wall -O2 -g -std=c++17 # 链接参数,按需添加库依赖 LDFLAGS := -lpthread
编译规则定义
# C++源文件编译规则 $(OBJ_DIR)/%.o: %.cpp | $(OBJ_DIR) @mkdir -p $(dir $@) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@ # C源文件编译规则 $(OBJ_DIR)/%.o: %.c | $(OBJ_DIR) @mkdir -p $(dir $@) $(CC) $(CPPFLAGS) $(CFLAGS) -c $< -o $@ # 根OBJ目录创建规则 $(OBJ_DIR): mkdir -p $@
最终目标配置
方案A:手动指定目标文件(完全可控)
直接列出所有源文件对应的.o路径即可,示例:
TARGET := my_app # 对应src/main.cpp、src/common/utils.cpp、src/common/hal.c三个源文件 OBJS := $(OBJ_DIR)/main.o $(OBJ_DIR)/utils.o $(OBJ_DIR)/hal.o $(TARGET): $(OBJS) $(CXX) $^ -o $@ $(LDFLAGS)
方案B:内置函数自动扫源文件(无需shell find)
用Make内置的wildcard函数按目录扫文件,无需调用shell:
TARGET := my_app # 分别扫描各目录下的C/C++源文件,新增目录只需追加对应wildcard规则 CPP_SRCS := $(wildcard $(SRC_DIR)/*.cpp) $(wildcard $(SRC_DIR)/common/*.cpp) C_SRCS := $(wildcard $(SRC_DIR)/*.c) $(wildcard $(SRC_DIR)/common/*.c) # 自动转换为.o路径 OBJS := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(CPP_SRCS)) \ $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(C_SRCS)) $(TARGET): $(OBJS) $(CXX) $^ -o $@ $(LDFLAGS)
3. 常用辅助规则(可选)
# 清理规则 .PHONY: clean clean: rm -rf $(OBJ_DIR) $(TARGET)
内容的提问来源于stack exchange,提问作者Engineer999
相关产品推荐
相关产品推荐

