Pregunta

Tengo un Makefile que comienza ejecutando una herramienta antes de aplicar las reglas de compilación (que esta herramienta escribe para mí). Si esta herramienta, que es un script de Python, sale con un código de estado no nulo, quiero que GNU Make se detenga allí y no continúe con la construcción del programa.

Actualmente, hago algo como esto (nivel superior, es decir, columna 1):

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

Pero esto no deja de hacer si collect_sources.py sale con un código de estado de 1. Esto también captura la salida estándar de <=> pero no la imprime, por lo que tengo la sensación de que estoy mirando mal dirección.

Si es posible, la solución debería funcionar incluso cuando un simple shell de MS-DOS es el shell estándar del sistema.

¿Alguna sugerencia?

¿Fue útil?

Solución 2

Ok, aquí está mi propia solución, que desafortunadamente no se basa en el código de estado del script collect_sources.py, pero que funciona para mí (TM) y me permite ver cualquier salida que produzca el script:

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

El script se escribe de modo que cualquier error produzca una salida que comience con "collect_sources: error:". Además, si python no puede encontrar o ejecutar el script dado, genera un mensaje de error que contiene el mensaje "[Errno 2]" o similar. Entonces, este pequeño fragmento de código solo captura la salida (redirigiendo stderr a stdout) y busca mensajes de error. Si no se encuentra ninguno, simplemente usa $(info) para imprimir la salida, de lo contrario usa $(error), lo que efectivamente hace que Stop se detenga.

Tenga en cuenta que la sangría en ifeq ... endif se realiza con espacios. Si se usan pestañas, Make cree que está intentando invocar un comando y se queja de ello.

Otros consejos

Puede haber una mejor manera, pero probé lo siguiente y funciona:

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

Aquí supuse que your_command no da ningún resultado, pero no debería ser difícil solucionar tal situación.

Editar: para que funcione con el shell predeterminado de Windows (y probablemente cualquier shell decente), puede escribir your_command && echo ok en lugar de if dentro de la función shell. No creo que esto sea posible para los shells DOS (más antiguos). Para estos, probablemente desee adaptar <=> o escribir un script de contenedor para imprimir algo por error (o éxito).

Debe usar un objetivo regular para crear BuildRules.mk:

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

include BuildRules.mk

Este es el truco estándar para usar cuando se generan dependencias automáticamente.

Reparación https://stackoverflow.com/a/226974/192373

.PHONY: BuildRules.mk

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

Asegúrese de no invocar make / gmake con la opción -k.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top