Subject: [PATCH 3/3] silent: new $(AM_V_P) variable, tell if we're running in silent mode

From: Stefano Lattarini <[email-masked]>
Date: Mon, 11 Jun 2012 16:52:41 +0200

Addresses part of automake bug#8665.

* automake.in (handle_silent): Define a new make variable '$(AM_V_P)',
that expands to a shell conditional that can be used in make recipes to
determine whether they are being run in silent mode or not.  The choice
of the name derives from the LISP convention of appending the letter
'P' to denote a predicate (see also "the '-P' convention" in the Jargon
File); we do so for lack of a better convention.
* t/automake.texi, NEWS: Document the new variable.
* t/silent6.sh: Adjust and extend.  Move out the checks that didn't
actually deal with user extension of silent rules ...
* t/silent-obsolescent-warns.sh: ... into this test (bound to be
removed once 'maint' is merged into the 'master' branch).
* t/list-of-tests.mk: Add the new test.

Signed-off-by: Stefano Lattarini <[email-masked]>
---
 NEWS                          |    6 +++
 automake.in                   |    7 +++
 doc/automake.texi             |   18 ++++++-
 t/list-of-tests.mk            |    1 +
 t/silent-obsolescent-warns.sh |   71 ++++++++++++++++++++++++++
 t/silent6.sh                  |  110 +++++++++++++++++++----------------------
 6 files changed, 154 insertions(+), 59 deletions(-)
 create mode 100755 t/silent-obsolescent-warns.sh

diff --git a/NEWS b/NEWS
index cf45836..bced15f 100644
--- a/NEWS
+++ b/NEWS
@@ -60,6 +60,12 @@ New in 1.12.2:
     input file.  Such a warning will also be present in the next
     Autoconf version (2.70).
 
+* Silent rules support:
+
+  - A new predefined $(AM_V_P) make variable is provided; it expands
+    to a shell conditional that can be used in recipes to know whether
+    make is being run in silent or verbose mode.
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 New in 1.12.1:
diff --git a/automake.in b/automake.in
index 722a202..53bed2f 100644
--- a/automake.in
+++ b/automake.in
@@ -1235,6 +1235,13 @@ sub define_verbose_libtool ()
 sub handle_silent ()
 {
     return unless option 'silent-rules';
+    # Define "$(AM_V_P)", expanding to a shell conditional that can be
+    # used in make recipes to determine whether we are being run in
+    # silent mode or not.  The choice of the name derives from the LISP
+    # convention of appending the letter 'P' to denote a predicate (see
+    # also "the '-P' convention" in the Jargon File); we do so for lack
+    # of a better convention.
+    define_verbose_var ('P', 'false', ':');
     # *Always* provide the user with 'AM_V_GEN' for 'silent-rules' mode.
     define_verbose_tagvar ('GEN');
     define_verbose_var ('at', '@');
diff --git a/doc/automake.texi b/doc/automake.texi
index 939fe44..1b57cd8 100644
--- a/doc/automake.texi
+++ b/doc/automake.texi
@@ -10966,15 +10966,31 @@ limitation should go away with time.
 @vindex @code{AM_DEFAULT_VERBOSITY}
 @vindex @code{AM_V}
 @vindex @code{AM_DEFAULT_V}
-To extend the silent mode to your own rules, you have two choices:
+To extend the silent mode to your own rules, you have few choices:
 
 @itemize @bullet
+
 @item
 You can use the predefined variable @code{AM_V_GEN} as a prefix to
 commands that should output a status line in silent mode, and
 @code{AM_V_at} as a prefix to commands that should not output anything
 in silent mode.  When output is to be verbose, both of these variables
 will expand to the empty string.
+
+@item
+You can silence a recipe unconditionally with @code{@@}, and then use
+the predefined variable @code{AM_V_P} to know whether make is being run
+in silent or verbose mode, adjust the verbose information your recipe
+displays accordingly:
+
+@example
+generate-headers:
+        @set -e; \
+        ... [commands defining a shell variable '$headers'] ...; \
+        if $(AM_V_P); then set -x; else echo " GEN   [headers]"; fi; \
+        rm -f $$headers && generate-header --flags $$headers
+@end example
+
 @item
 You can add your own variables, so strings of your own choice are shown.
 The following snippet shows how you would define your own equivalent of
diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk
index 446157c..7d7e88e 100644
--- a/t/list-of-tests.mk
+++ b/t/list-of-tests.mk
@@ -976,6 +976,7 @@ t/silent6.sh \
 t/silent7.sh \
 t/silent8.sh \
 t/silent9.sh \
+t/silent-obsolescent-warns.sh \
 t/silentcxx.sh \
 t/silentcxx-gcc.sh \
 t/silentf77.sh \
diff --git a/t/silent-obsolescent-warns.sh b/t/silent-obsolescent-warns.sh
new file mode 100755
index 0000000..a95f118
--- /dev/null
+++ b/t/silent-obsolescent-warns.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+# Copyright (C) 2009-2012 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Some checks about silent-rules mode and warnings.
+
+. ./defs || Exit 1
+
+cat >>configure.ac <<'EOF'
+AM_SILENT_RULES
+AC_OUTPUT
+EOF
+
+cat > Makefile.am <<'EOF'
+my_verbose = $(my_verbose_$(V))
+my_verbose_ = $(my_verbose_$(AM_DEFAULT_VERBOSITY))
+my_verbose_0 = @echo " PKG-GEN    $@";
+foo: foo.in
+	$(my_verbose)cp $(srcdir)/foo.in $@
+EOF
+
+$ACLOCAL
+$AUTOMAKE --add-missing
+
+cat > configure.ac <<'END'
+AC_INIT([silent6], [1.0])
+AM_INIT_AUTOMAKE([-Wall])
+AC_CONFIG_FILES([Makefile])
+END
+
+rm -rf autom4te*.cache
+$ACLOCAL
+AUTOMAKE_fails
+grep 'my_verbose_\$(V.*non-POSIX ' stderr
+$AUTOMAKE -Wno-error
+
+# AM_SILENT_RULES should turn off the warning.
+echo 'AM_SILENT_RULES' >> configure.ac
+rm -rf autom4te*.cache
+$ACLOCAL
+$AUTOMAKE
+grep 'AM_V_GEN' Makefile.in
+$AUTOMAKE --force -Wno-all -Wportability
+grep 'AM_V_GEN' Makefile.in
+
+# The 'silent-rules' option to AM_INIT_AUTOMAKE should work likewise.
+cat > configure.ac <<'END'
+AC_INIT([silent6], [1.0])
+AM_INIT_AUTOMAKE([silent-rules])
+AC_CONFIG_FILES([Makefile])
+END
+rm -rf autom4te*.cache
+$ACLOCAL
+$AUTOMAKE
+grep 'AM_V_GEN' Makefile.in
+$AUTOMAKE --force -Wno-all -Wportability
+grep 'AM_V_GEN' Makefile.in
+
+:
diff --git a/t/silent6.sh b/t/silent6.sh
index 280d25a..1d67a0c 100755
--- a/t/silent6.sh
+++ b/t/silent6.sh
@@ -20,15 +20,33 @@
 
 cat >>configure.ac <<'EOF'
 AM_SILENT_RULES
+AC_CONFIG_FILES([sub/Makefile])
 AC_OUTPUT
 EOF
 
-cat > Makefile.am <<'EOF'
+# We delegate all the work to the subdir makefile.  This is done
+# to ensure any command-line setting of $(V) gets correctly passed
+# down to recursive make invocations.
+echo SUBDIRS = sub > Makefile.am
+
+mkdir sub
+cat > sub/Makefile.am <<'EOF'
 my_verbose = $(my_verbose_$(V))
 my_verbose_ = $(my_verbose_$(AM_DEFAULT_VERBOSITY))
-my_verbose_0 = @echo GEN $@;
+my_verbose_0 = @echo " XGEN    $@";
+
+all-local: foo gen-headers
 
-all-local: foo
+list = 0 1 2
+.PHONY: gen-headers
+gen-headers:
+	@headers=`for i in $(list); do echo sub/$$i.h; done`; \
+	if $(AM_V_P); then set -x; else \
+	  echo " GEN     [headers]"; \
+	fi; \
+	rm -f $$headers || exit 1; \
+## Only fake header generation.
+	: generate-header --flags $$headers
 
 foo: foo.in
 	$(my_verbose)cp $(srcdir)/foo.in $@
@@ -36,72 +54,48 @@ EXTRA_DIST = foo.in
 CLEANFILES = foo
 EOF
 
-: >foo.in
+: > sub/foo.in
 
 $ACLOCAL
 $AUTOMAKE --add-missing
 $AUTOCONF
 
-./configure --enable-silent-rules
-$MAKE >stdout || { cat stdout; Exit 1; }
-cat stdout
-grep '^ *GEN foo *$' stdout
-grep 'cp ' stdout && Exit 1
+do_check ()
+{
+  case ${1-} in
+    --silent) silent=:;;
+    --verbose) silent=false;;
+    *) fatal_ "do_check(): incorrect usage";;
+  esac
+  shift
+  $MAKE clean
+  $MAKE ${1+"$@"} >output 2>&1 || { cat output; Exit 1; }
+  sed 's/^/  /' output
+  if $silent; then
+    $FGREP 'cp ' output && Exit 1
+    $FGREP 'generate-header' output && Exit 1
+    $FGREP 'rm -f' output && Exit 1
+    grep '[012]\.h' output && Exit 1
+    grep '^ XGEN    foo$' output
+    grep '^ GEN     \[headers\]$' output
+  else
+    $FGREP 'GEN ' output && Exit 1
+    $FGREP 'cp ./foo.in foo' output
+    $FGREP "rm -f sub/0.h sub/1.h sub/2.h" output
+    $FGREP "generate-header --flags sub/0.h sub/1.h sub/2.h" output
+  fi
+}
 
-$MAKE clean
-$MAKE V=1 >stdout || { cat stdout; Exit 1; }
-cat stdout
-grep 'GEN ' stdout && Exit 1
-grep 'cp \.*/foo\.in foo' stdout
+./configure --enable-silent-rules
+do_check --silent
+do_check --verbose V=1
 
 $MAKE distclean
 
 ./configure --disable-silent-rules
-$MAKE >stdout || { cat stdout; Exit 1; }
-cat stdout
-grep 'GEN ' stdout && Exit 1
-grep 'cp \.*/foo\.in foo' stdout
-
-$MAKE clean
-$MAKE V=0 >stdout || { cat stdout; Exit 1; }
-cat stdout
-grep '^ *GEN foo *$' stdout
-grep 'cp ' stdout && Exit 1
+do_check --verbose
+do_check --silent V=0
 
 $MAKE distclean
 
-$sleep
-# Things should also work with -Wall in AM_INIT_AUTOMAKE.
-cat > configure.ac <<'END'
-AC_INIT([silent6], [1.0])
-AM_INIT_AUTOMAKE([-Wall])
-AC_CONFIG_FILES([Makefile])
-END
-
-$ACLOCAL
-AUTOMAKE_fails
-$AUTOMAKE -Wno-error
-
-# AM_SILENT_RULES should turn off the warning.
-$sleep
-echo 'AM_SILENT_RULES' >> configure.ac
-$ACLOCAL
-$AUTOMAKE
-grep 'AM_V_GEN' Makefile.in
-$AUTOMAKE --force -Wno-all -Wportability
-grep 'AM_V_GEN' Makefile.in
-
-# The 'silent-rules' option to AM_INIT_AUTOMAKE should work likewise.
-$sleep
-cat > configure.ac <<'END'
-AC_INIT([silent6], [1.0])
-AM_INIT_AUTOMAKE([silent-rules])
-AC_CONFIG_FILES([Makefile])
-END
-$ACLOCAL
-$AUTOMAKE
-grep 'AM_V_GEN' Makefile.in
-$AUTOMAKE --force -Wno-all -Wportability
-grep 'AM_V_GEN' Makefile.in
-
 :
-- 
1.7.9.5