2013-07-22 139 views
1

我在make(3.81)中遇到與隱式規則有關的錯誤。的示例代碼是:使隱式規則第一次失敗,但第二次成功

dongli:test02 dongli$ ls -R 
Makefile a.F90 b.F90 dir 

./dir: 
a.t.F90 

代碼間的依賴關係:

a.t.F90: a.F90 
a.t.o: a.t.F90 
b.o: b.F90 
b: a.t.o b.o 

a.F90是中間代碼,並且當a.F90被更新a.t.F90將被更新。我的make過程是:

試驗1(所有在位置代碼):

------------------------------------------------------------- 
Project: >>> test <<< 
------------------------------------------------------------- 
Creating dependency a.t.o 
------------------------------------------------------------- 
-----> ./dir/a.t.F90 
Creating dependency b.o 
------------------------------------------------------------- 
-----> b.F90 
Creating target 'b' 
---> b is created. 
------------------------------------------------------------- 
Finished 
------------------------------------------------------------- 

試驗2(觸摸a.F90):

dongli:test02 dongli$ touch a.F90 
dongli:test02 dongli$ make 
------------------------------------------------------------- 
Project: >>> test <<< 
------------------------------------------------------------- 
Processing templates in a.F90 
------------------------------------------------------------- 
Creating dependency a.t.o 
------------------------------------------------------------- 
-----> a.t.F90 
gfortran: error: a.t.F90: No such file or directory 
gfortran: fatal error: no input files 
compilation terminated. 
make: *** [a.t.o] Error 1 

試驗3:(運行make):

dongli:test02 dongli$ make 
------------------------------------------------------------- 
Project: >>> test <<< 
------------------------------------------------------------- 
Creating dependency a.t.o 
------------------------------------------------------------- 
-----> ./dir/a.t.F90 
Creating dependency b.o 
------------------------------------------------------------- 
-----> b.F90 
Creating target 'b' 
---> b is created. 
------------------------------------------------------------- 
Finished 
------------------------------------------------------------- 

我知道有在make目錄緩存(見here)的錯誤,但對我來說,dir/a.t.F90始終存在。任何想法?謝謝!

UPDATE1:

我用make -d捕捉測試2以下信息:

 Finished prerequisites of target file `a.t.F90'. 
     Prerequisite `a.F90' is newer than target `a.t.F90'. 
     Must remake target `a.t.F90'. 
    Ignoring VPATH name `./dir/a.t.F90'. 

    ... 

     Successfully remade target file `a.t.F90'. 
Finished prerequisites of target file `a.t.o'. 
Prerequisite `a.t.F90' of target `a.t.o' does not exist. 
Must remake target `a.t.o'. 

爲什麼./dir/a.t.F90是當它的前提條件是a.F90比它更新的忽略?

UPDATE2:

我已經把例子代碼上gist

UPDATE3:

我發現了以下相關信息:

如果目標需要重建,GNU使丟棄的文件名VPATH搜索這一目標過程中發現 ,和使用makefile中給出的文件名在本地建立文件 。如果目標不需要重建 ,則GNU make將使用在VPATH 搜索期間找到的文件名。

+0

我已將此錯誤隔離爲最小集合。如果有人需要他們弄清楚什麼是錯誤的,我可以把它們放在某個地方。 –

+0

謝謝,這正是我正在尋找的。 – schwart

回答

0

我做了一個解決方法,我在隱式規則中插入了一些腳本,添加了缺少的目錄部分代碼,因爲VPATH對此有一些限制。

%.o: %.$(1) 
    @echo " Creating dependency [email protected]" 
    @echo $$(seperator) 
    @TEMPLATE_PATTERN='.*\.t\.$(1)'; \           < 
    if [[ $$$$(dirname $$<) == '.' && '$$<' =~ $$$$TEMPLATE_PATTERN ]]; then \ < 
     SRC=$(PROJECT_ROOT)/.codemate/processed_codes/$$<; \     < 
    else \                  < 
     SRC=$$<; \                < 
    fi; \                  < 
    $(FC) -c $$$$SRC $(OPTIONS) $(FFLAGS) $(INCLUDES) 

標記爲<

1

您確實需要顯示創建這些目標的規則。您已經提供了有關構建的許多方面的大量信息,但調試中最關鍵的方面之一就是看到規則。

像這樣的失敗(第一次構建失敗,第二次失敗)幾乎總是由於規則不符合你所描述的規則。如果你告訴作出這樣的規則建立一個文件「富」,通過創建類似foo : bar,但隨後你寫不實際創建「富」,而是「酒吧/富」,類似的配方:

foo : bar ; cp bar bar/foo 

那就錯了。此類問題的另一個常見原因是您定義了一個構建「foo.x」的規則,但它也構建了「foo.y」,並且您不會告訴它,但稍後使用「foo.y」作爲先決條件,那是行不通的。你必須定義一個規則告訴make這兩個文件是從配方的一次調用產生的,如:

%.x %.y : %.z ; cp $< $*.x && cp $< $*.y 

最後,你提到VPATH上面,它看起來像你正在嘗試使用VPATH找到生成的文件。這是行不通的。 VPATH只能用於用於查找源文件(文件不知道如何構建並期望始終存在)。沒有更多關於你的makefile以及規則是如何構建的,這就是我們所能說的。

編輯補充:

我不知道它是真的有必要用這麼多的評估和來電來訪;通常人們似乎會直接選擇這些非常強大的工具,而簡單的工具就足夠了。無論如何,你遇到的問題與我在上面第一條評論中所懷疑的完全相同。你有這樣的規則:

%.t.F90: %.$(1) 
     @echo " Processing templates in $$^" 
     @echo $$(seperator) 
     @cp $$< dir/[email protected] 

注意最後一行,在那裏,而不是創建您要創建dir/[email protected][email protected];這正是我上面描述的情況。無論什麼時候你有一個規則建立的東西不完全是[email protected],幾乎100%肯定規則是錯誤的。您需要將其編寫爲:

dir/%.t.F90: %.$(1) 
     @echo " Processing templates in $$^" 
     @echo $$(seperator) 
     @cp $$< [email protected] 

並且可能會有更多更改以匹配該目標。

+0

感謝您的幫助!我已將代碼放在要點https://gist.github.com/dongli/6059091上。 –

相關問題