2010-08-13 83 views
39

最近在工作中,我一直在做Makefiles的一些翻譯到一個替代構建系統。我已經看到一些漂亮的毛髮在某些地方使用功能性地圖,過濾器和foreach結構編寫代碼。這讓我感到驚訝,因爲我認爲構建腳本應該儘可能地聲明。Makefile文件是否完整?

無論如何,這讓我想到:是Makefile語言(比如最新的GNU make是具體的)圖靈完成了嗎?

+1

沒有你的描述,我會問你是否解決了一個打賭:) – 2010-08-13 22:10:01

+0

這是在Unix中,它有毛茸茸的語法,而且它驚人的強大。像這樣的大多數東西都是圖靈完備的。 20年前,當有人向我展示vi宏圖靈機時,我並不感到驚訝。 – 2010-08-16 19:45:57

+3

在製作琴絃的過程中,您可以掏出任何你喜歡的東西,包括圖靈機。技術上你已經失去了這一點。 (我們的Makefiles中有Perl調用)。 – 2011-10-30 03:37:42

回答

40

是的,請參閱this。一旦你有lambda,它就會從那裏下坡。

這裏是一個plagiarized斐波納契例如

這應該足以建立更一般的基礎(我得回去工作,或者我會發揮更多功能。)

dec = $(patsubst .%,%,$1) 

not = $(if $1,,.) 

lteq = $(if $1,$(if $(findstring $1,$2),.,),.) 
gteq = $(if $2,$(if $(findstring $2,$1),.,),.) 
eq = $(and $(call lteq,$1,$2),$(call gteq,$1,$2)) 
lt = $(and $(call lteq,$1,$2),$(call not,$(call gteq,$1,$2))) 

add = $1$2 
sub = $(if $(call not,$2),$1,$(call sub,$(call dec,$1),$(call dec,$2))) 
mul = $(if $(call not,$2),$2,$(call add,$1,$(call mul,$1,$(call dec,$2)))) 
fibo = $(if $(call lt,$1,..),$1,$(call add,$(call fibo,$(call dec,$1)),$(call fibo,$(call sub,$1,..)))) 
fact = $(if $(call lt,$1,..),.,$(call mul,$1,$(call fact,$(call dec,$1)))) 

numeral = $(words $(subst .,. ,$1)) 

go = $(or $(info $(call numeral,$(call mul,$1,$1)) $(call numeral,$(call fibo,$1)) $(call numeral,$(call fact,$1))),$(call go,.$1)) 

_ := $(call go,) 

這會打印出正方形,斐波納契數字和階乘。數字大小似乎有16位限制。遊民。

+1

一旦你有lambda,那麼我想你可以創建一個Y-combinator,它給你遞歸。正如你所說,從那裏一切下坡。 – 2010-08-13 22:18:21

+9

太棒了。和可怕的。非常可怕。 – 2010-08-13 22:29:05

+0

@Jorg奧列格是一個很棒但很可怕的傢伙。非常可怕。閱讀他擁有的其他東西。 – deinst 2010-08-13 22:33:04

6

現在對於一個否定的答案: GNU做出積極阻止某些機制,以創建遞歸:

1)Recursively expanded variables

不在「遞歸函數」感遞歸:他們不能被定義在自身方面:

Actually make detects the infinite loop and reports an error. 

(我不知道如何讓他們能夠在實踐中是有用的,順便說一句。)

2)Rule chaining

不能是遞歸的,或者:

No single implicit rule can appear more than once in a chain. (...) 
This constraint has the added benefit of preventing any infinite loop 
in the search for an implicit rule chain. 

(我失去了相當多的時間在這同時調試我的Makefile - 除了所有其他的事情,使生成文件很難保持。)

PS對於最近的一個項目,我寫了a patch to GNU make 3.82,它用新的-M選項取消了此限制(請參閱discussion)。這對我來說可以。

+0

這很有趣,但是如果make總能檢測到類似$(eval)的遞歸宏,我會感到非常驚訝。 – 2010-08-17 22:48:18