automake: Automake Silent Rules

1 
1 21.3 How Automake can help in silencing make
1 ============================================
1 
1 The tricks and idioms for silencing ‘make’ described in the previous
1 section can be useful from time to time, but we’ve seen that they all
1 have their serious drawbacks and limitations.  That’s why automake
1 provides support for a more advanced and flexible way of obtaining
1 quieter output from ‘make’ (for most rules at least).
1 
1    To give the gist of what Automake can do in this respect, here is a
1 simple comparison between a typical ‘make’ output (where silent rules
1 are disabled) and one with silent rules enabled:
1 
1      % cat Makefile.am
1      bin_PROGRAMS = foo
1      foo_SOURCES = main.c func.c
1      % cat main.c
1      int main (void) { return func (); }  /* func used undeclared */
1      % cat func.c
1      int func (void) { int i; return i; } /* i used uninitialized */
1 
1      The make output is by default very verbose.  This causes warnings
1      from the compiler to be somewhat hidden, and not immediate to spot.
1      % make CFLAGS=-Wall
1      gcc -DPACKAGE_NAME=\"foo\" -DPACKAGE_TARNAME=\"foo\" ...
1      -DPACKAGE_STRING=\"foo\ 1.0\" -DPACKAGE_BUGREPORT=\"\" ...
1      -DPACKAGE=\"foo\" -DVERSION=\"1.0\" -I. -Wall -MT main.o
1      -MD -MP -MF .deps/main.Tpo -c -o main.o main.c
1      main.c: In function ‘main’:
1      main.c:3:3: warning: implicit declaration of function ‘func’
1      mv -f .deps/main.Tpo .deps/main.Po
1      gcc -DPACKAGE_NAME=\"foo\" -DPACKAGE_TARNAME=\"foo\" ...
1      -DPACKAGE_STRING=\"foo\ 1.0\" -DPACKAGE_BUGREPORT=\"\" ...
1      -DPACKAGE=\"foo\" -DVERSION=\"1.0\" -I. -Wall -MT func.o
1      -MD -MP -MF .deps/func.Tpo -c -o func.o func.c
1      func.c: In function ‘func’:
1      func.c:4:3: warning: ‘i’ used uninitialized in this function
1      mv -f .deps/func.Tpo .deps/func.Po
1      gcc -Wall -o foo main.o func.o
1 
1      Clean up, so that we we can rebuild everything from scratch.
1      % make clean
1      test -z "foo" || rm -f foo
1      rm -f *.o
1 
1      Silent rules enabled: the output is minimal but informative.  In
1      particular, the warnings from the compiler stick out very clearly.
1      % make V=0 CFLAGS=-Wall
1        CC     main.o
1      main.c: In function ‘main’:
1      main.c:3:3: warning: implicit declaration of function ‘func’
1        CC     func.o
1      func.c: In function ‘func’:
1      func.c:4:3: warning: ‘i’ used uninitialized in this function
1        CCLD   foo
1 
1    Also, in projects using ‘libtool’, the use of silent rules can
1 automatically enable the ‘libtool’’s ‘--silent’ option:
1 
1      % cat Makefile.am
1      lib_LTLIBRARIES = libx.la
1 
1      % make # Both make and libtool are verbose by default.
1      ...
1      libtool: compile: gcc -DPACKAGE_NAME=\"foo\" ... -DLT_OBJDIR=\".libs/\"
1        -I. -g -O2 -MT libx.lo -MD -MP -MF .deps/libx.Tpo -c libx.c -fPIC
1        -DPIC -o .libs/libx.o
1      mv -f .deps/libx.Tpo .deps/libx.Plo
1      /bin/sh ./libtool --tag=CC --mode=link gcc -g -O2 -o libx.la -rpath
1        /usr/local/lib libx.lo
1      libtool: link: gcc -shared .libs/libx.o -Wl,-soname -Wl,libx.so.0
1        -o .libs/libx.so.0.0.0
1      libtool: link: cd .libs && rm -f libx.so && ln -s libx.so.0.0.0 libx.so
1      ...
1 
1      % make V=0
1        CC     libx.lo
1        CCLD   libx.la
1 
1    For Automake-generated ‘Makefile’s, the user may influence the
1 verbosity at ‘configure’ run time as well as at ‘make’ run time:
1 
1    • Passing ‘--enable-silent-rules’ to ‘configure’ will cause build
1      rules to be less verbose; the option ‘--disable-silent-rules’ will
1      cause normal verbose output.
1    • At ‘make’ run time, the default chosen at ‘configure’ time may be
1      overridden: ‘make V=1’ will produce verbose output, ‘make V=0’ less
1      verbose output.
1 
1    Note that silent rules are _disabled_ by default; the user must
1 enable them explicitly at either ‘configure’ run time or at ‘make’ run
1 time.  We think that this is a good policy, since it provides the casual
1 user with enough information to prepare a good bug report in case
1 anything breaks.
1 
1    Still, notwithstanding the rationales above, a developer who really
1 wants to make silent rules enabled by default in his own package can do
1 so by calling ‘AM_SILENT_RULES([yes])’ in ‘configure.ac’.
1 
1    Users who prefer to have silent rules enabled by default can edit
1 their ‘config.site’ file to make the variable ‘enable_silent_rules’
1 default to ‘yes’.  This should still allow disabling silent rules at
1 ‘configure’ time and at ‘make’ time.
1 
1    For portability to different ‘make’ implementations, package authors
1 are advised to not set the variable ‘V’ inside the ‘Makefile.am’ file,
1 to allow the user to override the value for subdirectories as well.
1 
1    To work at its best, the current implementation of this feature
1 normally uses nested variable expansion ‘$(VAR1$(V))’, a ‘Makefile’
1 feature that is not required by POSIX 2008 but is widely supported in
1 practice.  On the rare ‘make’ implementations that do not support nested
1 variable expansion, whether rules are silent is always determined at
1 configure time, and cannot be overridden at make time.  Future versions
1 of POSIX are likely to require nested variable expansion, so this minor
1 limitation should go away with time.
1 
1    To extend the silent mode to your own rules, you have few choices:
1 
1    • You can use the predefined variable ‘AM_V_GEN’ as a prefix to
1      commands that should output a status line in silent mode, and
1      ‘AM_V_at’ as a prefix to commands that should not output anything
1      in silent mode.  When output is to be verbose, both of these
1      variables will expand to the empty string.
1 
1    • You can silence a recipe unconditionally with ‘@’, and then use the
1      predefined variable ‘AM_V_P’ to know whether make is being run in
1      silent or verbose mode, adjust the verbose information your recipe
1      displays accordingly:
1 
1           generate-headers:
1                           ... [commands defining a shell variable '$headers'] ...; \
1                   if $(AM_V_P); then set -x; else echo " GEN   [headers]"; fi; \
1                   rm -f $$headers && generate-header --flags $$headers
1 
1    • You can add your own variables, so strings of your own choice are
1      shown.  The following snippet shows how you would define your own
1      equivalent of ‘AM_V_GEN’:
1 
1           pkg_verbose = $(pkg_verbose_@AM_V@)
1           pkg_verbose_ = $(pkg_verbose_@AM_DEFAULT_V@)
1           pkg_verbose_0 = @echo PKG-GEN $@;
1 
1           foo: foo.in
1                   $(pkg_verbose)cp $(srcdir)/foo.in $@
1 
1    As a final note, observe that, even when silent rules are enabled,
1 the ‘--no-print-directory’ option is still required with GNU ‘make’ if
1 the “Entering/Leaving directory ...” messages are to be disabled.
1