makefile - Controlando la verbosidad de la marca
verbosity (5)
Estoy usando un archivo MAKE para compilar un programa compuesto por muchos archivos .c
, y cada vez make
se invoca make
, solo compila los archivos modificados después de la última ejecución (nada especial hasta aquí).
Para evitar saturar mi pantalla, añoro @
al comienzo de cada llamada $(CC)
, y antes de eso imprimo un mensaje de echo
personalizado. Por ejemplo:
%.o: %.c $(h1) $(h3) %.h
@echo -e "/tCompiling <" $<
@$(CC) $(CFLAGS) -c $< -o $(libDir)$@$(MATHOPTS)
Mi pregunta es: ¿cómo puedo controlar la verbosidad de make
de una manera más "dinámica", para poder:
- Comportamiento normal : solo se imprime un mensaje personalizado para cada regla de makefile ejecutada.
- Comportamiento detallado : imprima el comando realmente ejecutado por cada regla de los archivos MAKE (como si
@
no se hubiera utilizado en absoluto).
Crearia una funcion que toma un comando para ejecutar y decide si hacer eco de ella.
# ''cmd'' takes two arguments:
# 1. The actual command to execute.
# 2. Optional message to print instead of echoing the command
# if executing without ''V'' flag.
ifdef V
cmd = $1
else
cmd = @$(if $(value 2),echo -e "$2";)$1
endif
%.o: %.c $(h1) $(h3) %.h
$(call cmd, /
$(CC) $(CFLAGS) -c $< -o $(libDir)$@$(MATHOPTS), /
Compiling $<)
Entonces el resultado de la invocación de make
simple será algo así como:
Compiling foo.c
Considerando que make V=1
dará:
gcc -Wall -c foo.c -o foo.o ...
Otra solución (una que me gusta porque es flexible)
ifeq ("$(BUILD_VERBOSE)","1")
Q :=
vecho = @echo
else
Q := @
vecho = @true
endif
%.o: %.c
$(vecho) "-> Compiling $@"
$(Q)$(CC) $(CFLAGS) -c $< -o $@
Puedes saltearte las cosas de vecho, pero a veces es útil.
Como no puedo comentar la sugerencia AT = $(AT_$(V))
, tenga en cuenta que Automake proporciona una macro estándar que hace lo mismo que AT
, que se llama AM_V_at
.
También encontrará que tiene otra variable AM_V_GEN
muy útil, que se resuelve en nada o en @echo " GEN " $@;
, dependiendo de la verbosidad.
Esto le permite codificar algo como esto:
grldr.mbr: mbrstart
$(AM_V_GEN)
$(AM_V_at)-rm -f grldr.mbr
$(AM_V_at)cat mbrstart > grldr.mbr
El resultado será (verbosity disabled):
GEN grldr.mbr
o (verbosidad habilitada):
rm -f grldr.mbr
cat mbrstart > grldr.mbr
Muy conveniente, y esto elimina la necesidad de definir sus propias macros.
En lugar de usar "@gcc" para compilar, puede omitir esa "@" y pasar la opción "-s" a su comando make. (Deje "@echo" tal como está). Luego "make -s" sería su comando breve, y "make" sería verboso.
La bandera ''-s'' o ''--silent'' para hacer previene todos los ecos, como si todas las recetas comenzaran con ''@''.
De las páginas de manual de GNU Make
(Las otras respuestas responden mejor a su pregunta, pero este enfoque merece una mención).
Lo haría como lo hace automake:
V = 0
ACTUAL_CC := $(CC)
CC_0 = @echo "Compiling $<..."; $(ACTUAL_CC)
CC_1 = $(ACTUAL_CC)
CC = $(CC_$(V))
%.o: %.c $(h1) $(h3) %.h
$(CC) $(CFLAGS) -c $< -o $(libDir)$@$(MATHOPTS)
Si necesita ejecutar otros comandos en sus reglas, me gusta el siguiente fragmento. Escriba $(AT)
lugar de @
y se silenciará cuando V=0
pero se imprimirá cuando V=1
.
AT_0 := @
AT_1 :=
AT = $(AT_$(V))