You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Makefile将编译生成文件保存至独立目录?

把Fortran编译产物全塞进Build目录的Makefile修改方案

原Makefile改了OBJDIR却没生效?问题出在这几个地方:

  • 用了未定义的SOURCES变量,导致目标文件路径转换完全失效
  • .mod模块文件默认丢主目录,没指定输出到Build
  • .d依赖文件也留在主目录,没统一管理
  • 可执行文件还是生成在根目录,没移到Build
  • 没自动创建Build目录,编译时可能因为目录不存在报错

修改后的完整Makefile

# Compiler settings - 可自定义
CC = gfortran
CPP = gfortran -cpp
# 加-J$(OBJDIR)让.mod文件输出到Build目录
CXXFLAGS = -g -O0 -Wall -Wextra -Wshadow -pedantic -J$(OBJDIR)
LDFLAGS =

# Makefile settings - 可自定义
APPNAME = myapp
EXT = .f90
SRCDIR = src
# 把Build放主目录和src平级,更清晰(想放src里就改回src/Build)
OBJDIR = Build

############## 核心修改部分 #############
# 获取src下所有Fortran源文件
SRC = $(wildcard $(SRCDIR)/*$(EXT))
# 把源文件路径转成Build下的.o文件路径
OBJ = $(patsubst $(SRCDIR)/%$(EXT), $(OBJDIR)/%.o, $(SRC))
# 依赖文件也放Build里
DEP = $(OBJ:$(OBJDIR)/%.o=$(OBJDIR)/%.d)
# Unix系统设置
RM = rm -rf
DELOBJ = $(OBJ) $(DEP) $(OBJDIR)/*.mod
# 可执行文件直接放Build
APP_PATH = $(OBJDIR)/$(APPNAME)
# Windows系统设置
DEL = del /Q /F
EXE = .exe
WDELOBJ = $(patsubst $(SRCDIR)/%$(EXT), $(OBJDIR)\\%.o, $(SRC))
WAPP_PATH = $(OBJDIR)\\$(APPNAME)$(EXE)

########################################################################
####################### 编译目标开始 #########################
########################################################################

all: $(APP_PATH)

# 编译前先确保Build目录存在
$(OBJDIR):
	mkdir -p $(OBJDIR)

# 生成可执行文件,依赖Build目录和所有.o文件
$(APP_PATH): $(OBJDIR) $(OBJ)
	$(CC) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)

# 生成依赖文件,输出到Build目录
$(OBJDIR)/%.d: $(SRCDIR)/%$(EXT) $(OBJDIR)
	@$(CPP) $(CXXFLAGS) $< -MM -MT $(@:$(OBJDIR)/%.d=$(OBJDIR)/%.o) >$@

# 引入所有依赖文件
-include $(DEP)

# 编译生成.o文件,依赖Build目录
$(OBJDIR)/%.o: $(SRCDIR)/%$(EXT) $(OBJDIR)
	$(CC) $(CXXFLAGS) -o $@ -c $<

################### Unix系统清理规则 ###################
# 清理所有编译产物
.PHONY: clean
clean:
	$(RM) $(DELOBJ) $(APP_PATH)

# 只清理依赖文件
.PHONY: cleandep
cleandep:
	$(RM) $(DEP)

#################### Windows系统清理规则 #####################
# 清理所有编译产物
.PHONY: cleanw
cleanw:
	$(DEL) $(WDELOBJ) $(OBJDIR)\*.mod $(DEP) $(WAPP_PATH)
	if exist $(OBJDIR) rmdir /S /Q $(OBJDIR)

# 只清理依赖文件
.PHONY: cleandepw
cleandepw:
	$(DEL) $(DEP)

关键修改点说明

  1. 管住.mod文件:在CXXFLAGS里加-J$(OBJDIR),gfortran会自动把编译生成的模块文件扔到Build目录,不会乱跑到主目录
  2. 修复路径转换:把原Makefile里的$(SOURCES)换成实际定义的$(SRC),这样目标文件的路径转换才会生效
  3. 统一依赖文件:把.d依赖文件也放到Build目录,主目录再也不会出现一堆零散的依赖文件
  4. 自动建目录:新增$(OBJDIR)目标,编译前自动创建Build目录,不用手动建
  5. 可执行文件搬家:把可执行文件的输出路径改成$(OBJDIR)/$(APPNAME),编译完直接在Build里找就行
  6. 清理更彻底:清理规则加上了.mod文件的删除,执行make clean就能把Build目录的产物全清干净

内容的提问来源于stack exchange,提问作者mho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 15:34:54