Question

J'ai un Makefile qui commence par exécuter un outil avant d'appliquer les règles de construction (que cet outil écrit pour moi). Si cet outil, qui est un script python, se ferme avec un code d'état non nul, je veux que GNU Make s'arrête là et ne continue pas avec la construction du programme.

Actuellement, je fais quelque chose comme ceci (niveau supérieur, c'est-à-dire colonne 1):

$(info Generating build rules...)
$(shell python collect_sources.py)
include BuildRules.mk

Mais cela ne s'arrête pas si collect_sources.py quitte avec un code d'état de 1. Cela capture également la sortie standard de <=> mais ne l'imprime pas, j'ai donc l'impression que je me trompe direction.

Si possible, la solution devrait même fonctionner lorsqu'un shell MS-DOS simple est le shell système standard.

Des suggestions?

Était-ce utile?

La solution 2

Ok, voici ma propre solution, qui n'est malheureusement pas basée sur le code d'état du script collect_sources.py, mais qui fonctionne pour moi (TM) et me permet de voir tout résultat généré par le script:

SHELL_OUTPUT := $(shell python collect_sources.py 2>&1)
ifeq ($(filter error: [Errno %],$(SHELL_OUTPUT)),)
  $(info $(SHELL_OUTPUT))
else
  $(error $(SHELL_OUTPUT))
endif

Le script est écrit de sorte que toute erreur produise une sortie commençant par "collect_sources: error:". De plus, si python ne peut pas trouver ou exécuter le script donné, il génère un message d'erreur contenant le message "[Errno 2]" ou similaire. Donc, ce petit morceau de code capture simplement la sortie (redirigeant stderr vers stdout) et recherche les messages d'erreur. Si aucun n'est trouvé, il utilise simplement $(info) pour imprimer le résultat, sinon il utilise $(error), ce qui rend effectivement Make stop.

Notez que l'indentation dans ifeq ... endif se fait avec des espaces. Si des onglets sont utilisés, Make pense que vous essayez d’appeler une commande et se plaint.

Autres conseils

Il existe peut-être un meilleur moyen, mais j’ai essayé ce qui suit et cela fonctionne:

$(if $(shell if your_command; then echo ok; fi), , $(error your_command failed))

Ici, j'ai supposé que your_command ne donnait aucun résultat, mais il ne devrait pas être difficile de contourner une telle situation.

Modifier: pour que cela fonctionne avec le shell Windows par défaut (et probablement avec n'importe quel shell décent), vous pouvez écrire your_command && echo ok à la place de if dans la fonction shell. Je ne pense pas que cela soit possible pour les coquilles DOS (plus anciennes). Pour cela, vous voudrez probablement adapter <=> ou écrire un script d'encapsulation pour imprimer quelque chose en cas d'erreur (ou de succès).

Vous devez utiliser une cible standard pour créer BuildRules.mk:

BuildRules.mk: collect_sources.py
        python $< >$@

include BuildRules.mk

Il s'agit de l'astuce standard à utiliser lors de la génération automatique de dépendances.

Correction de https://stackoverflow.com/a/226974/192373

.PHONY: BuildRules.mk

BuildRules.mk: collect_sources.py
        echo Generating build rules...)
        python $< >$@
        $(MAKE) -f BuildRules.mk

Assurez-vous de ne pas appeler make / gmake avec l'option -k.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top