2017-10-18 62 views
0

我正在使用macOS的默認內置版本(如果它有任何區別)。我試圖製作一個makefile來管理單獨目錄中的超小型項目,這些目錄由其中包含makefile的另一個目錄包含。所以,與其寫出關於每個項目的信息 - 這需要永遠 - 我已經遵循模式規則。但是,無論何時在目標依賴關係中存在一個目錄,它都會變得瘋狂,並說「無法完成目標」或「目標是最新的」。例如:模式規則和目錄

%: %.c 
    gcc -o [email protected] $< 

工作得很好。但是,如果我這樣做:

%: %/%.c 
    gcc -o [email protected] $< 

「目標是最新的」,無論我做什麼。我試過讓它.PHONY,並沒有結果。我甚至試着這樣做:

define FUNC 
$1: $1/$1.c 
    gcc -o $1 $1.c 
endef 
%: 
    $(call FUNC,[email protected]) 

再次,沒有什麼變化,即使我讓它再次.PHONY。 (不像.PHONY: %,當然,像.PHONY: a,然後我試着做make a)爲什麼第二個例子沒有工作?有沒有解決方法?

回答

1

首先,請注意,由於Apple非常害怕GPLv3軟件,因此MacOS附帶的GNU make版本非常陳舊。不僅如此,我還看到過他們應用到他們版本的補丁已經破壞了它。我強烈建議您使用Homebrew或MacPorts(或者從源代碼自己構建它)來獲得GNU make的更現代,支持的版本。

但是,這不會幫助你在這裏。首先,每個目標或模式的先決條件只能有一個%。第二個和後續的不會被替換,所以像%/%.c這樣的先決條件是不合法的。

對於第二次嘗試,這沒有任何意義。您不能在配方中定義make規則:配方會傳遞到shell以執行,因此它們是shell語法,而不是makefile語法。

但除此之外,你的規則是根本問題。考慮它會是什麼樣子,如果你寫一個明確的規則:

foo: foo/foo.c 
     gcc -o foo foo/foo.c 

在這裏,我們創建具有相同名稱的可執行foo作爲目錄foo已經存在(大概)。即使你直接從shell運行gcc,它也會因此而失敗,甚至不考慮make。

這就是make說「無事可做」的原因:那個目標foo已經存在(它是一個目錄),並且make找不到規則來更新它(因爲foo/%.c不存在,所以模式規則不會)不適用)。由於它存在並且沒有更新它的規則,所以沒有什麼可以做的。

所以你需要重新考慮你想在這裏完成什麼。