Pregunta

En mi GNUmakefile, me gustaría tener una regla que utiliza un directorio temporal. Por ejemplo:

out.tar: TMP := $(shell mktemp -d)
        echo hi $(TMP)/hi.txt
        tar -C $(TMP) cf $@ .
        rm -rf $(TMP)

Como está escrito, la regla anterior crea el directorio temporal en el momento que la regla es analizada . Esto significa que, aunque no hago out.tar todo el tiempo, muchos directorios temporales se crean. Me gustaría evitar mi / tmp está llena de directorios temporales no utilizados.

¿Hay una manera de hacer que la variable que sólo se define cuando se dispara la regla, en lugar de cada vez que se define?

Mi idea principal es para volcar el mktemp y alquitrán en un script de shell, pero que parece un poco desagradable.

¿Fue útil?

Solución

En el ejemplo, se establece la variable TMP (y el directorio temporal creado) cada vez que se evalúan los reglas para out.tar. Con el fin de crear el directorio sólo cuando out.tar es en realidad despedido, tiene que 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)

El href="http://www.gnu.org/software/make/manual/make.html#Eval-Function" rel="noreferrer"> eval función TMP al resultado de la llamada a la función shell.

editar (en respuesta a los comentarios):

Para crear una variable única, se puede hacer lo siguiente:

out.tar : 
    $(eval $@_TMP := $(shell mktemp -d))
    @echo hi $($@_TMP)/hi.txt
    tar -C $($@_TMP) cf $@ .
    rm -rf $($@_TMP)

Esto anteponer el nombre del destino (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.

Otros consejos

Otra posibilidad es utilizar líneas separadas para establecer Hacer variables cuando se activa una regla.

Por ejemplo, aquí es un makefile con dos reglas. Si se activa una regla, se crea un directorio temporal y establece TMP al nombre de directorio temporal.

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}

Al ejecutar el código produce el resultado esperado:

$ ls
Makefile
$ make ruleB
echo testruleB_Y4Ow
testruleB_Y4Ow
$ ls
Makefile  testruleB_Y4Ow
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top