0

我正在尝试编写一个Makefile来编译一个Fortran90项目,该项目由几个包含子例程和模块的源文件组成。为了使事情变得更复杂,我正在使用预编译*.for从文件创建*.F文件)。我找不到任何答案,但这可能是因为我对不同风格的 Makefile 语法感到困惑。

我创建了一个精简版本来重现我的问题(可在https://github.com/stineb/stackoverflow上获得)。这包含一个主程序 ( sayhello.F)、两个单独源文件中的子例程 (schleppe.Fschnuppi.F),以及两个单独源文件中的模块 (words_schleppe.mod.Fwords_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 运行它(Makefile_complex在我的 github 存储库上):

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

帮助,有人吗?非常感谢!

4

1 回答 1

1

我找到了解决方案!简单地说,规则all:必须包含模块源文件,并且这些必须在其他源文件之前。另外,必须添加从模块源文件创建目标文件的规则。工作的 Makefile 如下所示:

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
于 2014-10-25T23:17:03.623 回答