Makefile 使用make将对象文件存储在单独的目录中

Makefile 使用make将对象文件存储在单独的目录中,makefile,fortran,mingw,gfortran,Makefile,Fortran,Mingw,Gfortran,我正在windows上使用mingw运行makefile。我已经看到很多关于这个主题的链接,但是它们似乎都是C或C++的。我不确定是否适用相同的规则,因为我使用的是windows,语法似乎也有点不同。以下是一些其他参考资料: (我认为最有希望) 我现在拥有的是(逐字记录) 请注意,在收到错误后,我可以使用以下命令在错误后显式编译parametricStudy.f90: gfortran -g -J.\\mod -fopenmp -c -o .\\obj\parametricStudy.o

我正在windows上使用mingw运行makefile。我已经看到很多关于这个主题的链接,但是它们似乎都是C或C++的。我不确定是否适用相同的规则,因为我使用的是windows,语法似乎也有点不同。以下是一些其他参考资料:

(我认为最有希望)

我现在拥有的是(逐字记录)

请注意,在收到错误后,我可以使用以下命令在错误后显式编译parametricStudy.f90:

 gfortran -g -J.\\mod -fopenmp -c -o .\\obj\parametricStudy.o parametricStudy.f90
然后输入

 gmake
同样,这不会导致任何错误。我很困惑

以下是我的目录截图:


也许这和目标有关?最后一个文件的路径似乎有点错误。非常感谢您的帮助

你面临的问题是

ROOT_DIR = "C:\Users\Charlie\"
OBJ_DIR = $(ROOT_DIR)\obj
规则

$(OBJ_DIR)/%.o: %.f90
扩展到

"C:\Users\Charlie\"obj/%.o: %.f90
它被解析为静态模式规则

"C: \Users\Charlie\"obj/%.o: %.f90
也就是说,使用target
“C
、target模式
\Users\Charlie\”obj/%.o
和prerequisite模式
%.f90
。投诉
“C
与模式
\Users\Charlie\”obj/%.o
不匹配

GNU make中有一些黑客代码(至少在MinGW中是这样;我认为Cygwin的行为有所不同,因为它希望您使用它的unix ish目录结构)来识别绝对的Windows路径,但它不处理引用。只要您的
OBJ_DIR
不包含空格,请使用

ROOT_DIR = C:\Users\Charlie\
应该使Windows路径识别生效

然而,在手工制作的Makefiles中看到绝对路径是相当罕见的。你确定要这样做吗?一种更常见的方法是使用相对路径,以便在源代码复制到其他目录时不必更改Makefile。假设Makefile位于根目录中,则

ROOT_DIR = .
或者干脆将
ROOT\u DIR
变量全部禁用,然后说

MOD_DIR = mod
OBJ_DIR = obj
哦,为了回答下一个突然出现的问题:为了使
make
使用

$(OBJ_DIR)/%.o: %.f90
规则,您需要使
$(目标)
具有与
$(OBJ_DIR)/%模式匹配的先决条件。那可能是

OBJS_F = $(patsubst %.f90,$(OBJ_DIR)/%.o,$(notdir $(SRCS_F)))

我认为以下样式的makefile解决了这些问题。我用样本C测试了它 项目,而不是fortran,但这对
生成问题和解决方案无关紧要

# VPATH: Tell `make` to look for in `user` for prerequisites it can't find here
VPATH = user
# If e.g. you also want `make` to look for for prerequisites in `../include`, then:
# VPATH = user:../include
FC      = gfortran
TOP_DIR = .
MOD_DIR = $(TOP_DIR)\\mod
OBJ_DIR = $(TOP_DIR)\\obj

FCFLAGS = -g
FCFLAGS += -J$(MOD_DIR) -fopenmp -fimplicit-none -Wuninitialized

TARGET = parametricStudy

SRCS_F =\
    user\\constants.f90 \
    ...
    parametricStudy.f90

OBJS_T1 = $(patsubst %.f90,%.o,$(SRCS_F))
OBJS_T2 = $(notdir $(OBJS_T1))
# The object files are all to be obj\<name>.o
OBJS_F = $(patsubst %.o,$(OBJ_DIR)\\%.o,$(OBJS_T2))

all: $(TARGET)

$(TARGET): $(OBJS_F)
    $(FC) -o $@ $(FCFLAGS) $(OBJS_F)

# How to make an obj\*.o from the matching *.f90. `make` considers the VPATH
$(OBJ_DIR)\\%.o: %.f90
    $(FC) $(FCFLAGS) -c -o $@ $<
clean:
    del $(OBJ_DIR)\\*.o $(MOD_DIR)\\*.mod parametricStudy.exe
若要启动,您必须使
make
显示任何先决条件
*.f90
就在这里,按照模式, 不在其他目录中,例如
user\constants.f90
这就是
VPATH
实现

后续开发继续进行

我还没有看到makefile所在目录的列表 我只能冒险提出一个假设,但我所看到的假设是:

该目录实际上不包含名为
parametricStudy.f90
的文件, 但是一个名为
parametricStudy.F90
的文件,如果它被重命名为
parametricStudy.F90
, 然后makefile将找到并编译它

是这样吗

这是如何解释事实的:模式规则:

$(OBJ_DIR)\\%.o: %.f90
$(OBJ_DIR)\\%.o: %.f90
未能匹配任何
参数研究.f90
,因此没有此类文件。然而,你说:

gfortran -g -J.\\mod -fopenmp -c -o .\\obj\parametricStudy.o parametricStudy.f90
成功编译

您是在Windows上构建的,因此工具链订阅Windows的文件处理协议。 文件名不区分大小写:
parametricStudy.f90
将标识
parametricStudy.f90
,如果它存在, 而
.F90
将被
gfortran
(在Windows或其他任何地方)解释为表示 Fortran 90源文件。因此,成功的命令行编译

但是模式规则与文件处理协议无关。这只是一种模式
匹配规则,不变量
.f90
.f90

不匹配。您使用的是Cygwin或MinGW的GNU make吗?我想我实际使用的是MinGW。我使用gmake或mingw32 makefe运行makefe您是否仍然没有制定
参数研究的规则?如果是这样,请在包含makefile的目录中运行
dir
,并发布输出。是的,我是。前几天我更新了这个问题。它应该是最新的。今天下午1:30我会再次检查。当我尝试你的建议时,我得到错误“gmake:**No rule to make target
obj/constants.o”,这是参数研究所需要的。停止。“我想我不明白的是你说的$(target)具有与$(obj_DIR)%匹配的先决条件。o模式。”。。这是否意味着主程序需要位于.o目录中?。主程序位于何处并不重要,但其先决条件必须与规则的模式相匹配,该规则知道如何创建它们。嗯……我想我明白问题所在了。如果使用
(OBJ_DIR)/%.o:%.f90
,则
.f90
文件必须直接位于工作目录中,情况并非如此。而且很难重建特定的
%.o
所依赖的
%.f90
。但是,您的原始makefile也不能这样做,因此您至少应该能够使用
$(OBJ_DIR)/%.o:$(SRCS_F)
重现旧的行为(即当一个.f90更改时,所有内容都会重新编译)。。我希望在对.f90文件进行更改时,只编译需要编译的文件。。我可能会用一个不同的、更合适的标题重新发布这个问题,并检查我尝试过的每种形式的make文件的错误和问题。这是如此接近于完全工作!除最后一个文件(parametricStudy.f90)外,所有文件都编译为.object文件。如果最后一个.f90文件位于一个绝对路径中,那就太好了(我想把代码和模拟结果分开)。有没有办法让VPATH包含根目录?(我试过了,但没用)。是的
$(OBJ_DIR)\\%.o: %.f90
gfortran -g -J.\\mod -fopenmp -c -o .\\obj\parametricStudy.o parametricStudy.f90