Comment affecter la sortie d'une commande à une variable Makefile

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

j'ai pensé que je pouvais faire quelque chose comme exécuter:

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

et ensuite en utilisant la sortie ('1' si ok, '0' sinon) dans un ifeq faire la déclaration.

dans un simple script shell bash c'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 raisonnable pour atteindre cet objectif.

147
demandé sur Tshepang 2010-01-07 14:47:10

4 réponses

utiliser la marque shell builtin 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)
242
répondu Arkaitz Jimenez 2018-07-19 01:32:47

envelopper la mission 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)
20
répondu Dave 2018-06-01 08:04:42

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 insignifiant peut devenir un casse-tête très important pour quelqu'un qui cherche une réponse simple à une question raisonnable.

Ajoute ce qui suit 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 aimeriez voir est le suivant (en supposant que vous avez récemment installé python).

make
MY_VAR IS 1

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

makefile:4: *** separator manquant. Arrêt

pourquoi: parce que même si j'ai personnellement utilisé un véritable onglet, Stack Overflow (en essayant d'être utile) convertit mon onglet en un certain nombre d'espaces. Vous, frustré de l'internet citoyen, maintenant copier, en pensant que vous avez maintenant le même texte que j'ai utilisé. La commande make lit maintenant les espaces et constate que la commande "all" est mal formatée. Donc, Copiez le texte ci-dessus, collez-le, puis convertissez l'espace avant "@echo" en un onglet, et cet exemple devrait, enfin, espérons, travailler pour vous.

9
répondu AlanSE 2017-10-23 16:31:43

voici un exemple un peu plus compliqué avec la tuyauterie et l'assignation variable à l'intérieur de 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 $}'))
    echo $(PODNAME)
5
répondu Francesco Casula 2018-01-26 11:17:49