I\'m using a makefile to compile a program made of many .c
files, and any time make
is invoked it only compiles those files modified after the last run
Another solution (one which I like because it's flexible)
ifeq ("$(BUILD_VERBOSE)","1")
Q :=
vecho = @echo
else
Q := @
vecho = @true
endif
%.o: %.c
$(vecho) "-> Compiling $@"
$(Q)$(CC) $(CFLAGS) -c $< -o $@
You can skip the vecho stuff, but it does come in handy at times.
Since I can't comment on the AT = $(AT_$(V))
suggestion, note that Automake does provide a standard macro that does the same thing as AT
, which is called AM_V_at
.
You will also find that it has another very useful AM_V_GEN
variable, that resolves either to nothing or to @echo " GEN " $@;
, depending on the verbosity.
This allows you to code something like this:
grldr.mbr: mbrstart
$(AM_V_GEN)
$(AM_V_at)-rm -f grldr.mbr
$(AM_V_at)cat mbrstart > grldr.mbr
The output of which will be either (verbosity disabled):
GEN grldr.mbr
or (verbosity enabled):
rm -f grldr.mbr
cat mbrstart > grldr.mbr
Pretty convenient, and this removes the need to define your own macros.
Instead of using "@gcc" to compile, you can omit that "@" and pass the "-s" option to your make command instead. (Leave "@echo" as it is.) Then "make -s" would be your brief make command, and "make" would be verbose.
The ‘-s’ or ‘--silent’ flag to make prevents all echoing, as if all recipes started with ‘@’.
From the GNU Make manual pages
(The other answers better answer your question, but this approach deserves a mention.)
I would create a function which takes a command to execute and decides whether to echo it.
# '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 $<)
Then the result of plain make
invocation will be something like:
Compiling foo.c
Whereas make V=1
will give:
gcc -Wall -c foo.c -o foo.o ...
I'd do it the way automake does:
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)
If you need to execute other commands in your rules, I like the following snippet. Write $(AT)
instead of @
and it will be silent when V=0
but printed when V=1
.
AT_0 := @
AT_1 :=
AT = $(AT_$(V))