Comment assigner la sortie d’une commande à une variable Makefile

J’ai besoin d’exécuter certaines règles de make sous condition que le Python installé soit supérieur à une certaine version (disons 2.5).

Je pensais pouvoir faire quelque chose comme exécuter:

python -c 'import sys; print int(sys.version_info >= (2,5))' 

puis en utilisant la sortie (‘1’ si ok, ‘0’ sinon) dans une ifeq .

Dans un script shell bash simple, c’est juste:

 MY_VAR=`python -c 'import sys; print int(sys.version_info >= (2,5))'` 

mais cela ne fonctionne pas dans un Makefile.

Aucune suggestion? Je pourrais utiliser toute autre solution raisonnable pour y parvenir.

Utilisez le shell Make intégré comme dans MY_VAR=$(shell echo whatever)

 me@Zack:~$make MY_VAR IS whatever 

 me@Zack:~$ cat Makefile MY_VAR := $(shell echo whatever) all: @echo MY_VAR IS $(MY_VAR) 

Envelopper la tâche dans un eval fonctionne pour moi.

 # dependency on .PHONY prevents Make from # thinking there's `nothing to be done` set_opts: .PHONY $(eval DOCKER_OPTS = -v $(shell mktemp -d -p /scratch):/output) 

J’écris une réponse pour augmenter la visibilité de la syntaxe réelle qui résout le problème. Malheureusement, ce que quelqu’un pourrait considérer comme sortingvial peut devenir un mal de tête très important pour quelqu’un qui cherche une réponse simple à une question raisonnable.

Mettez le fichier suivant dans le fichier “Makefile”.

 MY_VAR := $(shell python -c 'import sys; print int(sys.version_info >= (2,5))') all: @echo MY_VAR IS $(MY_VAR) 

Le comportement que vous souhaitez voir est le suivant (en supposant que vous avez installé python récent).

 make MY_VAR IS 1 

Si vous copiez et collez le texte ci-dessus dans le Makefile, obtiendrez-vous cela? Probablement pas. Vous aurez probablement une erreur comme ce qui est rapporté ici:

makefile: 4: *** Séparateur manquant. Arrêtez

Pourquoi: Parce que bien que j’aie personnellement utilisé un onglet authentique, Stack Overflow (en essayant d’être utile) convertit mon onglet en plusieurs espaces. Vous, citoyen internet frustré, copiez maintenant ceci, pensant que vous avez maintenant le même texte que moi. La commande make lit maintenant les espaces et trouve que la commande “all” est mal formatée. Donc, copiez le texte ci-dessus, collez-le, puis convertissez les espaces avant “@echo” dans un onglet, et cet exemple devrait, enfin, fonctionner pour vous.

Voici un exemple un peu plus compliqué avec l’assignation de la tuyauterie et des variables dans la recette:

 getpodname: # Getting pod name @eval $$(minikube docker-env) ;\ $(eval PODNAME=$(shell sh -c "kubectl get pods | grep profile-posts-api | grep Running" | awk '{print $$1}')) echo $(PODNAME)