0

I'm trying to write a Makefile to compile a Fortran90 project that consists of several source files containing subroutines and modules. To make things more complicated, I'm using pre-compilation (creating *.for files from *.F files). I could not find any answer to this, but this may be because I get confused by the different styles of Makefile syntax.

I created a stripped-down version for reproducing my problem (available on https://github.com/stineb/stackoverflow). This contains a main program (sayhello.F), two subroutines in separate source files (schleppe.F and schnuppi.F), and two modules in separate source files (words_schleppe.mod.F and words_schnuppi.mod.F). The executable is hello.

I am able to build it with a simple Makefile and avoiding the pre-compilation. This file (Makefile_simple) looks like this:

FCOM=gfortran
EXE = hello

standard: 
    $(FCOM) -c words_schleppe.mod.F
    $(FCOM) -c words_schnuppi.mod.F
    $(FCOM) -c schleppe.F
    $(FCOM) -c schnuppi.F
    $(FCOM) words_schleppe.mod.o words_schnuppi.mod.o schleppe.o schnuppi.o sayhello.F -o $(EXE)

 .PHONY: clean
 clean:
    rm $(EXE) *.o *.mod

However, my project will be a bit bigger than this so I want to make use of the cryptic features of a more complex Makefile for defining rules. And crucially: I want to pre-compile source files *.F into .for. This is where I haven't managed to define the rules to create the .mod files from the modules and build the whole thing. Disregarding the modules, I do get it running with the following Makefile (Makefile_complex on my github repository):

FCOM=gfortran
CPPFLAGS=-e
COMPFLAGS=
EXE=hello
SOURCES=sayhello.F schleppe.F schnuppi.F 
OBJS=$(SOURCES:.F=.o)

all: $(OBJS)
    # this may also be replaced by the ar command (creating archive)
    $(FCOM) $(OBJS) -o $(EXE)

%.for: %.F
    rm -f $*.for
    $(FCOM) $(CPPFLAGS) $*.F > $*.for

$(OBJS): %.o: %.for
    $(FCOM) -c -o $@ $(COMPFLAGS) $*.for

# clean: remove .for, .o, .do, and .stb files
.PHONY: clean
clean:
    -rm -f *.for *.o *.stb *.mod

What do I have to add to this in order to include the modules in the build? The dependencies are as follows: subroutine schleppe <- module words_schleppe; and subroutine schnuppi <- module words_schnuppi.

Help, anyone? Thanks a bunch!

stineb
  • 461
  • 1
  • 5
  • 11
  • How does one make `.mod` files from the modules (are those the `.mod.F` files)? How are those `.mod` files then used in the rest of the build process? – Etan Reisner Oct 24 '14 at 13:59
  • @EtanReisner the `.mod` files are created by the compiler automatically when compiling the source files which happen to contain a module. They are used implicitly by the same compiler when they encounter any `use` statement. – Vladimir F Героям слава Oct 24 '14 at 16:03
  • Do you mean that compiling `schleppe.F` will generate `schleppe.for` and that compiling `words_schleppe.mod.F` will generate `words_schleppe.mod` automatically using the same compilation command? – Etan Reisner Oct 24 '14 at 16:09
  • @EtanReisner, yes, this is the case. – stineb Oct 24 '14 at 17:00
  • Then I think you just want to duplicate the bit about `OBJS` with `MODS` and add a `%.mod: %.F` recipe and matching `$(MODS): %.o: %.mod` recipe (if that is necessary also). – Etan Reisner Oct 24 '14 at 17:24
  • Simple solution: The rule for `all:` must include the module source files, and these must precede the other source files. Plus, rules of creating the object files from the module source files have to be added. The working Makefile looks like this: – stineb Oct 25 '14 at 20:49
  • @stineb Don't edit your question, post the solution as an answer and accept it ! – Chnossos Oct 25 '14 at 21:12
  • Sorry, first time user ... – stineb Oct 25 '14 at 23:18

1 Answers1

1

I FOUND THE SOLUTION! Simply, the rule for all: must include the module source files, and these must precede the other source files. Plus, rules of creating the object files from the module source files have to be added. The working Makefile looks like this:

FCOM=gfortran

CPPFLAGS=-E
COMPFLAGS=

EXE=hello

SOURCES=sayhello.F schleppe.F schnuppi.F
MODS=words_schleppe.F words_schnuppi.F

OBJS=$(SOURCES:.F=.o)
MODOBJS=$(MODS:.F=.o)

# this may also be replaced by the ar command (creating archive)
all: $(MODOBJS) $(OBJS)
    $(FCOM) $(OBJS) $(MODOBJS) -o $(EXE)

%.for: %.F
    rm -f $*.for
    $(FCOM) $(CPPFLAGS) $*.F > $*.for

$(MODOBJS): %.o: %.for
    $(FCOM) -c -o $@ $(COMPFLAGS) $*.for

$(OBJS): %.o: %.for
    $(FCOM) -c -o $@ $(COMPFLAGS) $*.for

# clean: remove .for, .o, .do, and .stb files
.PHONY: clean
clean:
    -rm -f *.for *.o *.stb *.mod
stineb
  • 461
  • 1
  • 5
  • 11