2017-01-21 75 views
0

通過這個Makefile,我不確定爲什麼會拋出丟失的分隔符錯誤。從makefile中缺少單獨的錯誤

define foo 
$(eval a := $(1)) 
$(eval b := $(1)) 
endef 

$(call foo,hello) 

$(info $(a)) 
$(info $(b)) 

all: ; 

如果我然而替換這第一EVAL,

$(eval a := $(1)) \ 

然後錯誤消失。 eval擴展爲無,並且在define內只有一個eval很滿意。但我不確定爲什麼它在這種情況下抱怨,也不知道爲什麼後面的反斜槓解決了它。

回答

1
define foo 
$(eval a := $(1)) 
$(eval b := $(1)) 
endef 

bar:=$(call foo,hello) 

$(info $(a)) 
$(info $(b)) 
$(info bar=[$(bar)]) 

all: ; 

運行此生成的文件輸出:

$ make -f Makefile.sample 
hello 
hello 
bar=[ 
] 
make: 'all' is up to date. 

所以$(富)功能輸出新行字符。它應該不輸出任何內容,或者應該在變量中捕獲值或者用$(eval)或$(strip)捕獲值。

$(eval a := $(1)) \導致$(foo)沒有新的行輸出,這就是它解決問題的原因。

替代添加反斜槓到$(FOO)爲:

#1:

define fooBody 
$(eval a := $(1)) 
$(eval b := $(1)) 
endef 
foo = $(strip $(call fooBody,$1,$2)) 

#2

define fooBody 
$(eval a := $(1)) 
$(eval b := $(1)) 
endef 
foo = $(eval $(call fooBody,$1,$2)) 

#3

$(strip $(call foo,hello)) 

#4

$(eval $(call foo,hello)) 

#5

.:=$(call foo,hello) 

我個人的選擇是#1。

+0

如果分配的結果給一個變量你不需要帶或EVAL;對於包含換行符的變量來說很好(確實,'fooBody'已經做過......) – MadScientist

+0

strip和eval用於當函數調用的結果未分配給變量的情況。 –

+0

哦,我明白你的意思了,這個取代了foo而不是foo的調用。嗯。就我個人而言,我不喜歡這樣:它很混亂。我知道它允許你使用'foo'。就我個人而言,我並不是把這種變量加入eval這個全部成語的粉絲;通常的做法是將分配放在'foo'中,然後評估調用的結果。但也許在真正的makefile中它更有意義。 – MadScientist

1

call擴張導致單個換行(因爲,如你所說,無論是eval的擴展爲空字符串。當make試圖解析,它不理解它,並拋出這個錯誤。

需要了解的重要一點是make會在之前將輸入分解爲邏輯行,所以在擴展完成後,希望看到一行輸出,並且它不能理解現有的換行符在那個單行中。

也許這可以更好地處理,如果你想在012提交一個bug

ETA其實我查了一下,這已經被固定在GNU使4.2:

$ make-4.1 
Makefile:5: *** missing separator. Stop. 

$ make-4.2 
make: *** No targets. Stop.