245 votes

Define faire variable au moment de l’exécution de règle

Dans mon GNUmakefile, je voudrais avoir une règle qui utilise un répertoire temporaire. Par exemple:

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

Comme l'écrit, la règle ci-dessus crée le répertoire temporaire au moment où la règle est analysée. Cela signifie que, même moi, je ne fais pas.de goudron de tous les temps, de nombreux répertoires temporaires créées. Je tiens à éviter mon /tmp étant jonché de inutilisés des répertoires temporaires.

Est-il un moyen de provoquer la variable à être définies uniquement lorsque la règle est déclenchée, par opposition à chaque fois qu'il est défini?

Ma principale de la pensée est de faire un dump de la mktemp et de goudron dans un script shell, mais qui semble un peu disgracieux.

377voto

e.James Points 51680

Dans votre exemple, l' TMP variable est définie (et le répertoire temporaire créé) chaque fois que les règles pour l' out.tar sont évaluées. Afin de créer le répertoire seulement lorsqu' out.tar est effectivement tiré, vous avez besoin de déplacer le répertoire de la création vers le bas sur les étapes de:

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

L' eval fonction évalue une chaîne de caractères comme si elle avait été tapé dans le makefile manuellement. Dans ce cas, il définit l' TMP variable à la suite de l' shell appel de fonction.

modifier (en réponse aux commentaires):

Pour créer une variable unique, vous pouvez effectuer les opérations suivantes:

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

Cela permettrait de faire précéder le nom de la cible (.tar, dans ce cas) à la variable, la production d'une variable avec le nom out.tar_TMP. J'espère que c'est suffisant pour prévenir les conflits.

37voto

user3124434 Points 41

Une autre possibilité consiste à utiliser des lignes distinctes pour configurer les variables Make quand une règle est déclenchée.

Par exemple, voici un fichier makefile avec deux règles. Si une règle est déclenchée, elle crée un répertoire temporaire et définit TMP sur le nom du répertoire temporaire.

 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}
 

L'exécution du code produit le résultat attendu:

 $ ls
Makefile
$ make ruleB
echo testruleB_Y4Ow
testruleB_Y4Ow
$ ls
Makefile  testruleB_Y4Ow
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X