创建 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
但是,当我尝试编写程序时,我收到了大量未定义的引用错误。我的意思是,第一个编译的 .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 的最后一个问题。在构建程序的第一个目标中,我仅对第一个依赖项 ($<) 使用快捷方式命令,但我需要使用 ($^) 快捷方式包含所有依赖项(即所有 *.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
I have a FORTRAN source code consisting of many different .F and .h files. I need to build an executable from it, but I'm having some problems. The makefile that I produced so far (which may have errors as I'm new to this) is:
# 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) $@ lt;
%.o: %.F
$(FC) $(FLFLAGS) -o $@ lt;
%.mod: %.h
$(FC) $(FLFLAGS) -o $@ lt;
clean:
rm -f *.o *.mod
When I try to make the program, however, I'm getting a slew of undefined reference errors. I mean, every function and subroutine call in the very first compiled .F file gives back an undefined reference error. I thought this was because gfortran was trying to link the files instead of just compiling them and then linking at the end, but I thought the '-c' option was supposed to prevent that.
UPDATE:
As commenters have pointed out, I mixed up the compile and link flags. Furthermore, you shouldn't compile *.h files. Here is the latest, corrected 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 $@ lt;
%.o: %.F
$(FC) $(FCFLAGS) -o $@ lt;
clean:
rm -f *.o *.mod
Now when I run make, it will compile each *.F file in the code, but it fails at the linking stage. I get a bunch of undefined reference errors in the very first *.F file. The compiler seems to be going over each *.F file individually in the linking stage, which I'm not sure is correct. Then I get an error:
/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
However, if I type the command:
gfortran -o blah *.o
The executable will be built, so it seems like I did something wrong in the makefile for the linking stage.
UPDATE: 5/9/2011
Sverre pointed out the final problem with my makefile. In my first target that builds the program, I use the shortcut command for only the first dependency ($<), but I need to include all dependencies (i.e. all *.o files) using the ($^) shortcut. The final, working makefile is as follows:
# 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 $@ lt;
# %.mod: %.h
# $(FC) $(FCFLAGS) -o $@ lt;
clean:
rm -f *.o *.mod
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你使用的是 GNU make 吗?如果是这样,
罪魁祸首可能就是它。
$<
是第一个先决条件的名称,但您需要所有*.o
文件。尝试使用$^
代替。Are you using GNU make? If so,
may be the culprit.
$<
is the name of the first prerequisite, but you want all the*.o
files. Try using$^
instead.