2010-08-13 78 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