Necesito ejecutar algunas reglas de creación condicionalmente, solo si el Python instalado es mayor que 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 ifeq
declaración 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 razonable para lograr esto.
Respuestas:
Utilice el Make
shell
incorporado como enMY_VAR=$(shell echo whatever)
fuente
$
.Ajustar la tarea en una
eval
está funcionando para mí.fuente
.PHONY always make these targets
está.Aquí hay un ejemplo un poco más complicado con tuberías y asignación de variables dentro de la receta:
fuente
PODNAME
nombre de implementación:$(eval PODNAME=$(shell sh -c "kubectl get pod -l app=sqlproxy -o jsonpath='{.items[0].metadata.name}'"))
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".
El comportamiento que le gustaría ver es el siguiente (suponiendo que haya instalado Python recientemente).
Si copia y pega el texto anterior en el Makefile, ¿obtendrá esto? Probablemente no. Probablemente obtendrá un error como el que se informa aquí:
makefile: 4: *** falta separador. Detener
Por qué: porque aunque utilicé personalmente una pestaña genuina, Stack Overflow (intentando ser útil) convierte mi pestaña en varios espacios. Usted, ciudadano frustrado de Internet, 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á formateado incorrectamente. 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, al final, con suerte, funcionará para usted.
fuente
Cuidado con recetas como esta
Hace dos cosas mal. La primera línea de la receta se ejecuta en una instancia de shell separada de la segunda línea. La variable se pierde mientras tanto. La segunda cosa incorrecta es que
$
no se ha escapado.Ambos problemas se han solucionado y la variable es utilizable. La barra invertida combina ambas líneas para ejecutarse en un único shell, por lo tanto, la configuración de la variable y la lectura de las palabras clave variables funcionan.
Me doy cuenta de que la publicación original decía cómo obtener los resultados de un comando de shell en una variable MAKE, y esta respuesta muestra cómo obtenerlo en una variable de shell. Pero otros lectores pueden beneficiarse.
Una mejora final, si el consumidor espera que se establezca una "variable de entorno", entonces debe exportarla.
necesitaría esto en el archivo MAKE
Espero que ayude a alguien. En general, uno debe evitar hacer un trabajo real fuera de las recetas, porque si alguien usa el archivo MAKE con la opción '--dry-run', solo para VER lo que hará, no tendrá efectos secundarios indeseables. Cada
$(shell)
llamada se evalúa en tiempo de compilación y se puede realizar accidentalmente un trabajo real. Es mejor dejar el trabajo real, como generar identificadores, en el interior de las recetas cuando sea posible.fuente
Con GNU Make, puede usar
shell
yeval
almacenar, ejecutar y asignar resultados de invocaciones arbitrarias de línea de comandos. La diferencia entre el siguiente ejemplo y los que usan:=
es que la:=
asignación ocurre una vez (cuando se encuentra) y para todos. Las variables expandidas recursivamente establecidas con=
son un poco más "perezosas"; las referencias a otras variables permanecen hasta que se hace referencia a la variable en sí, y la expansión recursiva posterior tiene lugar cada vez que se hace referencia a la variable , lo cual es deseable para hacer "fragmentos consistentes, invocables". Consulte el manual sobre configuración de variables para obtener más información.fuente
$(SET_ID)
vive dentro de unaif
cláusula que es falsa, entonces todavía se llama .En el ejemplo a continuación, he almacenado la ruta de la carpeta Makefile
LOCAL_PKG_DIR
y luego uso laLOCAL_PKG_DIR
variable en los objetivos.Makefile:
Terminal de salida:
fuente