自动依赖项检测在GFortran中不起作用 [英] Automatic dependency detection not working in GFortran

查看:120
本文介绍了自动依赖项检测在GFortran中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

GCC Wiki 中,它表示支持对依赖项的自动检测从4.6版开始可用:

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

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

gfortran -cpp -M main.f08

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

我看到的方式是,每次将新模块添加到代码中时,都必须在运行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文件作为源程序包的一部分进行分发.)

I the GCC Wiki it is stated that support for auto-detection of dependencies has been available since version 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.

In my program I have two Fortran files: module_1.f08 and main.f08, where main uses module_1. I am using the following command to try to auto-detect dependencies of main:

gfortran -cpp -M main.f08

If module_1 has been already compiled, the command above returns a list of dependencies as expected, though if module_1 has not been compiled yet, I get an error message instead saying that module_1.mod does not exist.

The way I'm seeing this is that every time a new module is added to the code, it has to be compiled separately before running make all (or we might run make all before using the module in any other file, then use the module and compile again) or else any dependency of it might be compiled before the module itself and a compilation error will be returned.

Another thing is that dependency files have to be created gradually and one-by-one as the project grows, and if .mod files and dependency files got deleted at some point (with a make clean command for example), there will be no way to generate dependency files all at once using the auto-detection feature.

Is there a way to get around these limitations? Is there a way for auto-detection to work even if .mod files do not exist yet?

解决方案

To start with, you need to add snippets to your Makefile to actually use the dependency generation feature. Additionally, you can use the -MD option to generate dependency files automatically for each target, so you don't need a special target to regenerate your dependencies. For an example project like yours above with a main.f90 that uses a module defined in mod1.f90 a simple Makefile using dependencies could look like:

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 $@ $<

When you run make you'll see that it generates files main.d and mod1.d containing the dependencies for the corresponding source file.

A (minor?) problem here is that your SRCS variable containing your list of source files must be listed in an order that allows the files to be compiled from left to right before you have any .d files. So the dependency stuff as it's done here doesn't help with ordering a build before the .d files have been generated. (Thus I'd recommend distributing the .d files as part of the source package.)

这篇关于自动依赖项检测在GFortran中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆