fortrans module feature can become quite clumsy even when routines are moved to submodules. Parent-child-grandchild-etc definitions and routine interfaces can occupy several thousand lines of code.
For code readability I am thinking about moving type definitions and related interface blocks to files accessed via "include". With a small test example I noticed that "make" is not detecting changes in these files since it only checks the host file (that with the include statement) for changes.
Is there any way of telling make to monitor these files as well such that the host files gets recompiled in case an included files has changed??
Usually you add the include file as a dependency in the makefile. make doesn't try reading your sources. I don't understand your comment about modules and submodules, though. Submodules help avoid compilation cascades, though you do need to accurately describe them in the makefile.
Depending on the contents of an INCLUDEd file, the host file, as you call it, may or may not need recompilation. As Steve pointed out, make does not read and interpret source code. Therefore, you cannot put in an implicit rule in the makefile to cover the include files in your project.
You are left with adding explicit rules such as
sub1.o: inc3.inc inc5.inc mod4.mod
mod4.mod: sub4.f mod3.mod
to your makefile. Modifying and maintaining explicit rules in a makefile by hand for a large project can become quite error prone, as you may have already seen.
Utilities such as Wester's makemake, https://www.fortran.com/makemake.perl , can assist.
My comment regarding submodules was just an "intro" that even submodules sometimes aren't a sufficient tool for keeping modules "small", at least if the whole inheritance path must sit in one module.
I am aware that make doesn't read the content.
Thanks for the hint to the additional dependency. Works.
I am aiming for this structure:
Submoudle file (submod.f90):
Submodule(test) rout contains Module Procedure Subs1 write(*,*) "hello" end procedure end Submodule rout
Module file (mod.f90):
Module test Implicit None private include "tt_include.f90" end Module test
included file (tt_include.f90):
Type, public :: tt contains procedure, pass :: s1=> subs1 end type tt interface Module Subroutine subs1(this) class(tt), intent(inout) :: this end Subroutine end interface
source file for make (Moduls.mk):
SRC += mod.f90\ submod.f90
make file itself:
SRC := .SUFFIXES: .SUFFIXES: .f90 include Moduls.mk OBJS = $(subst .f90,.o,$(SRC)) %.o:%.f90 *include.f90 ifort -c $< -o $@ all: $(OBJS) clean: -rm *.mod -rm *.o -rm *.smod
Because of the final application (+1000 files), I cannot write the rules by hand. As this is just a mickey mouse trial, I don't know whether it will eventually work okish.
Maybe mecej4 can answer this better, it appears that if mod.f90 gets edited, that submod.f90 will not be compiled.
Note, submod.f90 contains neither INCLUDE mod.f90, nor #include mod.f90
I do not know if the makemake pearl script addresses submodules properly.
You're going to have to write the rules for each source file. ifort has a -gen-dep option that may be of help here. For submodules, the submodule sources depend on the parent module and the regular sources depend on the parent module, not the submodule(s). That way if you modify the implementation (in the submodule), neither the module nor sources that use the module have to be recompiled. Of course, if you modify the interface (which must be done in the module), then all users of the module get recompiled.
Many coders will find INCLUDE files only make sense when the INCLUDEd code snippet applies to more than one program component, a classic example being the use of a same COMMON block in different subprograms and perhaps the main program also. OP does not appear to have such a need, at least from what is shown in this thread - it's difficult to fathom how the "tt_include.f90" statement will need to be present anywhere besides the module named Test. All the INCLUDE statement statement appears to be achieving is shorten the amount of text in the module; such an aim is better achieved by other means - see below - note though nothing is perfect.
So what OP may want to consider is
Apart from all the comments made so far, if include files are used I suggest that they be given a suffix other than .f or .f90. Doing so will avoid causing make and other utilities attempt to compile or parse those include files as independent Fortran source files, which we know in advance will fail.
Utilities such as makemake.pl were created in the days before submodules were added to Fortran. I do not know if any of them have been updated to know about submodules.
All the INCLUDE statement statement appears to be achieving is shorten the amount of text in the module ......................
improved code design based on better OO and other programming paradigms
I think this forum has seen discussion about the short-commings of oop in fortran several times, and I think the general consensus was that they are there. Also, there are applications, and I think I have once elaborated on one example, where "one type one module" approaches simply do not work which will eventually lead to very large modules. However, without knowing application specifities you are free to believe that everything can be solved via better design ....................... even in oo fortran.
Better code editor(s) that continue to advance further at a rapid frequency (e.g., Microsoft Visual Studio editor on Windows for C# and C++ languages) their existing quality code folding capabilities with good shortcuts and macros, etc. Large files can then be handled more efficiently.
You may have noticed that this is the Linux/Mac forum. There a plenty of ides in linux for c++ and c (e.g. eclipse), but to my knowledge fortran supporting ides are very limited to absent in linux (maybe photran in eclipse) .................. most likely due to the limited use of this language in large projects. Code folding in emacs might be an option, but one would have to fix the plugin first to cope with different programming styles which lead to the same code.