我是 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.f08
和 main.f08
,其中 main
使用 module_1
。我正在使用以下命令尝试自动检测 main
的依赖项:
gfortran -cpp -M main.f08
如果 module_1
已经编译,上面的命令会按预期返回依赖项列表,但如果 module_1
还没有编译,我会收到一条错误消息说 module_1.mod
不存在。
我看到的方式是,每次将新模块添加到代码中时,都必须在运行 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.d
和 mod1.d
,其中包含相应源文件的依赖项。
这里的一个(小?)问题是,包含源文件列表的 SRCS 变量必须按顺序列出,以便在您拥有任何 .d 文件之前从左到右编译文件。因此,此处完成的依赖性内容无助于在生成 .d 文件之前订购构建。 (因此我建议将 .d 文件作为源包的一部分分发。)
关于makefile - 自动依赖检测在 GFortran 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57866481/