28 votes

Les makefiles Turing sont-ils complets?

Dernièrement au travail, j'ai fait une traduction de Makefiles vers un système de construction alternatif. J'ai vu du code Make assez velu à certains endroits en utilisant une carte fonctionnelle, un filtre et des constructions foreach. Cela m'a surpris car je pense que les scripts de construction doivent être aussi déclaratifs que possible.

Quoi qu'il en soit, cela m'a fait réfléchir: le langage Makefile (disons que la dernière marque GNU est spécifique) est-il complet?

25voto

deinst Points 8706

Oui, voir ce. Une fois que vous avez lambda, il est tout en descente à partir de là.

Ici, c'est un plagiat de Fibonacci exemple

Cela devrait être assez pour construire une fondation pour plus de généralité (je dois retourner au travail, ou je jouerais plus.)

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,)

Cette commande affiche des carrés, des nombres de fibonacci et les factorielles. Il semble y avoir un 16 bits de limite sur le nombre de tailles. La poisse.

5voto

reinierpost Points 4221

Maintenant, pour une réponse négative: GNU make activement blocs de certains mécanismes pour créer une récursivité:

1) de manière Récursive l'extension de variables

ne sont pas récursives dans la "fonction récursive" sens: ils ne peuvent pas être définis en termes d'eux-mêmes:

Actually make detects the infinite loop and reports an error.

(Je ne vois pas comment leur permettant pourraient être utiles dans la pratique, par la manière.)

2) la Règle de chaînage

ne peut pas être récursive, soit:

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.

(J'ai perdu beaucoup de temps sur ce pendant le débogage de mon Makefile - en plus de toutes les autres choses qui rendent les makefiles difficiles à maintenir.)

P. S. pour un projet récent, j'ai écrit un patch pour GNU make 3.82 qui supprime cette limitation avec un nouveau -M option (voir discussion). Il fonctionne très bien pour moi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X