Cómo asignar la salida de un comando a una variable Makefile


Necesito ejecutar algunas reglas make condicionalmente, solo si el Python instalado es mayor que una cierta versión (digamos 2.5).

Pensé que podría hacer algo como ejecutar:

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

Y luego usando la salida ('1' si está bien, '0' de lo contrario) en una instrucción ifeq make.

En un simple script de shell bash es solo:

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

Pero eso no funciona en un Makefile.

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

Author: Tshepang, 2010-01-07

4 answers

Usa el Make shell incorporado como en 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
Author: Arkaitz Jimenez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-19 01:32:47

Envolver la tarea en un eval está funcionando para mí.

# 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
Author: Dave,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-01 08:04:42

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 significativo 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 tenga instalado python recientemente).

make
MY_VAR IS 1

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

Makefile: 4: * * * falta el separador. Stop

Por qué: Porque aunque personalmente usé una pestaña genuina, Stack Overflow (tratando de ser útil) convierte mi pestaña en un número de espacios. Tú, ciudadano frustrado de Internet, ahora copia esto, pensando que ahora tienes el mismo texto que yo usé. El comando make, ahora lee los espacios y encuentra que el comando" all " está incorrectamente formatear. Así que copie el texto anterior, péguelo y luego convierta el espacio en blanco antes de "@echo" en una pestaña, y este ejemplo debería, por fin, con suerte, funcionar para usted.

 9
Author: AlanSE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-10-23 16:31:43

Aquí hay un ejemplo un poco más complicado con la tubería y la asignación de variables dentro de la 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)
 5
Author: Francesco Casula,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-26 11:17:49