En mi GNUmakefile, me gustaría tener una regla que use un directorio temporal. Por ejemplo:
out.tar: TMP := $(shell mktemp -d)
echo hi $(TMP)/hi.txt
tar -C $(TMP) cf $@ .
rm -rf $(TMP)
Tal como está escrito, la regla anterior crea el directorio temporal en el momento en que se analiza la regla . Esto significa que, incluso si no lo hago.tar todo el tiempo, se crean muchos directorios temporales. Me gustaría evitar que mi / tmp esté lleno de directorios temporales no utilizados.
¿Hay alguna manera de hacer que la variable solo se defina cuando se activa la regla, en lugar de cuando se define?
Mi pensamiento principal es volcar el mktemp y el alquitrán en un script de shell, pero eso parece algo desagradable.
$(eval $@_TMP := $(shell mktemp -d))
ocurrirá cuando el Makefile se evalúe por primera vez, no en el orden de los procedimientos de la regla. En otras palabras,$(eval ...)
ocurre antes de lo que piensas. Si bien eso podría estar bien para este ejemplo, este método causará problemas para algunas operaciones secuenciales.Una forma relativamente fácil de hacer esto es escribir toda la secuencia como un script de shell.
He consolidado algunos consejos relacionados aquí: https://stackoverflow.com/a/29085684/86967
fuente
@
eeval
y haciendo el mismo trabajo). Tenga en cuenta que en su salida puede ver$TMP
(por ejemplotar -C $TMP ...
), aunque el valor se pasa correctamente al comando.SHELL := /bin/bash
en su archivo MAKE para habilitar funciones específicas de BASH.Otra posibilidad es utilizar líneas separadas para configurar Crear variables cuando se activa una regla.
Por ejemplo, aquí hay un archivo MAKE con dos reglas. Si se activa una regla, crea un directorio temporal y establece TMP con el nombre del directorio temporal.
Ejecutar el código produce el resultado esperado:
fuente
ruleA: TMP = $(shell mktemp -d testruleA_XXXX)
yruleB: TMP = $(shell mktemp -d testruleB_XXXX)
sucederá cuando el Makefile se evalúe por primera vez. En otras palabras,ruleA: TMP = $(shell ...
ocurre antes de lo que piensas. Si bien esto podría funcionar para este caso particular, este método causará problemas para algunas operaciones secuenciales.No me gustan las respuestas de "No", pero ... no.
make
Las variables son globales y se supone que deben evaluarse durante la etapa de "análisis" del archivo MAKE, no durante la etapa de ejecución.En este caso, siempre que la variable local a un solo objetivo, siga la respuesta de @ nobar y conviértala en una variable de shell.
Las variables específicas de destino también se consideran dañinas por otras implementaciones de marca: kati , Mozilla pymake . Debido a ellos, un objetivo se puede construir de manera diferente dependiendo de si se construye de manera independiente o como una dependencia de un objetivo principal con una variable específica del objetivo. Y no sabrá de qué manera fue , porque no sabe lo que ya está construido.
fuente