2011-05-03 44 views
12

我有一個FORTRAN源代碼包含許多不同的.F和.h文件。我需要從它構建一個可執行文件,但是我遇到了一些問題。我生產至今(其中可能有錯誤,因爲我是新來的這個)的生成文件是:創建一個FORTRAN生成文件

# 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) [email protected] $< 

%.o: %.F 
    $(FC) $(FLFLAGS) -o [email protected] $< 

%.mod: %.h 
    $(FC) $(FLFLAGS) -o [email protected] $< 

clean: 
    rm -f *.o *.mod 

當我試圖使程序,但是,我得到未定義引用錯誤的轉換。我的意思是,在第一個編譯的.F文件中的每個函數和子程序調用都會返回一個未定義的引用錯誤。我認爲這是因爲gfortran試圖鏈接文件,而不是僅僅編譯它們,然後在最後連接,但我認爲'-c'選項應該阻止這種情況。

UPDATE:

正如評論者所指出的那樣,我是混合了編譯和鏈接標誌。而且,你不應該編譯* .h文件。下面是最新的,糾正生成文件:

# 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 [email protected] $< 

%.o: %.F 
    $(FC) $(FCFLAGS) -o [email protected] $< 

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日

斯維爾指出,最終的問題與我的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 [email protected] $^ 

%.o: %.F 
    $(FC) $(FCFLAGS) -o [email protected] $< 

# %.mod: %.h 
# $(FC) $(FCFLAGS) -o [email protected] $< 

clean: 
    rm -f *.o *.mod 
+0

Make只是一種自動完成手動任務的方法。你可以在命令行上編譯這些代碼嗎?如果沒有,那麼擺弄makefile將無濟於事。 – Beta 2011-05-03 15:24:13

+5

您正在將鏈接標誌應用於編譯,反之亦然。 – 2011-05-03 15:26:33

+0

對於我來說,有太多的源文件和頭文件需要手動完成。 unapersson,你是對的。我愚蠢地改變了這兩個變量。將它們切換回來允許我構建.f文件。雖然gfortran給了我.h文件的錯誤。它似乎認爲他們是C文件。但那是另一個問題。謝謝您的幫助。 – Bob 2011-05-03 15:49:43

回答

11

您使用的是GNU make嗎?如果是這樣,

$(FC) $(FLFLAGS) -o [email protected] $< 

可能是罪魁禍首。 $<第一個的先決條件,但您希望所有*.o文件的名稱。請嘗試使用$^代替。

+2

是的,這是完美的。我做了改變,它工作。最後的工作makefile發佈在我原來的問題中。有趣的是,我有一天在我的辦公室實際追蹤了這個代碼的makefile。但是,它比我的長20倍,因爲它們列出了每個個體的依賴關係。非常高興我學會了正確的方式來做到這一點。 – Bob 2011-05-09 14:28:37

+1

如果一個答案解決了你的問題,你應該標記它 – steabert 2012-01-22 10:17:49

+0

通常人們使用'$(FFLAGS)'而不是'$(FLFLAGS)' – 2016-06-26 10:19:20