makefile - 创建 FORTRAN makefile

标签 makefile fortran

我有一个 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

但是,当我尝试编写该程序时,我收到了大量 undefined reference 错误。我的意思是,第一个编译的 .F 文件中的每个函数和子例程调用都会返回 undefined reference 错误。我认为这是因为 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 文件中收到一堆 undefined reference 错误。编译器似乎在链接阶段单独检查每个 *.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 的最后一个问题。在构建程序的第一个目标中,我仅对第一个依赖项 ($<) 使用快捷方式命令,但我需要使用 ($^) 快捷方式包含所有依赖项(即所有 *.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

最佳答案

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

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

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

关于makefile - 创建 FORTRAN makefile,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5871780/

相关文章:

makefile - make 文件中的 -wl, --start-group 是什么意思?

makefile - 为什么 echo 在 % : foo. o 规则中起作用,但在 % : %. o 中不起作用?

c++ - 在编译期间包含未使用的代码

c++ - 编译简单的 hello world 程序时错误泛滥

compiler-errors - 通用 'dde_solver' 没有特定功能

linux - 如何在我的 Fortran 代码中检索架构类型(Linux 与 Windows)

windows - 如何为 YoloV3 Darknet(适用于 Windows)运行 "make"命令?

matlab - 如何将 MATLAB 变量写入格式如 3.4d3 的文本文件

c++ - 在混合 C/Fortran 代码中捕获浮点异常

c++ - 支持三元 NURBS 的 NURBS 库