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

Automatic dependency detection not working in GFortran

GCC Wiki 据说从 4.6 版开始支持自动检测依赖关系:

Support the generation of Makefile dependencies via the -M... flags of GCC; you may need to specify additionally the -cpp option. The dependencies take modules, Fortran's include, and CPP's #include into account. Note: Using -M for the module path is no longer supported, use -J instead.

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

的依赖项

gfortran -cpp -M main.f08

如果 module_1 已经编译,上面的命令 returns 是预期的依赖项列表,但如果 module_1 还没有编译,我会收到一条错误消息说 module_1.mod 不存在。

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

另一件事是,随着项目的增长,依赖文件必须逐渐逐一创建,如果 .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 $@ $<

当您 运行 make 时,您会看到它生成文件 main.dmod1.d 包含相应源文件的依赖项。

这里的一个(小?)问题是,包含源文件列表的 SRCS 变量必须按顺序列出,以便在您拥有任何 .d 文件之前从左到右编译文件。因此,此处完成的依赖性内容无助于在生成 .d 文件之前订购构建。 (因此我建议将 .d 文件作为源包的一部分分发。)