Domanda

Ho un Makefile che inizia eseguendo uno strumento prima di applicare le regole di compilazione (che questo strumento scrive per me). Se questo strumento, che è uno script Python, esce con un codice di stato non nullo, voglio che GNU Make si fermi proprio lì e non continui con la costruzione del programma.

Attualmente, faccio qualcosa del genere (livello superiore, ovvero colonna 1):

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

Ma questo non si ferma se collect_sources.py esce con un codice di stato di 1. Questo cattura anche l'output standard di <=> ma non lo stampa, quindi ho la sensazione che sto guardando nel modo sbagliato direzione.

Se possibile, la soluzione dovrebbe funzionare anche quando una semplice shell MS-DOS è la shell di sistema standard.

Qualche suggerimento?

È stato utile?

Soluzione 2

Ok, ecco la mia soluzione, che purtroppo non si basa sul codice di stato dello script collect_sources.py, ma che funziona per me (TM) e mi consente di vedere qualsiasi output prodotto dallo script:

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

Lo script è scritto in modo tale che qualsiasi errore produca un output che inizia con "collect_sources: error:". Inoltre, se python non riesce a trovare o eseguire lo script specificato, genera un messaggio di errore contenente il messaggio "[Errno 2]" o simile. Quindi questo piccolo pezzo di codice cattura l'output (reindirizzando stderr a stdout) e cerca i messaggi di errore. Se non ne viene trovato nessuno, utilizza semplicemente $(info) per stampare l'output, altrimenti utilizza $(error), il che rende efficacemente Stop.

Nota che il rientro in ifeq ... endif viene eseguito con spazi. Se vengono utilizzate le schede, fai in modo di pensare che stai tentando di invocare un comando e ti lamenti.

Altri suggerimenti

Potrebbe esserci un modo migliore, ma ho provato quanto segue e funziona:

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

Qui ho supposto che your_command non fornisse alcun output, ma non dovrebbe essere difficile aggirare una situazione del genere.

Modifica: per farlo funzionare con la shell di Windows predefinita (e probabilmente con qualsiasi shell decente) puoi scrivere your_command && echo ok invece di if all'interno della funzione shell. Non penso che ciò sia possibile per le shell DOS (più vecchie). Per questi probabilmente vuoi adattare <=> o scrivere uno script wrapper per stampare qualcosa in errore (o successo).

Dovresti usare un target regolare per creare BuildRules.mk:

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

include BuildRules.mk

Questo è il trucco standard da usare quando si generano automaticamente dipendenze.

Correzione https://stackoverflow.com/a/226974/192373

.PHONY: BuildRules.mk

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

Assicurati di non invocare make / gmake con l'opzione -k.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top