【发布时间】:2014-10-24 13:39:50
【问题描述】:
我正在尝试编写一个 Makefile 来编译一个 Fortran90 项目,该项目由多个包含子例程和 模块 的源文件组成。为了让事情变得更复杂,我正在使用 预编译(从 *.F 文件创建 *.for 文件)。我找不到任何答案,但这可能是因为我对不同风格的 Makefile 语法感到困惑。
我创建了一个精简版本来重现我的问题(可在https://github.com/stineb/stackoverflow 上找到)。这包含一个主程序(sayhello.F),两个单独源文件中的子例程(schleppe.F 和schnuppi.F),以及两个单独源文件中的模块(words_schleppe.mod.F 和words_schnuppi.mod.F)。可执行文件是hello。
我可以使用简单的 Makefile 来构建它并避免预编译。这个文件(Makefile_simple)看起来像这样:
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
但是,我的项目会比这个大一些,所以我想利用更复杂的 Makefile 的神秘特性来定义规则。至关重要的是:我想将源文件*.F 预编译成.for。这是我没有设法定义规则以从模块创建.mod 文件并构建整个事物的地方。忽略模块,我确实使用以下 Makefile 运行它(我的 github 存储库上的Makefile_complex):
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
为了在构建中包含模块,我必须添加什么?依赖关系如下:subroutine schleppe module words_schleppe;和subroutine schnuppi module words_schnuppi.
帮忙,有人吗? 非常感谢!
【问题讨论】:
-
如何从模块中制作
.mod文件(那些是.mod.F文件)?这些.mod文件如何在构建过程的其余部分中使用? -
@EtanReisner
.mod文件由编译器在编译包含模块的源文件时自动创建。当它们遇到任何use语句时,它们会被同一个编译器隐式使用。 -
你的意思是编译
schleppe.F会生成schleppe.for,而编译words_schleppe.mod.F会自动使用相同的编译命令生成words_schleppe.mod? -
@EtanReisner,是的,就是这样。
-
那么我想你只想用
MODS复制关于OBJS的部分,并添加一个%.mod: %.F配方和匹配$(MODS): %.o: %.mod配方(如果有必要的话)。
标签: makefile fortran fortran90 precompile pre-compilation