2016-09-29 25 views
1

我對GNU make有一個非常混亂的問題。我有以下文件:Makefile應用遞歸規則,即使它不應該

a/x.html 
b/Makefile 
b/c/Makefile 

a/x.html的內容是不相關的。是b/Makefile內容如下:

SRC=../a 
all: x.html 

%.html: ${SRC}/%.html 
     rsync $< [email protected] 

b/c/Makefile的內容是一樣的,除了爲SRC定義:

SRC=../../a 

如果我在b/c/運行make如預期的結果:

rsync ../../a/x.html x.html 

x.html從複製而來3210至b/c/

但是,如果我在b/運行make輸出我得到的只是幾行:

make: stat: ../a/../a/.. (repeated many times) ../a/x.html: File name too long 

似乎make正在申請的規則%.html遞歸的,但爲什麼呢?有什麼明顯的我失蹤?

回答

1

要建立一個模式%.html(即在.html結尾的任何目標名稱)相匹配的目標,使應用是否可以建立依賴關係(目標從原來的目標建有../a/預謀)的規則。

  1. 你問建立x.html。這與模式%.html匹配,因此該規則適用:make會看看它是否可以構建../a/x.html
  2. ../a/x.html匹配模式%.html,所以該規則適用:make看看它是否可以構建../a/../a/x.html
  3. ../../a/x.html圖案%.html相匹配,所以該規則適用等

杆字符可以匹配的路徑,其中包括目錄分隔符的任何部分。

您可以通過運行make -r -d-d來顯示調試輸出,-r關閉會導致大量噪聲的內置規則)來查看試圖做什麼。

當您在b/c中時,由於../../a/x.html存在,但../../../../a/x.html不存在,所以在步驟2停止。

解決此問題的一種方法是列出要採取行動的文件。你可以建立從文件列表列表中已經存在../a

$(notdir $(wildcard ${SRC}/*.html)): %.html: ${SRC}/%.html 
     rsync $< [email protected] 

這樣做的缺點是,如果在../a的HTML文件本身由規則b/Makefile建,然後運行在b韓元make」將它們構建在一個原始的源代碼目錄中。這應該不是一個問題:在b以外的地方建立一個makefile文件是不尋常的,它可以在b以外的地方創建。

不存在此缺陷的另一種方法是使用絕對路徑。

%.html: $(abspath ${SRC})/%.html 
     rsync $< [email protected] 
+0

非常感謝!我想我會使用abspath解決方案。 –