我有一个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的最后一个问题。在我构建程序的第一个目标中,我使用快捷命令仅用于第一个依赖项($&lt;),但我需要使用($ ^)快捷方式包含所有依赖项(即所有* .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
答案 0 :(得分:13)
您使用的是GNU make吗?如果是的话,
$(FC) $(FLFLAGS) -o $@ $<
可能是罪魁祸首。 $<
是第一个先决条件的名称,但您需要所有*.o
个文件。请尝试使用$^
。