How to create a makefile for a Fortran program using modules

删除回忆录丶 提交于 2019-12-21 06:22:50

问题


The challenge is to create a makefile which takes a list of modules and does not require me to sort out precendence. For example, the modules are

mod allocations.f08     mod precision definitions.f08   mod unit values.f08
mod blocks.f08          mod shared.f08                  mod parameters.f08
mod timers.f08

The main program is characterize.f08. The error message is

Fatal Error: Can't open module file ‘mprecisiondefinitions.mod’ for reading at (1): No such file or directory

The first statement in the main program is use mPrecisionDefinitions, the module defined in mod precision definitions.f08.

The following makefile, based upon Creating a FORTRAN makefile, is:

# compiler
FC := /usr/local/bin/gfortran

# compile flags
FCFLAGS = -g -c -Wall -Wextra -Wconversion -Og -pedantic -fcheck=bounds -fmax-errors=5
# link flags
FLFLAGS =

# source files and objects
SRCS = $(patsubst %.f08, %.o, $(wildcard *.f08))

# program name
PROGRAM = a.out

all: $(PROGRAM)

$(PROGRAM): $(SRCS)
    $(FC) $(FLFLAGS) -o $@ $^

%.mod: %.f08
    $(FC) $(FCFLAGS) -o $@ $<

%.o: %.f08
    $(FC) $(FCFLAGS) -o $@ $<

clean:
    rm -f *.o *.mod

回答1:


For starters, I recommend to replace all spaces in your file names with underscores or something similar.

Spaces are almost universally used as separators, and any program that is started with something like

gfortran -c -o mod precision definitions.o mod precision definitions.f08

would interpret this line as 'create an object file called mod from the source files precision, definitions.o, mod, precision, and definitions.f08. And while there are ways to do it, with increasing automation, you have to jump more and more hoops.

In contrast, this works well:

gfortran -c -o mod_precision_definitions.o mod_precision_definitions.f08

I would use this command to change all the spaces into underscores:

rename 's/ /_/g' *.f08

If that doesn't work, use this command:

for f in *.f08; do mv "$f" ${f// /_}; done

Next, I wouldn't worry about .mod files. They get generated together with the object files when you compile a module. So while technically some routine that uses a module requires the .mod file for that module, you might as well claim in your Makefile that it depends on the object file itself.

So with that said, here's the Makefile I would use (with some suspected inner-module dependencies added):

# Find all source files, create a list of corresponding object files
SRCS=$(wildcard *.f08)
OBJS=$(patsubst %.f08,%.o,$(SRCS))

# Ditto for mods (They will be in both lists)
MODS=$(wildcard mod*.f08)
MOD_OBJS=$(patsubst %.f08,%.o,$(MODS))

# Compiler/Linker settings
FC = gfortran
FLFLAGS = -g
FCFLAGS = -g -c -Wall -Wextra -Wconversion -Og -pedantic -fcheck=bounds -fmax-errors=5
PROGRAM = characterize
PRG_OBJ = $(PROGRAM).o

# make without parameters will make first target found.
default : $(PROGRAM)

# Compiler steps for all objects
$(OBJS) : %.o : %.f08
    $(FC) $(FCFLAGS) -o $@ $<

# Linker
$(PROGRAM) : $(OBJS)
    $(FC) $(FLFLAGS) -o $@ $^

# If something doesn't work right, have a 'make debug' to 
# show what each variable contains.
debug:
    @echo "SRCS = $(SRCS)"
    @echo "OBJS = $(OBJS)"
    @echo "MODS = $(MODS)"
    @echo "MOD_OBJS = $(MOD_OBJS)"
    @echo "PROGRAM = $(PROGRAM)"
    @echo "PRG_OBJ = $(PRG_OBJ)"

clean:
    rm -rf $(OBJS) $(PROGRAM) $(patsubst %.o,%.mod,$(MOD_OBJS))

.PHONY: debug default clean

# Dependencies

# Main program depends on all modules
$(PRG_OBJ) : $(MOD_OBJS)

# Blocks and allocations depends on shared
mod_blocks.o mod_allocations.o : mod_shared.o


来源:https://stackoverflow.com/questions/35234003/how-to-create-a-makefile-for-a-fortran-program-using-modules

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!