多子目录源码对应生成独立二进制文件的Makefile编写问题
Makefile多源文件单独编译解决方案
问题根因
你现有写法的问题在于$(EXES): $(SRCF)这条规则将所有二进制目标的依赖绑定到了全部源文件,Make自动变量$<只会取依赖列表的第一个文件,因此所有目标都会编译同一个源文件,无法实现一一对应编译的效果。
修改后完整Makefile
# 编译器定义 FC = gfortran # 目录配置(因为Makefile放在Gamma目录下,直接用相对路径更灵活,无需写绝对路径) BIN = ../bin FROOT = . # 自动收集所有5a开头子目录下的Fortran源文件,无需手动逐个添加子目录 SRCF = $(wildcard $(FROOT)/5a*/*.f03) # 生成对应二进制文件路径:去掉源文件后缀和源目录名,加上bin目录前缀 EXES = $(addprefix $(BIN)/, $(notdir $(patsubst %.f03, %, $(SRCF)))) # 编译参数:将mod文件生成到bin目录 FCFLAGS = -J $(BIN) # 默认编译目标:生成所有二进制文件 all: $(EXES) # 核心静态模式规则:为每个二进制文件匹配对应同名源文件 $(EXES): $(BIN)/% : $(wildcard $(FROOT)/5a*/%.f03) @mkdir -p $(BIN) $(FC) $(FCFLAGS) -o $@ $< # 可选清理规则:一键删除bin目录下所有生成文件 clean: rm -rf $(BIN)/*
关键修改说明
- 源文件收集优化:用通配符
$(wildcard $(FROOT)/5a*/*.f03)自动匹配所有符合命名规则的子目录下的f03文件,后续新增5a30这类子目录时不需要修改Makefile,维护更方便。 - 静态模式规则:
$(EXES): $(BIN)/% : $(wildcard $(FROOT)/5a*/%.f03)会对每一个待生成的二进制目标,提取出文件名前缀,自动去所有5a开头的子目录下找对应的同名源文件作为依赖,保证每个目标只依赖对应的源文件,解决了所有目标都编译第一个源的问题。 - 新增目录自动创建:
@mkdir -p $(BIN)避免第一次编译时bin目录不存在导致的报错。
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

