Comment obtenir le statut 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 le statut de sortie de la commande de l’outil et si cette commande échoue, make doit être interrompu.

J’ai essayé de vérifier avec $ ?, $$? \ $? etc dans le makefile. Mais ils me donnent une erreur de syntaxe lorsque makefile s’exécute.

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 

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 mycommand échoue, la logique se connecte à l’instruction echo, puis quitte.

Voici quelques autres approches:


shell & .SHELLSTATUS

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

Sortie:

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

Il ne faut pas oublier que la sortie de la commande shell n’est pas diffusée en continu, vous avez donc un vidage sur stdout à la fin.


$?

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

Sortie:

 $ 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. Echapper à de nouvelles lignes que vous voulez est gênant et il est facile d’oublier les points-virgules, mais je suis allé avec cette approche uniquement en raison de l’avertissement mentionné ci-dessus.

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

Exemple de Makefile :

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

. C’est ce qui se passe avec ma make :

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

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

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

est incorrect: si genb échoue au premier essai, il laissera probablement un b incorrect, ce qui, au deuxième essai, supposera que le résultat est correct. Donc, vous devez faire quelque chose comme

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