如何使用模块为Fortran程序创建Makefile [英] How to create a makefile for a Fortran program using modules
问题描述
面临的挑战是创建一个makefile,该makefile可以使用模块列表,而不需要我整理优先级.例如,这些模块是
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
主程序是characterize.f08
.错误消息是
Fatal Error: Can't open module file ‘mprecisiondefinitions.mod’ for reading at (1): No such file or directory
主程序中的第一条语句是use mPrecisionDefinitions
,这是在mod precision definitions.f08
中定义的模块.
The first statement in the main program is use mPrecisionDefinitions
, the module defined in mod precision definitions.f08
.
基于创建FORTRAN生成文件的以下生成文件为:
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
推荐答案
对于初学者,我建议用下划线或类似的内容替换文件名中的所有空格.
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
将此行解释为'从源文件precision
,definitions.o
,mod
,precision
和definitions.f08
创建一个名为mod
的目标文件.尽管有多种方法可以实现,但随着自动化程度的提高,您必须跳出越来越多的麻烦.
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.
相反,这很好用:
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
接下来,我不用担心.mod
文件.在编译模块时,它们与目标文件一起生成.因此,尽管从技术上讲某些使用模块的例程需要该模块的.mod
文件,但您最好在Makefile
中声明它取决于目标文件本身.
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.
因此,这就是我要使用的Makefile(添加了一些假定的模块间依赖项):
So with that said, here's the Makefile I would use (with some assumed inter-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
这篇关于如何使用模块为Fortran程序创建Makefile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!