2010-01-07 23 views
132

Necesito ejecutar algunas reglas make condicionalmente, solo si el Python instalado es mayor que cierta versión (digamos 2.5).Cómo asignar la salida de un comando a una variable Makefile

pensé que podía hacer algo así como la ejecución de:

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

y luego usando la salida ('1' si bien, '0' de otro tipo) en un comunicado ifeq maquillaje.

En un simple script de shell bash es sólo:

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

pero eso no funciona en un Makefile.

¿Alguna sugerencia? Podría utilizar cualquier otra solución sensata para lograr esto.

+0

extraño volver garrapatas torno a la obra de comandos para ejecutar otros scripts para mí en un Makefile. Podría ser otra cosa. –

Respuesta

216

emplee las marcas shell builtin como en 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

shell no es un comando estándar Hacer comando integrado. Este es un GNU Make incorporado. – Dereckson

+6

http://stackoverflow.com/a/2373111/12916 agrega una nota importante acerca de cómo escapar '$'. –

+1

Este sencillo ejemplo funciona. También funciona con la línea de comandos de shell.Pero es esencial que use $$ para representar $ en el comando de shell –

16

Envolver la asignación en un eval está trabajando para mí.

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

Nota: El @true aquí impide Realizar de pensar que hay nothing to be done.

+5

_ "Nota: @true aquí impide que Make piense que no hay nada que hacer." _ Um, eso es para lo que '.PHONY siempre hacen que estos objetivos' sean para. –

+0

¡Gracias! Esto me ayuda a pasar por alto "bash extraño" en makefile –

1

Estoy escribiendo una respuesta para aumentar la visibilidad de la sintaxis real que resuelve el problema. Desafortunadamente, lo que alguien podría ver como trivial puede convertirse en un dolor de cabeza muy importante para alguien que busca una respuesta simple a una pregunta razonable.

Ponga lo siguiente en el archivo "Makefile".

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

all: 
    @echo MY_VAR IS $(MY_VAR) 

El comportamiento que le gustaría ver es el siguiente (suponiendo que tiene python reciente instalado).

make 
MY_VAR IS 1 

Si copia y pega el texto anterior en el archivo Makefile, ¿lo conseguirá? Probablemente no. Probablemente obtendrá un error como lo que se informa aquí:

makefile:4: *** missing separator. Stop

Por qué: Porque aunque yo personalmente utilizado con una ficha auténtica, desbordamiento de pila (intentar ser útil) convierte mi cuenta en un número de espacios. Usted, ciudadano de Internet frustrado, ahora copie esto, pensando que ahora tiene el mismo texto que yo usé. El comando make, ahora lee los espacios y encuentra que el comando "all" está incorrectamente formateado. Así que copie el texto anterior, péguelo y luego convierta el espacio en blanco antes de "@echo" a una pestaña, y este ejemplo debería, por fin, funcionar para usted.

0

Aquí es un poco más complicado ejemplo, con tuberías y asignación de variables dentro de receta:

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) 
Cuestiones relacionadas