最近在工作中,我一直在从Makefile转换到另一种构建系统。我在一些地方看到了一些非常多毛的Make代码,使用了功能映射,过滤器和foreach结构。这让我感到惊讶,因为我认为构建脚本应尽可能具有说明性。
无论如何,这让我想到了:是Makefile语言(说最新的GNU make具体)Turing完成了吗?
答案 0 :(得分:44)
是的,请参阅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 :(得分:9)
现在回答否定: GNU make积极阻止一些机制来创建递归:
1)Recursively expanded variables
在“递归函数”意义上不是递归的:它们不能用它们自己来定义:
Actually make detects the infinite loop and reports an error.
(顺便说一句,我不知道如何允许它们在实践中有用。)
也不能递归:
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时,我失去了很多时间 - 除了使makefile难以维护的所有其他东西。)
P.S。对于我最近编写的a patch to GNU make 3.82 项目,它使用新的 -M 选项删除了此限制(请参阅discussion)。它对我来说很好。