创建FORTRAN makefile

Bob*_*Bob 16 fortran makefile

我有一个FORTRAN源代码,由许多不同的.F和.h文件组成.我需要从中构建一个可执行文件,但是我遇到了一些问题.我到目前为止生成的makefile(由于我是新手,可能有错误)是:

 # compiler
 FC = /usr/bin/gfortran-4.5

 # compile flags
 FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons
 # link flags
 FLFLAGS = -g -fbacktrace

 # source files and objects
 SRCS = $(patsubst %.F, %.o, $(wildcard *.F)) \
        $(patsubst %.h, %.mod, $(wildcard *.h))

 # program name
 PROGRAM = blah

 all: $(PROGRAM)

 $(PROGRAM): $(SRCS)
    $(FC) $(FCFLAGS) $@ $<

 %.o: %.F
    $(FC) $(FLFLAGS) -o $@ $<

 %.mod: %.h
    $(FC) $(FLFLAGS) -o $@ $<

 clean:
    rm -f *.o *.mod
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试制作程序时,我遇到了大量未定义的引用错误.我的意思是,在第一个编译的.F文件中的每个函数和子例程调用都会返回一个未定义的引用错误.我认为这是因为gfortran试图链接文件而不是仅编译它们然后在最后进行链接,但我认为'-c'选项应该可以防止这种情况.

更新:

正如评论者指出的那样,我混淆了编译和链接标志.此外,您不应该编译*.h文件.这是最新的,更正的makefile:

# compiler
FC = /usr/bin/gfortran-4.4

# compile flags
FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons -fbounds-check -std=legacy
# link flags
FLFLAGS =

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

# program name
PROGRAM = blah

all: $(PROGRAM)

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

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

clean:
    rm -f *.o *.mod
Run Code Online (Sandbox Code Playgroud)

现在,当我运行make时,它将编译代码中的每个*.F文件,但它在链接阶段失败.我在第一个*.F文件中得到了一堆未定义的引用错误.编译器似乎在链接阶段单独遍历每个*.F文件,我不确定是否正确.然后我收到一个错误:

/usr/lib/gcc/x86_64-linux-gnu/4.4.5/libgfortranbegin.a(fmain.o): In function `main':
(.text+0x26): undefined reference to `MAIN__'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)

但是,如果我输入命令:

gfortran -o blah *.o
Run Code Online (Sandbox Code Playgroud)

将构建可执行文件,因此我似乎在链接阶段的makefile中做错了.

更新:2011年5月9日

Sverre指出了我的makefile的最后一个问题.在我构建程序的第一个目标中,我使用快捷命令仅用于第一个依赖项($ <),但我需要使用($ ^)快捷方式包含所有依赖项(即所有*.o文件).最终的工作makefile如下:

# compiler
FC      := /usr/bin/gfortran-4.5

# compile flags
FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons -fbounds-check
# link flags
FLFLAGS =

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

# program name
PROGRAM = vipre

all: $(PROGRAM)

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

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

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

clean:
    rm -f *.o *.mod
Run Code Online (Sandbox Code Playgroud)

sve*_*rre 14

你在使用GNU make吗?如果是这样,

$(FC) $(FLFLAGS) -o $@ $<
Run Code Online (Sandbox Code Playgroud)

可能是罪魁祸首.$<第一个先决条件的名称,但您想要所有*.o文件.请尝试使用$^.

  • 是的,这很完美.我做了改变而且工作正常.最终的工作makefile发布在我原来的问题中.有趣的是,我实际上有一天在办公室里找到了这个代码的makefile.然而,它比我的长20倍,因为它们列出了每个个体的依赖性.很高兴我学到了正确的方法. (2认同)