【问题标题】:Creating a FORTRAN makefile创建 FORTRAN 生成文件
【发布时间】:2011-05-03 15:21:01
【问题描述】:

我有一个由许多不同的 .F 和 .h 文件组成的 FORTRAN 源代码。我需要从中构建一个可执行文件,但我遇到了一些问题。到目前为止我制作的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

但是,当我尝试编写程序时,我遇到了许多未定义的引用错误。我的意思是,第一个编译的 .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

现在当我运行 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

但是,如果我输入命令:

gfortran -o blah *.o

可执行文件将被构建,所以看起来我在链接阶段的 makefile 中做错了。

更新:2011 年 5 月 9 日

Sverre 指出了我的 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

【问题讨论】:

  • Make 只是一种自动化您可以手动完成的任务的方法。你能在命令行上编译这段代码,而不用 Make 吗?如果没有,那么摆弄 makefile 将无济于事。
  • 您正在将链接标志应用于编译,反之亦然。
  • 源文件和头文件太多,依赖项太多,我无法手动完成。无人问津,你是对的。我愚蠢地切换了这两个变量。将它们切换回来允许我构建 .f 文件。 gfortran 给了我 .h 文件的错误。似乎认为它们是C文件。但这是另一个问题。感谢您的帮助。
  • 您似乎正在尝试构建您的 *.h 文件,您不应该这样做。如果我没记错的话,%.mod: *.h 下的$&lt; 会挑选出第一个*.h 文件。也许您想以包含模块的*.F 文件为首? (尽管我必须承认我从不担心我的 makefile 中的 *.mods)
  • 另外,我想补充一点,这个问题的最终解决方案可能不适用于 F90、F2003 和 F2008 源文件,因为使用模块会施加依赖关系,然后对象“*.o”文件具有他们自己的依赖关系,他们需要以一种特殊的方式重新排序。在这种一般情况下,解决方案发布在stackoverflow.com/questions/25705273/…

标签: makefile fortran


【解决方案1】:

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

$(FC) $(FLFLAGS) -o $@ $<

可能是罪魁祸首。 $&lt;first 先决条件的名称,但您需要所有 *.o 文件。尝试改用$^

【讨论】:

  • 是的,这是完美的。我做出了改变,它奏效了。最终的工作生成文件发布在我原来的问题中。有趣的是,前几天我实际上在我的办公室里为这段代码找到了一个生成文件。但是,它比我的要长 20 倍,因为它们列出了每个单独的依赖项。很高兴我学会了正确的方法。
  • 通常人们使用$(FFLAGS)而不是$(FLFLAGS)
猜你喜欢
  • 1970-01-01
  • 2018-03-20
  • 2014-12-31
  • 1970-01-01
  • 2015-09-21
  • 2016-05-15
  • 2018-07-02
  • 2016-10-05
相关资源
最近更新 更多