2011-06-20 12 views
10

Criterios: Makefile es un Make Make Make de GNU - No estoy interesado en makepp, qmake, cmake, etc. Todos son agradables (especialmente cmake), pero esto es para el trabajo y en el trabajo usamos GNU Make. La solución óptima es una solución pura de Makefile en lugar de una secuencia de comandos shell que analiza hacer para usted.GNU Makefile equivalente del comando shell 'TRAP' para la identificación concisa del error de compilación en la salida

Tampoco quiero hacer una solución de 'continuar con fallas': si está rota, está rota y necesita ser reparada.

La situación es esta, tengo un archivo MAKE que construye varios directorios en paralelo: si uno de ellos falla, por supuesto falla la compilación completa, pero no hasta que todo el funcionamiento se ejecuta hasta su finalización (o falla). Esto significa que la razón por la que realmente falla está enterrada en algún lugar arbitrariamente lejos del final de la salida de make.

He aquí un ejemplo de lo que tengo:

all: $(SUBDIRS) 

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

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

Si me quedo 'make -j 5' y 'naranja' pasa a fallar - Me gustaría ver una tabla como ésta en el final del proceso de maquillaje

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

he pensado en que un & & echo "pasado"> .result || echo "FAILED"> .result, pero make still necesita algún tipo de comando de limpieza TRAP o __onexit() para imprimir en ellos al salir.

¿Alguna ninja Makefile tiene una solución de archivo puro para esto?

un-edit - mi solución no funcionaba realmente como esperaba ... ¡ESTIMADO!

+1

"si uno de ellos falla, por supuesto, toda la generación falla, pero no hasta que todo el funcionamiento hace correr hasta su finalización (o el fracaso)." Probablemente pueda mejorar esa situación anteponiendo 'set -o pipefail; 'al comando' $ (SUBDIRS) ', de modo que el código de salida distinto de cero de un' $ (MAKE) 'fallido ya no esté oculto por la salida exitosa del' sed'. – slowdog

+0

Si 'orange' falla, ¿quiere que proceda con naranja, plátano, etc.? – Beta

+0

@slowdog - El código de salida de make no es necesariamente el problema, pero ese es un buen punto, +1 para usted – synthesizerpatel

Respuesta

0

La única manera que veo es auto-ejecución con una sub-marca:

all : subdirs 

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

subdirs-recursive: $(SUBDIRS) 
3

Cuando se quiere hacer para abortar en el primer fracaso, fin de inmediato y matar a todos los puestos de trabajo durante el vuelo en lugar de esperar que puedan terminar, tienes que parchear GNU hecho así http://lists.gnu.org/archive/html/bug-make/2009-01/msg00035.html

Luego hay que poner una trampa para todos los depósitos que hacen que invoca (así como set -o pipefail si se utiliza un tubo), tal como se describe en este post http://lists.gnu.org/archive/html/help-make/2009-02/msg00011.html

En pocas palabras:

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