Two patches: a fix to be applied to maint, and a testsuite enhancement to be applied to master.
Tested with GNU make from 3.79 to 3.82, FreeBSD 9.0 make, OpenBSD 5.0 make, NetBSD 5.1 make, Solaris 10 CCS make and Sun Distributed Make 7.8. I will push soonish if there is no objection. Regards, Stefano
>From e8a607e7e78cf59721c8277876a4d2323610e4c5 Mon Sep 17 00:00:00 2001 Message-Id: <e8a607e7e78cf59721c8277876a4d2323610e4c5.1329476117.git.stefano.lattar...@gmail.com> From: Stefano Lattarini <stefano.lattar...@gmail.com> Date: Fri, 17 Feb 2012 10:57:37 +0100 Subject: [PATCH] tests: expose $(am__dry_run) limitations Currently, the internal $(am__dry_run) macro can fail in weird ways when $(MAKEFLAGS) contains shell metacharacters. Let's expose this limitation in the testsuite (and fix a couple of related weaknesses since we are at it). * tests/make-dryrun.test: Moved ... * tests/make-dryrun.tap: ... here, converted to TAP, and extended to expose the described limitations. Also ... (am_parallel_tests): Define this so that the 'gen-testsuite-part' script won't generate a useless wrapper script. * test/list-of-tests.mk: Update. --- tests/list-of-tests.mk | 2 +- tests/make-dryrun.tap | 125 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/make-dryrun.test | 65 ------------------------- 3 files changed, 126 insertions(+), 66 deletions(-) create mode 100755 tests/make-dryrun.tap delete mode 100755 tests/make-dryrun.test diff --git a/tests/list-of-tests.mk b/tests/list-of-tests.mk index 119ebca..a80879f 100644 --- a/tests/list-of-tests.mk +++ b/tests/list-of-tests.mk @@ -612,7 +612,7 @@ makej.test \ makej2.test \ maken.test \ maken3.test \ -make-dryrun.test \ +make-dryrun.tap \ makevars.test \ man.test \ man2.test \ diff --git a/tests/make-dryrun.tap b/tests/make-dryrun.tap new file mode 100755 index 0000000..553f28b --- /dev/null +++ b/tests/make-dryrun.tap @@ -0,0 +1,125 @@ +#! /bin/sh +# Copyright (C) 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/>. + +# Check that $(am__make_dryrun) works as expected. + +am_parallel_tests=yes # Avoid generation of a useless wrapper test. +. ./defs || Exit 1 + +plan_ 14 + +if echo "all: ; @+printf %sbb%s aa cc" | $MAKE -n -f - | grep aabbcc; then + make_plus_silence () { return 0; } +else + make_plus_silence () { return 1; } +fi + +mkdir sub + +echo AC_OUTPUT >> configure.in + +cat > Makefile.am <<'END' +all: + : Dummy, nothing to do. +foo: + $(MAKE) all +notdry: + @echo ":: $$MAKEFLAGS ::"; : For debugging. + $(am__make_dryrun) && exit 1; exit 0 +dry: + +@echo ":: $$MAKEFLAGS ::"; : For debugging. + +$(am__make_dryrun) || exit 1; echo ok > from-dry-mode +END + +$ACLOCAL || fatal_ "aclocal failed" +$AUTOCONF || fatal_ "autoconf failed" +$AUTOMAKE || fatal_ "automake failed" +./configure || fatal_ "configure failed" + +# ---------------------------------------------------------------------- + +check_no_dryrun () +{ + command_ok_ "dry-run ($cnt)" $MAKE notdry ${1+"$@"} + cnt=`expr $cnt + 1` +} +cnt=1 + +check_no_dryrun + +# Test against a known regressions. This was especially +# heinous, since make running in normal mode was sometimes +# mistaken for make running in dry mode. +check_no_dryrun TESTS="n1.test n2.test" +check_no_dryrun TESTS="n1 n2" AM_MAKEFLAGS="TESTS='n1 n2'" +check_no_dryrun TESTS="n1 n2" AM_MAKEFLAGS='TESTS="n1 n2"' +check_no_dryrun FOOFLAGS="-n -n -knf2 n --none -n" +check_no_dryrun MYFLAGS="-n --dryrun -n --dry-run -n" + +# ---------------------------------------------------------------------- + +check_dryrun () +{ + r=ok directive= + case $1 in + -C) condition=$2 reason=$3; shift; shift; shift;; + *) condition=: reason=;; + esac + if $condition; then + $MAKE dry ${1+"$@"} || r='not ok' + test -f from-dry-mode || r='not ok' + rm -f from-dry-mode || fatal_ "cleaning up" + else + directive=SKIP + fi + result_ "$r" -D "$directive" -r "$reason" "not dry-run ($cnt)" + unset r directive reason + cnt=`expr $cnt + 1` +} +cnt=1 + +check_dryrun -C make_plus_silence 'recipe prefix "+" unsupported' -n +check_dryrun -C using_gmake "\$MAKE is not GNU make" --dry-run -k + +# ---------------------------------------------------------------------- + +# Test for when shell metacharacters or backslashes are in $(MAKEFLAGS). + +check_metachars () +{ + r=ok + $MAKE notdry ${1+"$@"} || r='not ok' + if test -f bad; then + r='not ok' + else + rm -f bad || fatal_ "cleaning up" + fi + result_ "$r" "dry-run, with shell metachars ($cnt)" + unset r + cnt=`expr $cnt + 1` +} +cnt=1 + +check_metachars MYFLAGS="-n \"n\" '-n' --none -n" +check_metachars MYFLAGS='-knf2\ n\ \\n' +check_metachars MYFLAGS="(&) | ; \" \` '" +check_metachars MYFLAGS=" ' # ' " +check_metachars MYFLAGS='$(foo)' +check_metachars MYFLAGS='`touch bad`' + +# ---------------------------------------------------------------------- + +: diff --git a/tests/make-dryrun.test b/tests/make-dryrun.test deleted file mode 100755 index 0202dc9..0000000 --- a/tests/make-dryrun.test +++ /dev/null @@ -1,65 +0,0 @@ -#! /bin/sh -# Copyright (C) 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/>. - -# Check that $(am__make_dryrun) works as expected. - -. ./defs || Exit 1 - -mkdir sub - -echo AC_OUTPUT >> configure.in - -cat > Makefile.am <<'END' -all: - : Dummy, nothing to do. -foo: - $(MAKE) all -notdry: - @echo ":: $$MAKEFLAGS ::"; : For debugging. - $(am__make_dryrun) && exit 1; exit 0 -dry: - +@echo ":: $$MAKEFLAGS ::"; : For debugging. - +$(am__make_dryrun) || exit 1; echo ok > from-dry-mode -END - -$ACLOCAL -$AUTOCONF -$AUTOMAKE -./configure - -$MAKE notdry - -# Test against a known regressions. This was especially -# heinous, since make running in normal mode was sometimes -# mistaken for make running in dry mode. -$MAKE notdry TESTS="n1.test n2.test" -$MAKE notdry TESTS="n1 n2" AM_MAKEFLAGS="TESTS='n1 n2'" -$MAKE notdry TESTS="n1 n2" AM_MAKEFLAGS='TESTS="n1 n2"' -$MAKE notdry FOOFLAGS="-n -n -knf2 \\n --none -n" -$MAKE notdry BARFLAGS="-n \"n\" '-n' --none -n" - -if echo 'all: ; @+printf %sbb%s aa cc' | $MAKE -n -f - | grep aabbcc; then - $MAKE -n dry - test -f from-dry-mode - rm -f from-dry-mode -fi - -if using_gmake; then - $MAKE --dry-run -k dry - test -f from-dry-mode -fi - -: -- 1.7.9
>From c7575f2fe60ffc0ef770c66cdea2529e95376d01 Mon Sep 17 00:00:00 2001 Message-Id: <c7575f2fe60ffc0ef770c66cdea2529e95376d01.1329476091.git.stefano.lattar...@gmail.com> From: Stefano Lattarini <stefano.lattar...@gmail.com> Date: Fri, 17 Feb 2012 11:52:13 +0100 Subject: [PATCH] dryrun: $(am__dry_run) not confused by metachars in $(MAKEFLAGS) * lib/am/header-vars.am (am__make_dryrun): Make smarter and more correct in handling shell metacharacters in $(MAKEFLAGS). --- lib/am/header-vars.am | 28 ++++++++++++++++++---------- 1 files changed, 18 insertions(+), 10 deletions(-) diff --git a/lib/am/header-vars.am b/lib/am/header-vars.am index 97516ef..2d81009 100644 --- a/lib/am/header-vars.am +++ b/lib/am/header-vars.am @@ -31,20 +31,28 @@ VPATH = @srcdir@ ## ("make -n") or not. Useful in rules that invoke make recursively, ## and are thus executed also with "make -n" -- either because they ## are declared as dependencies to '.MAKE' (NetBSD make), or because -## their recipes contain the "$(MAKE)" string (GNU and Solari make). +## their recipes contain the "$(MAKE)" string (GNU and Solaris make). -## The case statement has [:] in order to not tickle makefile-deps.test -## which greps for '^ *:'. am__make_dryrun = \ { \ am__dry=no; \ - for am__flg in : $(MAKEFLAGS); do \ - case $$am__flg in \ - [:]) ;; \ - *=*|--*) ;; \ - *n*) am__dry=yes; break;; \ - esac; \ - done; \ + case $$MAKEFLAGS in \ +## If we run "make TESTS='snooze nap'", GNU make will export MAKEFLAGS +## to "TESTS=foo\ nap", so that the simpler loop below (on word-splitted +## $$MAKEFLAGS) would see a "make flag" equal to "nap", and would wrongly +## misinterpret that as and indication that make is running in dry mode. +## This has already happened in practice. So we need this hack. + *\\[\ \ ]*) \ + echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \ + | grep '^AM OK$$' >/dev/null || am__dry=yes;; \ + *) \ + for am__flg in $$MAKEFLAGS; do \ + case $$am__flg in \ + *=*|--*) ;; \ + *n*) am__dry=yes; break;; \ + esac; \ + done;; \ + esac; \ test $$am__dry = yes; \ } -- 1.7.9