2010-08-19 19 views
12

make語法是換行符分隔的,但$(shell ...)用空格替換換行符。那麼什麼是最醜陋的方式去做

$(EVAL $(shell程序 - 即-發出-的makefile片段))

不工作有人可能會喜歡的方式。

回答

13

這可能會爲你心目中是什麼:

makefile_fragment: 
    program-that-emits-makefile-fragment > [email protected] 

include makefile_fragment 

是否已足夠?如果需要它們,還可以使用其他技巧,比如讓規則爲程序生成的內容添加上下文,或者通過sed將輸出管道輸入到一行中,然後用反斜槓解析。

+3

+10如果可以的話。這是一款優雅且相當便攜的解決方案。 – 2010-08-19 18:53:01

+0

不起作用.. _for me_。我只是在'make:makefile_fragment「是最新的變體上.' – 2015-12-21 17:56:47

+0

alex grey:嘗試[添加對'Makefile'本身的依賴關係](http://make.mad-scientist.net/constructed-include-文件/) - 'makefile_fragment:$(MAKEFILE_LIST)' – rampion 2016-05-28 09:06:39

4

問題已經被報告給GNU使維護者:

http://savannah.gnu.org/bugs/?28230

它是用下面的評論關閉:

菲利普提到,這是意/記錄的行爲。
我推薦使用「include」而不是eval;讓腳本寫出一個文件,然後包含該文件。

ADDED:有一種解決方法!下面是一個示例GNUmakefile(通過選項卡代替8位;是的,有define newline後兩個空行):

define newline 


endef 

$(eval $(subst #,$(newline),$(shell { echo 'war:'; echo '  echo "not love?"'; echo '  echo "Give peace a chance!"'; } | tr '\n' '#'))) 

更一般地,這是$(eval $(subst #,$(newline),$(shell myscript | tr '\n' '#')))

你必須選擇,將不會出現在一個字符腳本的輸出; #似乎是一個很好的候選人。

+0

寫出文件有點難看---必須使用tempfile來防止破壞東西,清理等。 只要發出的行數腳本不包含空格。 $(foreach line,$(shell make-frag-maker),$(eval $(line))) – Bryan 2010-08-19 19:16:46

+0

@colmode:如果你不喜歡包含技巧,這裏有另一個。我不確定我是否喜歡它:它感覺非常冒險,但是另一方面,它是我所期望的。好的一點是它相當透明。有利於包含的一點是它們應該更容易調試。 – Gilles 2010-08-19 20:00:10

+0

個人而言,我更喜歡「包含」方法。可移植性在OP的特定情況下可能無關緊要,但「include」避免使用非可移植構造(如'$(shell)和'$(eval)'),因此,恕我直言,這是更好的解決方案。 – 2010-08-19 20:18:50

0

下面是劫持%替換字符的方法,因此我們不需要依賴不出現在myscript輸出中的字符。

define nl 


enddef 
$(foreach line, $(shell myscript | sed -e 's/%/\\%/' -e 's/$$/%/'), \ 
    $(eval $(patsubst %, $(line), $(nl)))) 
+0

不適用於我,即使在s/enddef/endef /之後:'GNUmakefile:5:***缺少分隔符。 Stop.'(GNU Make 3.81) – Gilles 2010-08-20 17:44:12

+0

好奇。我只是從這篇文章逐字地將其粘貼到makefile中,它適用於我。同樣的版本也是。這個解析錯誤是否可能來自執行eval,即它是myscript輸出中的錯誤? – Bryan 2010-08-20 19:14:25