Makefile 自动依赖项检测在GFortran中不起作用

Makefile 自动依赖项检测在GFortran中不起作用,makefile,fortran,dependencies,gnu-make,gfortran,Makefile,Fortran,Dependencies,Gnu Make,Gfortran,我声明,自版本4.6以来,已提供对依赖项自动检测的支持: 支持通过GCC的-M..标志生成Makefile依赖项;您可能需要另外指定-cpp选项。依赖项考虑了模块、Fortran的include和CPP的#include。注意:不再支持将-M用于模块路径,请改用-J 在我的程序中,我有两个Fortran文件:module_1.f08和main.f08,其中main使用module_1。我正在使用以下命令尝试自动检测main的依赖项: gfortran-cpp-M main.f08 如果已经编译了

我声明,自版本4.6以来,已提供对依赖项自动检测的支持:

支持通过GCC的
-M..
标志生成Makefile依赖项;您可能需要另外指定-cpp选项。依赖项考虑了模块、Fortran的include和CPP的#include。注意:不再支持将-M用于模块路径,请改用-J

在我的程序中,我有两个Fortran文件:
module_1.f08
main.f08
,其中
main
使用
module_1
。我正在使用以下命令尝试自动检测
main
的依赖项:

gfortran-cpp-M main.f08

如果已经编译了
module_1
,则上面的命令会按预期返回一个依赖项列表,但是如果
module_1
尚未编译,我会收到一条错误消息,而不是说
module_1.mod
不存在

我看到的是,每次向代码中添加新模块时,都必须在运行
makeall
之前对其进行单独编译(或者我们可以在任何其他文件中使用模块之前运行
makeall
,然后使用该模块并再次编译)或者,它的任何依赖项都可能在模块本身之前编译,并将返回编译错误

另一件事是,依赖文件必须随着项目的发展而逐步创建,如果
.mod
文件和依赖文件在某个时候被删除(例如使用
make clean
命令),将无法使用自动检测功能一次生成所有依赖文件


有没有办法绕过这些限制?即使
.mod
文件还不存在,是否有一种自动检测方法可以工作?

首先,您需要向Makefile中添加代码片段,以实际使用依赖项生成功能。此外,您可以使用
-MD
选项为每个目标自动生成依赖项文件,因此不需要特殊目标来重新生成依赖项。对于您上面的示例项目,其
main.f90
使用
mod1.f90
中定义的模块,使用依赖项的简单
Makefile
可能如下所示:

FC := gfortran
FFLAGS := -O2 -g
LIBS := # Needed libs like -lopenblas
SRCS := mod1.f90 main.f90
OBJS := ${SRCS:f90=o}
DEPS := ${OBJS:o=d}

myprog: $(OBJS)
    $(FC) $(FFLAGS) -o $@ $^ $(LIBS)

.PHONY: clean
clean:
    -rm -f $(OBJS) *.mod

-include $(DEPS)

%.o: %.f90 
    $(FC) $(FFLAGS) -cpp -MD -c -o $@ $<
FC:=gfortran
FFLAGS:=-O2-g
LIBS:=#需要像-lopenblas这样的LIBS
SRCS:=mod1.f90 main.f90
OBJS:=${SRCS:f90=o}
DEPS:=${OBJS:o=d}
myprog:$(OBJS)
$(FC)$(FFLAGS)-o$@$^$(LIBS)
.假冒:干净
清洁:
-rm-f$(OBJS)*.mod
-包括美元(DEPS)
%.o:%.f90
$(FC)$(FFLAGS)-cpp-MD-c-o$@$<
当您运行make时,您会看到它生成了包含相应源文件依赖项的文件
main.d
mod1.d


这里的一个(次要?)问题是,包含源文件列表的SRCS变量必须按顺序列出,以便在拥有任何.d文件之前从左到右编译这些文件。因此,在生成.d文件之前,这里所做的依赖项工作无助于对构建进行排序。(因此,我建议将.d文件作为源代码包的一部分分发。)

@jbdv:感谢您的关注。的确
$