2012-03-31 79 views
0

在GNU make中,追加到變量賦值的尾隨註釋阻止後續比較(通過ifeq)正常工作。變量賦值顛覆比較後的尾隨註釋

這裏的Makefile文件...

A = a 
    B = b ## trailing comment 
    C = c 

    RESULT := 

ifeq "$(A)" "a" 
    RESULT += a 
endif 

ifeq "$(B)" "b" 
    RESULT += b 
endif 

ifeq "$(C)" "c" 
    RESULT += c 
endif 

rule: 
    @echo RESULT=\"$(RESULT)\" 
    @echo A=\"$(A)\" 
    @echo B=\"$(B)\" 
    @echo C=\"$(C)\" 

下面是輸出...

$ make 
RESULT=" a c" 
A="a" 
B="b " 
C="c" 

正如你可以從RESULT顯示值看出,ifeq是受的存在在B的轉讓中發表評論。回顯變量B,表明的問題不是評論,而是介入空間

顯而易見的解決方案是明確strip空白像這樣比較之前...

ifeq "$(strip $(B))" "b" 
    RESULT += b 
endif 

然而,這似乎很容易出錯。由於strip操作是不需要的,除非/直到使用註釋,您可以省略strip,並且所有內容最初都可以正常工作 - 因此您可能不會永遠記得添加strip。後來,如果有人在設置變量時添加註釋,則Makefile不再按預期工作。

注意:如this question所示,存在一個密切相關的問題,即使沒有評論,尾隨空格可能會斷開字符串比較。

問:有沒有更多的傻瓜方式來解決這個問題?

+2

只是100%清楚,它不是尾隨的評論是問題。這是評論前的空白。如果你寫了'b = b#尾註釋',所以在註釋字符之前沒有尾部空格,雖然它看起來很醜,但它工作正常。而且,除了不添加尾部空格以外,沒有萬無一失的方法來處理它。大多數體面的編輯器都會有一種檢測並突出顯示尾隨空白的模式,或者甚至在保存時自動將其刪除。使用它。我不會試圖捍衛讓設計師做出的奇怪的決定,只是說很久以前。 – MadScientist 2012-03-31 15:11:12

+0

順便說一下,這裏是一個有趣的線程,OP有完全相同的問題(但要求一個不同的問題):http://old.nabble.com/White-Space-Problems--Again-td22756435.html – nobar 2012-03-31 16:49:22

+0

@ MadScientist:我同意你的建議,使用一個突出尾部空格的編輯器。但僅僅因爲我使用了一個,並不意味着其他人都會這樣做。即使對於不瞭解所有技巧和陷阱的人,我也希望我的Makefiles能夠以合理的方式工作。 – nobar 2012-03-31 21:36:13

回答

5

這不是GNU Make特有的東西;相反,makedefined by POSIX to work this way

string1 = [string2]

命名字符串1定義宏爲具有<equals-sign>後的字符串2,其中字符串2被定義爲所有字符,如果有的話,該值,註釋字符(#)或未轉義的<newline><equals-sign>之前或之後的任何<blank>字符都應被忽略。

這可以被理解爲一個功能,讓您清楚地創建具有尾隨空格變量:

FOO = stuff # this macro has two trailing spaces 
BAR = something else# and this one has none 

雖然可能它通常會更清晰重新組織你使用$(FOO)而不是地方依賴於它具有掩蓋了空白。

可能是處理這個問題的最好方法就是避免它:有一個約定,你不要在變量定義行上放置註釋(除非偶爾會使有意識的空白清晰)。

A = a # list of apples 
B = b # list of bananas 
C = C# list of carrots 

寫:不是寫這個的

# list of apples 
A = a 
# list of bananas 
B = b 
# list of carrots 
C = c 

這往往是在GNU項目的樣式(見例如the bottom of this page),但我不記得這是否記錄任何地方。

順便說一下,檢查空格時,你可能要引用您的變量在echo命令的更多:

rule: 
    @echo 'RESULT="$(RESULT)"' 

在你echo RESULT=\"$(RESULT)\"版本,$(RESULT)不是從殼報價,所以製表符和多個空格都被誤導顯示爲單個空格。

+0

謝謝你的好的見解。我會說,我不喜歡你提出的約定,原因有兩個:1)編輯起來更麻煩,而且更難讀(在我看來)。 2)這是一個非直觀的要求,將會傳遞給所有未來的所有Makefiles用戶。 – nobar 2012-03-31 17:00:19

+0

另外,感謝關​​於報價的說明。我不認爲我會完全理解POSIX shell如何操縱字符串。我猜'make'和'shell'具有古怪字符串管理的共同特點 - 兩種情況都是基於很久以前做出的決定。 – nobar 2012-03-31 17:04:55

0

這裏是我有一些原始的想法:

  • 使它成爲一個政策總是使用stripifeq
    • 不使用strip將是一個罕見的例外,並且需要在一個解釋註釋。
  • 一個Makefile
    • 找到或創造一些其他的工具來做到這一點的裏面不要手動設置配置變量。
    • 也許POSIX shell就足夠了(儘管我認爲shell變量的細微差別可能比make的差異更大)。
    • 我懷疑GNU build system(Autoconf/Automake /等)解決了這個問題,但我的感覺是這對於大多數目的來說是過分的。
  • 使用某種「皮棉」工具來找到這些類型的問題
    • 我不知道有任何這樣的工具的存在。
  • 修改GNU make來解決這個問題。
    • 優選最小化對現有Makefiles的影響。
    • 修改make語言,使默認拖尾空間被剝離
  • 使用更現代化的構建工具,而不是GNU使
+0

使用'strip'不會縮放。此外,ifeq並不是尾隨空格可能成爲問題的唯一情況。 – nobar 2017-08-10 21:49:46

0

醜,但也許更萬無一失。任何在將來編輯它的人可能至少會注意到,你可能故意使它變得醜陋。

A = $(strip a)## 
B = $(strip b)## trailing comment 
C = $(strip c)##