web-dev-qa-db-fra.com

Comment obtenir l'état de sortie d'une commande Shell utilisée dans GNU Makefile?

J'ai une règle de makefile pendant que j'exécute un outil Linux. Je dois vérifier l'état de sortie de la commande d'outil, et si cette commande échoue, la marque doit être abandonnée.

J'ai essayé de vérifier avec $ ?, $$?\$? etc dans le makefile. Mais ils me donnent une erreur de syntaxe lors de l'exécution de makefile.

Quel est le bon moyen de le faire ?

Voici la règle pertinente dans Makefile

    mycommand \
    if [ $$? -ne 0 ]; \
    then \
        echo "mycommand failed"; \
        false; \
    fi
25
Lunar Mushrooms

Dans le makefile-:

mycommand || (echo "mycommand failed $$?"; exit 1)

Chaque ligne de l'action makefile appelle un nouveau shell - l'erreur doit être vérifiée dans la ligne d'action où la commande a échoué.

Si ma commande échoue, la logique se ramifie à l'instruction echo puis se ferme.

43
suspectus

Voici quelques autres approches:


Shell & .SHELLSTATUS

some_recipe:
    @echo $(Shell echo 'doing stuff'; exit 123)
    @echo 'command exited with $(.SHELLSTATUS)'
    @exit $(.SHELLSTATUS)

Production:

$ make some_recipe

doing stuff
command exited with 123      
make: *** [Makefile:4: some_recipe] Error 123

Il a la mise en garde que la sortie de la commande Shell n'est pas diffusée, vous vous retrouvez donc avec un vidage à stdout quand il a terminé.


$?

some_recipe:
    @echo 'doing stuff'; exit 123;\
    EXIT_CODE=$$?;\
    echo "command exited with $$EXIT_CODE";\
    exit $$EXIT_CODE

Production:

$ make some_recipe

doing stuff                  
command exited with 123      
make: *** [Makefile:2: some_recipe] Error 123

Il s'agit essentiellement d'une chaîne de commandes Shell, séparées par des points-virgules. Échapper aux nouvelles lignes que vous voulez est ennuyeux et il est facile d'oublier les points-virgules, mais j'ai choisi cette approche uniquement en raison de la mise en garde mentionnée ci-dessus.

14
c24w

Si tout ce que vous voulez, c'est que make soit abandonné si l'outil se termine avec un état différent de zéro, make le fera déjà par défaut.

Exemple Makefile:

a: b
    @echo making $@
b:
    @echo making $@
    @false
    @echo already failed

. Voici ce qui se passe avec mon make:

$ make
making b
make: *** [Makefile:6: b] Error 1

Assurez-vous que les cibles partiellement ou entièrement créées sont supprimées en cas d'échec. Par exemple, cette

a: b
    @gena $+ > $@
b:
    @genb > $@

est incorrect: si au premier essai, genb échoue, il laissera probablement un b incorrect, qui, au deuxième essai, make supposera qu'il est correct. Vous devez donc faire quelque chose comme

a: b
    @gena $+ > $@ || { rm $@; exit 1; }
b:
    @genb > $@
2
reinierpost