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 é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 si je ne distingue pas tout le temps, de nombreux répertoires temporaires sont créés. Je voudrais éviter que mon / tmp soit jonché de répertoires temporaires inutilisés.
Existe-t-il un moyen de faire en sorte que la variable soit définie uniquement lorsque la règle est déclenchée, par opposition à chaque fois qu'elle est définie?
Ma pensée principale est de vider le mktemp et le tar dans un script shell mais cela semble quelque peu disgracieux.
$(eval $@_TMP := $(shell mktemp -d))
se produira lorsque le Makefile est évalué pour la première fois et non dans l'ordre des procédures de règles. En d'autres termes,$(eval ...)
cela se produit plus tôt que vous ne le pensez. Bien que cela puisse convenir à cet exemple, cette méthode entraînera des problèmes pour certaines opérations séquentielles.Une manière relativement simple de procéder consiste à écrire la séquence entière sous forme de script shell.
J'ai regroupé quelques conseils connexes ici: https://stackoverflow.com/a/29085684/86967
la source
@
eteval
et faire le même travail). Notez que dans votre sortie, vous voyez$TMP
(par exempletar -C $TMP ...
) bien que la valeur soit correctement transmise à la commande.SHELL := /bin/bash
dans votre makefile activer des fonctionnalités spécifiques à BASH.Une autre possibilité consiste à utiliser des lignes distinctes pour configurer les variables Make lorsqu'une règle se déclenche.
Par exemple, voici un makefile avec deux règles. Si une règle se déclenche, elle crée un répertoire temporaire et définit TMP sur le nom du répertoire temporaire.
L'exécution du code produit le résultat attendu:
la source
ruleA: TMP = $(shell mktemp -d testruleA_XXXX)
etruleB: TMP = $(shell mktemp -d testruleB_XXXX)
se produira lors de la première évaluation du Makefile. En d'autres termes,ruleA: TMP = $(shell ...
cela se produit plus tôt que vous ne le pensez. Bien que cela puisse fonctionner dans ce cas particulier, cette méthode entraînera des problèmes pour certaines opérations séquentielles.Je n'aime pas les réponses "Ne pas", mais ... non.
make
Les variables de sont globales et sont censées être évaluées pendant la phase "d'analyse" du makefile, pas pendant la phase d'exécution.Dans ce cas, tant que la variable est locale à une seule cible, suivez la réponse de @ nobar et faites-en une variable shell.
Les variables spécifiques à la cible sont également considérées comme nuisibles par d'autres implémentations de marque: kati , Mozilla pymake . Grâce à eux, une cible peut être construite différemment selon qu'elle est construite de manière autonome ou en tant que dépendance d'une cible parent avec une variable spécifique à la cible. Et vous ne saurez pas de quelle façon c'était , parce que vous ne savez pas ce qui est déjà construit.
la source