jerárquico - makefile linux c
Definir la variable make en el tiempo de ejecución de la regla (3)
En su ejemplo, la variable TMP
está configurada (y el directorio temporal creado) cada vez que se evalúan las reglas para out.tar
. Para crear el directorio solo cuando out.tar
realidad está out.tar
, debe mover la creación del directorio hacia abajo en los pasos:
out.tar :
$(eval TMP := $(shell mktemp -d))
@echo hi $(TMP)/hi.txt
tar -C $(TMP) cf $@ .
rm -rf $(TMP)
La función eval evalúa una cadena como si hubiera sido escrita manualmente en el archivo MAKE. En este caso, establece la variable TMP
para el resultado de la llamada de función de shell
.
editar (en respuesta a los comentarios):
Para crear una variable única, puede hacer lo siguiente:
out.tar :
$(eval $@_TMP := $(shell mktemp -d))
@echo hi $($@_TMP)/hi.txt
tar -C $($@_TMP) cf $@ .
rm -rf $($@_TMP)
Esto antepondría el nombre del objetivo (out.tar, en este caso) a la variable, produciendo una variable con el nombre out.tar_TMP
. Con suerte, eso es suficiente para evitar conflictos.
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 yo no distingo .tar todo el tiempo, muchos directorios temporales se crean. Me gustaría evitar que my / tmp esté lleno de directorios temporales no utilizados.
¿Hay alguna manera de hacer que la variable solo se defina cuando se dispara la regla, a diferencia de cuando se define?
Mi idea principal es volcar mktemp y tar en un script de shell, pero eso parece algo antiestético.
Otra posibilidad es usar líneas separadas para configurar las variables Make cuando se dispara una regla.
Por ejemplo, aquí hay un archivo MAKE con dos reglas. Si una regla se activa, crea un directorio de temperatura y establece TMP en el nombre del directorio de la instalación.
PHONY = ruleA ruleB display
all: ruleA
ruleA: TMP = $(shell mktemp -d testruleA_XXXX)
ruleA: display
ruleB: TMP = $(shell mktemp -d testruleB_XXXX)
ruleB: display
display:
echo ${TMP}
Ejecutar el código produce el resultado esperado:
$ ls
Makefile
$ make ruleB
echo testruleB_Y4Ow
testruleB_Y4Ow
$ ls
Makefile testruleB_Y4Ow
Una forma relativamente fácil de hacerlo es escribir la secuencia completa como un script de shell.
out.tar:
set -e ;/
TMP=$$(mktemp -d) ;/
echo hi $$TMP/hi.txt ;/
tar -C $$TMP cf $@ . ;/
rm -rf $$TMP ;/
He consolidado algunos consejos relacionados aquí: https://.com/a/29085684/86967