首页 > 代码库 > Generating Fortran 90 dependencies for Automake
Generating Fortran 90 dependencies for Automake
GNU Autotools can not only handle making (compiling and linking), distributing, transplanting source code for different platforms, but can also track file dependencies hence reduce redundant compiling. This property is by default enabled for C/C++ programming and one of the measures taken by Automake to achieve this automatic tracking is implemented by
How to initialize a bootstrap
Use ‘make all‘ to create dependencies while compiling the source code. After this step, ‘make‘ is able to work normally.
If there are auto generated header files, the compiler would complain about header file lost during the above bootstrap step. It is therefore suggested by Automake that these header files should be added to the variable BUILT_SOURCES, which ensures that these files are generated before the real compiling procedure begins.
The generation of these headers files is usually explicitly based on user defined generation or compiling rules.
The above procedures are actually effective for C/C++ because the inter-dependencies between different source files explicitly rely upon user written header files or explicitly user-defined generation rules. For Fortran 90 programming, the concomitant *.mod files play the role of header files in C/C++. Because they are automatically generated concomitantly with corresponding object files containing implementation of modules, there are no explicit user-defined generation rules for these *.mod files. Hence, it is useless to put these *.mod files into the variable BUILT_SOURCES. If no other measures are taken to deal with the *.mod files, Fortran compiler will not be able to proceed normally.
Although a Fortran file referencing a module written in another file, for example a.f90, is dependent on a.mod, we can actually write the dependency as follows without any problem just because *.mod files are generated simultaneously with *.o files, the dependency on *.mod files is equivalent to dependency on corresponding *.o files:
main.o: a.o
Because Automake knows how to compile *.f90 into *.o files, the whole dependency tree can be generated.
In my previous implementation, the dependency relationships for each *.f90 file is written in a respective file with the same base name appending by an extension *.Po and such a file is located in a .deps folder in each directory. The reason to do this is to mimic the Automake’s support for C/C++ dependency tracking. It seems that it really worked in previous tests. However, right now Automake doesn’t include the contents of these *.Po file into the final Makefile. It is so strange!
Because there is no existing solution both simple and effective for detecting Fortran source file dependencies, a Perl script fdepcomp.pl is written by me to perform this task. The generated dependency relationships are written in a file named makedeps in each directory. For the first attempt, these dependencies are generated like this:
main.o: $(top_builddir)/Defs.o $(top_builddir)/PhysConst.o $(top_builddir)/MathFunc.o $(top_builddir)/ReadFile.oMathFunc.o: $(top_builddir)/Defs.oPhysConst.o: $(top_builddir)/MathFunc.oReadFile.o: $(top_builddir)/MathFunc.o
However, compiler still reported error. Initially, I was unaware of the potential problem. After changing the above relationships into the following, the compiling process was normal again:
main.o: Defs.o PhysConst.o MathFunc.o ReadFile.oMathFunc.o: Defs.oPhysConst.o: MathFunc.oReadFile.o: MathFunc.o
The reason for this is: taking an arbitrary file as an example, the dependent file name $(top_builddir)/Defs.o is not equivalent to the target file name Defs.o from the view of Automake. It is obvious to imagine that the following are also valid format describing dependencies:
$(top_builddir)/main.o: $(top_builddir)/Defs.o$(top_builddir)/PhysConst.o$(top_builddir)/MathFunc.o$(top_builddir)/ReadFile.o$(top_builddir)/MathFunc.o: $(top_builddir)/Defs.o$(top_builddir)/PhysConst.o: $(top_builddir)/MathFunc.o$(top_builddir)/ReadFile.o: $(top_builddir)/MathFunc.o