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

标签 makefile fortran dependencies gnu-make 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 已经编译,上面的命令会按预期返回依赖项列表,但如果 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.dmod1.d,其中包含相应源文件的依赖项。

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

关于makefile - 自动依赖检测在 GFortran 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57866481/

相关文章:

binary - Fortran:硬编码一些依赖于环境变量的代码

python - 此输出中的 conda 依赖冲突在哪里?我看不到他们。 :(

java - gradle到Maven转换,在依赖项的依赖项版本名称中解析通配符 “+”?

compilation - 使 : $LD_RUN_PATH is ignored

string - Fortran 中的可变长度字符串

c++ - g++ -std=c++11,标志没有生效

parameters - 在 Fortran-90 中将参数作为参数传递?

c++ - 标题互相需要

c++ - 模板调用中变量的生成文件评估

c - 在 C 中使用 makefile 标志进行调试