Question Variables dans GNU Faire des recettes, est-ce possible?


Est-il possible d'avoir des variables dans les recettes GNU Make?

Quelque chose comme ça ne fonctionne pas:

%_t.mkd : %.mkd
    REV=$$(svn info $<|grep 'Last Changed Rev'|cut -f4 -d\ )
    echo $${REV}

Y a-t-il un moyen de faire ce travail du tout?

Comme vous pouvez voir ce que je veux, c'est d'extraire la révision de la modification d'un fichier, puis de l'utiliser plus tard dans la recette complète. Malheureusement je ne peux pas utiliser svn:keywords comme j'ai besoin du numéro de révision en dehors du document en question.


4
2017-07-31 06:49


origine




Réponses:


Cela ne fonctionne pas parce que le make Cet outil lance un nouveau processus shell pour chaque ligne de recette. Et les variables shell - même les variables d'environnement «exportées» - ne peuvent pas se propager «vers le haut»; ils sont partis dès la sortie du processus shell.

  • La méthode traditionnelle consiste à joindre les lignes de recette en utilisant \ dans le Makefile:

    foo: bar baz
        line1; \
        line2; \
        line3
    

    (Notez que les commandes doivent être séparées en utilisant ; ou &&, car les barres obliques inverses sont également transmises au shell qui effectue la même jonction de ligne.)

    Voir également info make "Splitting Lines" et info make "Splitting Recipe Lines" dans le manuel GNU Make.

  • L'autre méthode consiste à dire make pour toujours utiliser un processus shell pour la recette entière, en utilisant le .ONESHELL directif:

    .ONESHELL:
    
    foo: bar baz
        line1
        line2
        line3
    

    Voir info make "One Shell".

    (Notez que tout en .ONESHELL est recommandé par POSIX, tous ne font pas supporter les versions; par exemple. BSD make n'a qu'un indicateur de ligne de commande pour cela. Cela ne devrait pas être un problème cependant.)


6
2017-07-31 07:56





Grâce à https://stackoverflow.com/questions/6519234/cant-assign-variable-inside-recipe

Ceci est la solution pour changer une variable dans une recette:

recipe: 
        $(eval variablename=whatever)

3
2017-10-11 19:54





Selon Gnu Make 6.5 Variables de réglage:

L'opérateur d'affectation de shell != peut être utilisé pour exécuter un programme   et définir une variable à sa sortie. Cet opérateur évalue d'abord le   à droite, passe ce résultat au shell pour exécution.   Si le résultat de l'exécution se termine par une nouvelle ligne, cette nouvelle ligne est   enlevé; toutes les autres nouvelles lignes sont remplacées par des espaces. La résultante   string est ensuite placé dans la variable nommée récursivement étendue.

Donc, vous pouvez essayer ce qui suit (non testé):

REV != $$(svn info $<|grep 'Last Changed Rev'|cut -f4 -d\ ) \
echo $${REV}

1
2017-07-31 07:56



Cela fonctionnerait au niveau supérieur d'un fichier makefile, mais pas au milieu d'une recette (où la syntaxe du shell est utilisée, pas la syntaxe Make). Ce serait REV != svn info ... aussi. - grawity
Peut-être que l'op peut définir la variable une fois au plus haut niveau de son makefile alors? : / - DavidPostill♦
Non, comme vous le voyez, j'en ai besoin dans le cadre de la recette, car la valeur sera différente pour différents fichiers. - Magnus


en prenant ce que @ user3645902 a mentionné, voici la solution à la question principale:

recipe:
    @$(eval REV=`svn info $<|grep 'Last Changed Rev'|cut -f4 -d`)
    @echo $(REV)

0
2018-01-15 15:15