2010-01-07 4 views
132

J'ai besoin d'exécuter certaines règles make conditionnellement, seulement si le Python installé est supérieur à une certaine version (disons 2.5).Comment assigner la sortie d'une commande à une variable Makefile

Je pensais que je pouvais faire quelque chose comme l'exécution:

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

puis en utilisant la sortie ('1' si ok, '0' autre) dans un communiqué ifeq de marque.

Dans un simple script shell bash, il est juste:

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

mais cela ne fonctionne pas dans un Makefile.

Des suggestions? Je pourrais utiliser n'importe quelle autre solution de contournement raisonnable pour y parvenir.

+0

étrange tiques retour autour du travail de commande pour l'exécution d'autres scripts pour moi dans un Makefile. Peut-être quelque chose d'autre. Le shell –

Répondre

216

Utilisez le Marque shell builtin comme dans MY_VAR=$(shell echo whatever)

[email protected]:~$make 
MY_VAR IS whatever 
[email protected]:~$ cat Makefile 
MY_VAR := $(shell echo whatever) 

all: 
    @echo MY_VAR IS $(MY_VAR) 
+22

n'est pas une commande standard Make intégrée. C'est un GNU Make intégré. – Dereckson

+6

http://stackoverflow.com/a/2373111/12916 ajoute une note importante sur l'échappement de '$'. –

+1

Cet exemple simple fonctionne. Il fonctionne également avec le pipeline de commandes shell.Mais il est essentiel que vous utilisiez $$ pour représenter $ dans la commande shell –

16

Envelopper l'affectation dans un eval travaille pour moi.

set_opts: 
    $(eval DOCKER_OPTS = -v $(shell mktemp -d -p /scratch):/output) 
    @true 

Note: Le @true ici empêche Faites de penser qu'il ya nothing to be done.

+5

_ "Note: Le @true ici empêche Make de penser qu'il n'y a rien à faire." _ Um, c'est ce que '.PHONY fait toujours pour ces cibles'. –

+0

Merci! Cela m'aide à contourner "bizarre bash" dans makefile –

1

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

Mettez le code suivant dans le fichier "Makefile". Le comportement que vous aimeriez voir est le suivant (en supposant que python récent soit installé).

make 
MY_VAR IS 1 

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

makefile:4: *** missing separator. Stop

Pourquoi: Parce que même si je personnellement un onglet véritable, débordement de pile (en essayant d'être utile) convertit mon onglet en plusieurs espaces. Vous, citoyen Internet frustré, copiez maintenant cela, en pensant que vous avez maintenant le même texte que j'ai utilisé. 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" en un onglet, et cet exemple devrait enfin, espérons-le, travailler pour vous.

0

est ici un peu plus compliqué par exemple avec la tuyauterie et l'affectation variable à l'intérieur 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) 
Questions connexes