2011-06-20 14 views
10

Criteri: Makefile è un Make Makefile GNU - Non sono interessato a makepp, qmake, cmake, ecc. Sono tutti carini (specialmente cmake), ma questo è per lavoro e al lavoro usiamo GNU Make. La soluzione ottimale è una pura soluzione Makefile piuttosto che uno script di shell che l'analisi fa per te.GNU Makefile equivalente del comando shell "TRAP" per l'identificazione concisa dell'errore di build all'uscita

Inoltre, non voglio eseguire una soluzione "continua in caso di errore", se è danneggiata, è rotta e deve essere risolta.

La situazione è questa, ho un makefile che costruisce diverse directory in parallelo - se uno di questi fallisce, ovviamente l'intera build fallisce, ma non fino a quando tutta la corsa non è in esecuzione (o fallimento). Ciò significa che la ragione per cui rendere effettivamente fallito è sepolto da qualche parte arbitrariamente lontano dalla fine dell'output di make.

Ecco un esempio di quello che ho:

all: $(SUBDIRS) 

SUBDIRS = \ 
    apple \ 
    orange \ 
    banana \ 
    pineapple \ 
    lemon \ 
    watermelon \ 
    grapefruit 

$(SUBDIRS): 
    cd [email protected] && $(MAKE) $(MFLAGS) 2>&1 | sed -e "s/^/$(notdir $(@)): /g" 

Se corro 'make -j 5' e 'arancione' accade a fallire - Mi piacerebbe vedere una tabella come questa in fine del processo di make

apple  - passed 
    orange - FAILED 
    banana - passed 
    pineapple - passed 
    lemon  - passed 

ho considerato avere un & & echo "passato"> .result || echo "FAILED"> .result, ma make ha ancora bisogno di una sorta di comando TRAP o __onexit() cleanup per stampare su di essi all'uscita.

Tutti i ninja di Makefile hanno una soluzione di puro makefile per questo?

un-edit - la mia soluzione non stava funzionando nel modo in cui speravo .. STYMIED!

+1

Probabilmente è possibile migliorare questa situazione anteponendo 'set -o pipefail; 'al comando' $ (SUBDIRS) ', in modo che il codice di uscita diverso da zero di un' '(MAKE)' non riuscito non sia più nascosto dall'uscita corretta di 'sed'. – slowdog

+0

Se 'orange' fallisce, vuoi procedere con orange, banana, ecc.? – Beta

+0

@slowdog - Il codice di uscita di make non è necessariamente il problema, ma questo è un buon punto, +1 per te – synthesizerpatel

risposta

0

L'unico modo che vedo è auto-esecuzione con un sub-make:

all : subdirs 

subdirs : 
    $(MAKE) -f $(lastword $(MAKEFILE_LIST)) subdirs-recursive || cat log 

subdirs-recursive: $(SUBDIRS) 
3

Quando si vuole fare abortire al primo fallimento, immediatamente fine e uccidere tutti i lavori in volo invece di aspettare li per finire, è necessario applicare una patch GNU Make come questo http://lists.gnu.org/archive/html/bug-make/2009-01/msg00035.html

Poi è necessario impostare una trappola per ogni shell che fanno invoca (così come set -o pipefail se si utilizza un tubo), come descritto in questo post http://lists.gnu.org/archive/html/help-make/2009-02/msg00011.html

In poche parole: "Se uno di loro non riesce, naturalmente tutta la costruzione fallisce, ma non fino a quando tutta la corsa fa correre a compimento (o il fallimento)"

target1: 
    trap 'kill $$(jobs -p)'; command && something || something-else 
target2: 
    trap 'kill $$(jobs -p)'; set -o pipefail; command | sed '...'