自动依赖项检测在GFortran中不起作用 [英] Automatic dependency detection not working in GFortran
问题描述
在 GCC Wiki 中,它表示支持对依赖项的自动检测从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
不存在. /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.d
和mod1.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屋!