Hello Stefano, Bruno, nice collaboration work there, thank you!
I have a few nits, mostly really trivial. Feel free to push after addressing them. --author? * Stefano Lattarini wrote on Fri, Apr 08, 2011 at 12:54:27PM CEST: > Subject: [PATCH] coverage: add tests on remake rules in more complex > situations > > * tests/defs (using_gmake): New function. > (for tool in $required): Use it when $tool is 'GNUmake'. > * tests/remake-moved-m4-file.test: New test. > * tests/remake-deleted-m4-file.test: Likewise. > * tests/remake-renamed-m4-file.test: Likewise. > * tests/remake-renamed-m4-macro-and-file.test: Likewise. > * tests/remake-renamed-m4-macro.test: Likewise. > * tests/remake-add-acsubst-gnulib.test: Likewise. > * tests/remake-add-header-gnulib.test: Likewise. > * tests/remake-remove-header-gnulib.test: Likewise. > * tests/Makefile.am (TESTS): Update. > --- a/tests/defs > +++ b/tests/defs > @@ -146,6 +146,38 @@ AUTOMAKE_fails () > AUTOMAKE_run 1 ${1+"$@"} > } > > +# using_gmake > +# ----------- > +# Return success if $MAKE is GNU make, return failure otherwise. > +# Caches the result for speed reasons. > +using_gmake () > +{ > + case $am__using_gmake in > + yes) > + return 0 > + ;; > + no) > + return 1 > + ;; Would it be ok to merge the ;; to the previous line? My laptop doesn't have very many vertical lines, and the spacing doesn't add information here. Same below in this case statement. Thanks. > + '') > + # Use --version AND -v, because SGI Make doesn't fail on --version. > + # Also grep for GNU because newer versions of FreeBSD make do > + # not complain about `--version' (they seem to silently ignore it). > + if $MAKE --version -v | grep GNU; then > + am__using_gmake=yes > + return 0 > + else > + am__using_gmake=no > + return 1 > + fi > + ;; > + *) > + echo "invalid value for \$am__using_gmake: '$am__using_gmake'" >&2 > + Exit 99 > + ;; > + esac > +} > + > commented_sed_unindent_prog=' > /^$/b # Nothing to do for empty lines. > x # Get x<indent> into pattern space. > @@ -217,11 +249,8 @@ do > etags --version -o /dev/null || exit 77 > ;; > GNUmake) > - # Use --version AND -v, because SGI Make doesn't fail on --version. > - # Also grep for GNU because newer versions of FreeBSD make do > - # not complain about `--version' (they seem to silently ignore it). > - echo "$me: running $MAKE --version -v | grep GNU" > - ( $MAKE --version -v | grep GNU ) || exit 77 > + echo "$me: determine if $MAKE is GNU make" > + using_gmake || exit 77 > ;; > gcc) > # When gcc is required, export `CC=gcc' so that ./configure > --- /dev/null > +++ b/tests/remake-deleted-m4-file.test > +# Test remake rules when an m4 file gets removed and the macros it > +# defined gets inlined into the caller. Try with both an indirect s/gets/get/ > +# call and a direct one. This can be seen as testing the "deleted > +# header file" issue w.r.t. aclocal.m4 dependencies. add cross-ref to acloca22.test? > +. ./defs || Exit 1 > + > +cat >> configure.in <<'END' > +FOO_MACRO > +AC_OUTPUT > +END > + > +cat > Makefile.am <<'END' > +ACLOCAL_AMFLAGS = -I m4 > +.PHONY: test > +test: > + test '$(the_answer)' = 42 -eq ? More instances below. > +END > + > +macro_value='the_answer=42; AC_SUBST([the_answer])' > + > +mkdir m4 > + > +cat > m4/foo.m4 <<'END' > +AC_DEFUN([FOO_MACRO], [BAR_MACRO]) > +END > + > +cat > m4/bar.m4 <<END > +AC_DEFUN([BAR_MACRO], [$macro_value]) > +END > + > +$ACLOCAL -I m4 > +$AUTOCONF > +$AUTOMAKE > + > +./configure > +$MAKE test > + > +$sleep > + > +sed -e "s|BAR_MACRO|$macro_value|" m4/foo.m4 > t > +mv -f t m4/foo.m4 > +rm -f m4/bar.m4 > + > +using_gmake || $MAKE Makefile > +$MAKE test > + > +$sleep > + > +sed -e "s|FOO_MACRO|$macro_value|" configure.in > t > +mv -f t configure.in > +rm -f m4/foo.m4 > + > +using_gmake || $MAKE Makefile > +$MAKE test > --- /dev/null > +++ b/tests/remake-gnulib-add-acsubst.test > +# Test remake rules when a new AC_SUBST'd variable is added, and C header > +# files are involved. > +# This test overlaps with others, and is not strictly necessary per se, > +# but it exercises a real use case (from gnulib, see: > +# <http://lists.gnu.org/archive/html/bug-gnulib/2011-04/msg00005.html> > +# for more info), so keep it anyway. You could s/,.*// in the last line if you like (more instances below), as that part is not needed any more once the test is applied. ;-) > +. ./defs || Exit 1 > + > +cat >> configure.in <<'END' > +AC_PROG_CC > +MY_MACROS > +AC_OUTPUT > +END > + > +cat > Makefile.am <<'END' > +ACLOCAL_AMFLAGS = -I m4 > +noinst_PROGRAMS = foo > +foo_SOURCES = foo.c > +BUILT_SOURCES = foo.h > +edit_h = sed -e 's|[@]foovar@|@foovar@|g' > +foo.h: foo.in.h > + $(edit_h) < $(srcdir)/foo.in.h > $@-t > + cat $@-t;: for debugging > + mv -f $@-t $@ > +EXTRA_DIST = foo.in.h > +MOSTLYCLEANFILES = foo.h foo.h-t > +END > + > +mkdir m4 > + > +cat > m4/foo.m4 <<'END' > +AC_DEFUN([MY_MACROS], [ > + FOO_MACRO > +dnl: ZAP_MACRO > +]) > +END > + > +cat > m4/bar.m4 <<'END' > +AC_DEFUN([FOO_MACRO], [ > + foovar=42; AC_SUBST([foovar]) > +dnl: barvar=47; AC_SUBST([barvar]) > +]) > +END > + > +cat > foo.in.h <<'END' > +#define foo @foovar@ > +END > + > +cat > foo.c <<'END' > +#include "foo.h" > +int main (void) { return 0; } > +typedef int checkfoo[1 - 2 * (foo != 42)]; > +END > + > +$ACLOCAL -I m4 > +$AUTOCONF > +$AUTOMAKE > + > +./configure > +$MAKE > + > +: AC_SUBST @barvar@ and add it to foo.h. > + > +$sleep > + > +sed -e 's/^dnl:/ /' m4/bar.m4 > t > +mv -f t m4/bar.m4 > +cat m4/bar.m4 > + > +cat >> foo.in.h <<'END' > +#define bar @barvar@ > +END > + > +cat >> foo.c <<'END' > +typedef int checkbar[1 - 2 * (bar != 47)]; > +END > + > +cat >> Makefile.am <<'END' > +edit_h += -e 's|[@]barvar@|@barvar@|g' > +END > + > +using_gmake || $MAKE Makefile > +$MAKE > + > +: AC_SUBST @zapvar@ and add it to foo.h. > +# Do it in a slightly different way from how it was done for @barvar@. > + > +$sleep > + > +cat >> Makefile.am <<'END' > +edit_h += -e 's|[@]zapvar@|$(zapvar)|g' > +END > + > +cat >> foo.c <<'END' > +typedef int checkzap[1 - 2 * (zap != 163)]; > +END > + > +sed -e 's/^dnl://' m4/foo.m4 > t > +mv -f t m4/foo.m4 > +cat m4/foo.m4 > + > +cat >> foo.in.h <<'END' > +#define zap @zapvar@ > +END > + > +cat >> m4/bar.m4 <<'END' > +AC_DEFUN([ZAP_MACRO], [zapvar=163; AC_SUBST([zapvar])]) > +END > + > +using_gmake || $MAKE Makefile > +$MAKE > + > +$MAKE distcheck > --- /dev/null > +++ b/tests/remake-gnulib-add-header.test > +# Test remake rules when a new C header "guarded" by AC_SUBST'd > +# variables is added. > +# This test overlaps with others, and is not strictly necessary per se, > +# but it exercises a real use case (from gnulib, see: > +# <http://lists.gnu.org/archive/html/bug-gnulib/2011-04/msg00005.html> > +# for more info), so please keep it anyway. > + > +. ./defs || Exit 1 > + > +cat >> configure.in <<'END' > +AC_CONFIG_HEADERS([config.h]) > +AC_PROG_CC > +MY_MACROS > +AC_OUTPUT > +END > + > +cat > Makefile.am <<'END' > +ACLOCAL_AMFLAGS = -I . > +noinst_PROGRAMS = foo > +foo_SOURCES = foo.c > +BUILT_SOURCES = $(STDIO_H) > +stdio.h: stdio.in.h > + cp $(srcdir)/stdio.in.h $@ > +MOSTLYCLEANFILES = stdio.h > +EXTRA_DIST = stdio.in.h > +check-local: > + ls -l . $(srcdir) > + if test -n '$(STDIO_H)'; then \ > + test -f stdio.h || exit 1; \ > + else \ > + test ! -f stdio.h || exit 1; \ > + fi > +END > + > +cat > macros.m4 <<'END' > +AC_DEFUN([MY_MACROS], [ > + override_stdio=false > + if $override_stdio; then > + STDIO_H=stdio.h > + use_dummies=1 > + else > + STDIO_H= > + use_dummies=0 > + fi > + AC_SUBST([STDIO_H]) > + AC_DEFINE_UNQUOTED([USE_DUMMIES], [$use_dummies], > + [Whether to use dummy types.]) > +]) > +END > + > +cat > stdio.in.h <<'END' > +typedef struct dummyfile { void *p; } DUMMYFILE; > +END > + > +cat > foo.c <<'END' > +#include <config.h> > +#include <stdio.h> > +#if USE_DUMMIES > +DUMMYFILE *f; > +#else > +FILE *f; > +#endif > +int main () { return 0; } > +END > + > +$ACLOCAL -I . > +$AUTOHEADER > +$AUTOMAKE > +$AUTOCONF > + > +./configure > + > +$MAKE > +ls -l > +test ! -f stdio.h > +# Also try our build rules in a VPATH build. > +$MAKE distcheck > + > +# No need to sleep here: "./configure" and "make distcheck" above > +# have already slept enough. > + > +sed -e 's/^\( *override_stdio\)=.*$/\1=:/' macros.m4 > t > +mv -f t macros.m4 > + > +using_gmake || $MAKE Makefile > +$MAKE > +ls -l > +test -f stdio.h > +# Also try our build rules in a VPATH build. > +$MAKE distcheck > --- /dev/null > +++ b/tests/remake-gnulib-remove-header.test > +# Test remake rules when a C header "guarded" by AC_SUBST'd variables > +# is not needed anymore, or when it's needed back. s/back/again/ > +# This test requires some user-level machinery, overlaps with other tests, > +# and is not strictly necessary per se, but it exercises a real, important > +# use case (from gnulib, see: > +# <http://lists.gnu.org/archive/html/bug-gnulib/2011-04/msg00005.html> > +# for more info), so please keep it anyway. > + > +. ./defs || Exit 1 > + > +cat >> configure.in <<'END' > +AC_CONFIG_HEADERS([config.h]) > +AC_PROG_CC > +MY_MACROS > +AC_OUTPUT > +END > + > +cat > Makefile.am <<'END' > +ACLOCAL_AMFLAGS = -I . > +noinst_PROGRAMS = foo > +foo_SOURCES = foo.c > +BUILT_SOURCES = $(STDIO_H) > +if REPLACE_STDIO_H > +stdio.h: stdio.in.h $(top_builddir)/config.status > + cp $(srcdir)/stdio.in.h $@ > +else > +stdio.h: $(top_builddir)/config.status > + rm -f $@ > +endif > +MOSTLYCLEANFILES = stdio.h > +END > + > +cat > macros.m4 <<'END' > +AC_DEFUN([MY_MACROS], [ > + override_stdio=: > + if $override_stdio; then > + STDIO_H=stdio.h > + use_dummies=1 > + else > + STDIO_H= > + use_dummies=0 > + fi > + AC_SUBST([STDIO_H]) > + AC_DEFINE_UNQUOTED([USE_DUMMIES], [$use_dummies], > + [Whether to use dummy types.]) > + AM_CONDITIONAL([REPLACE_STDIO_H], [test -n "$STDIO_H"]) > +]) > +END > + > +cat > stdio.in.h <<'END' > +typedef struct dummyfile { void *p; } DUMMYFILE; > +END > + > +cat > foo.c <<'END' > +#include <config.h> > +#include <stdio.h> > +#if USE_DUMMIES > +DUMMYFILE *f; > +#else > +FILE *f; > +#endif > +int main () { return 0; } > +END > + > +$ACLOCAL -I . > +$AUTOHEADER > +$AUTOMAKE > +$AUTOCONF > + > +for vpath in : false; do > + > + if $vpath; then > + mkdir build > + cd build > + srcdir=.. > + else > + srcdir=. > + fi > + > + # Do not reject slow dependency extractors: we need dependency tracking. > + $srcdir/configure --enable-dependency-tracking This could still result in no dependency tracking, namely when there is just no way. You could add grep 'depmode=none' Makefile && Exit 77 > + $MAKE > + ls -l > + test -f stdio.h > + > + # Simulate that we don't need our custom stdio.h anymore. > + > + $sleep > + sed -e 's/^\( *override_stdio\)=.*$/\1=false/' $srcdir/macros.m4 > t > + diff $srcdir/macros.m4 t && Exit 99 # sanity check > + mv -f t $srcdir/macros.m4 > + > + using_gmake || $MAKE Makefile > + $MAKE > + ls -l > + test ! -f stdio.h > + > + # And now simulate that we want our custom stdio.h back. > + > + $sleep > + sed -e 's/^\( *override_stdio\)=.*$/\1=:/' $srcdir/macros.m4 > t > + diff $srcdir/macros.m4 t && Exit 99 # sanity check > + mv -f t $srcdir/macros.m4 > + > + using_gmake || $MAKE Makefile > + $MAKE > + ls -l > + test -f stdio.h > + > + $MAKE distclean > + cd $srcdir > + > +done > --- /dev/null > +++ b/tests/remake-moved-m4-file.test > +# Test remake rules when an m4 files gets moved among different "include s/an m4 files gets/m4 files get/ > +# dirs" (i.e. those passed to aclocal with `-I' option). > + > +. ./defs || Exit 1 > + > +distdir=$me-1.0 > + > +cat >> configure.in <<'END' > +MY_MACRO > +AC_OUTPUT > +END > + > +cat > Makefile.am <<'END' > +ACLOCAL_AMFLAGS = -I d1 -I d2 -I d3 > +.PHONY: test > +test: > + test '$(the_answer)' = 42 > +END > + > +mkdir d1 d2 d3 > + > +cat > d1/macros.m4 <<'END' > +AC_DEFUN([MY_MACRO], [FOO]) > +END > + > +cat > d1/foo.m4 <<'END' > +AC_DEFUN([FOO], [the_answer=42; AC_SUBST([the_answer])]) > +END > + > +$ACLOCAL -I d1 > +$AUTOCONF > +$AUTOMAKE > + > +./configure > +$MAKE test > + > +# Move one file. > +mv d1/foo.m4 d2/foo.m4 > +using_gmake || $MAKE Makefile > +$MAKE test > +$MAKE distdir > +ls -l $distdir $distdir/* > +test -f $distdir/d2/foo.m4 > +test ! -f $distdir/d1/foo.m4 > +test -f $distdir/d1/macros.m4 > +test ! -f $distdir/d2/macros.m4 > + > +# Move both files at once. > +mv d1/macros.m4 d3/macros.m4 > +mv d2/foo.m4 d3/foo.m4 > +using_gmake || $MAKE Makefile > +$MAKE test > +$MAKE distdir > +ls -l $distdir $distdir/* > +test -f $distdir/d3/foo.m4 > +test -f $distdir/d3/macros.m4 > +test ! -f $distdir/d1/foo.m4 > +test ! -f $distdir/d2/foo.m4 > +test ! -f $distdir/d1/macros.m4 > +test ! -f $distdir/d2/macros.m4 > --- /dev/null > +++ b/tests/remake-renamed-m4-file.test > +# Test remake rules when m4 files gets renamed. s/gets/get/ > +. ./defs || Exit 1 > + > +distdir=$me-1.0 > + > +cat >> configure.in <<'END' > +MY_MACRO > +AC_OUTPUT > +END > + > +cat > Makefile.am <<'END' > +ACLOCAL_AMFLAGS = -I m4 > +.PHONY: test > +test: > + test '$(the_answer)' = 42 > +END > + > +mkdir m4 > + > +cat > m4/macros.m4 <<'END' > +AC_DEFUN([MY_MACRO], [FOO]) > +END > + > +cat > m4/foo.m4 <<'END' > +AC_DEFUN([FOO], [the_answer=42; AC_SUBST([the_answer])]) > +END > + > +$ACLOCAL -I m4 > +$AUTOCONF > +$AUTOMAKE > + > +./configure > +$MAKE test > + > +# Rename one file at the time. > + > +mv m4/foo.m4 m4/bar.m4 > +using_gmake || $MAKE Makefile > +$MAKE test > +$MAKE distdir > +ls -l $distdir $distdir/* > +test -f $distdir/m4/bar.m4 > +test ! -f $distdir/m4/foo.m4 > + > +mv m4/macros.m4 m4/defs.m4 > +using_gmake || $MAKE Makefile > +$MAKE test > +$MAKE distdir > +ls -l $distdir $distdir/* > +test -f $distdir/m4/defs.m4 > +test ! -f $distdir/m4/macros.m4 > + > +# Rename both files at once. > + > +mv m4/bar.m4 m4/quux.m4 > +mv m4/defs.m4 acinclude.m4 > +using_gmake || $MAKE Makefile > +$MAKE test > +$MAKE distdir > +ls -l $distdir $distdir/* > +test -f $distdir/m4/quux.m4 > +test -f $distdir/acinclude.m4 > +test ! -f $distdir/m4/foo.m4 > +test ! -f $distdir/m4/bar.m4 > +test ! -f $distdir/m4/macros.m4 > +test ! -f $distdir/m4/defs.m4 > --- /dev/null > +++ b/tests/remake-renamed-m4-macro-and-file.test > +# Test remake rules when an m4 file gets renamed and *simultaneously* > +# an m4 macro in it gets renamed. Kudos to Bruno Haible for thinking > +# about this situation. > + > +. ./defs || Exit 1 > + > +distdir=$me-1.0 > + > +cat >> configure.in <<'END' > +MY_MACRO > +AC_OUTPUT > +END > + > +cat > Makefile.am <<'END' > +ACLOCAL_AMFLAGS = -I m4 > +.PHONY: test > +test: > + test '$(the_answer)' = 42 > +END > + > +mkdir m4 > + > +cat > m4/macros.m4 <<'END' > +AC_DEFUN([MY_MACRO], [FOO_MACRO]) > +END > + > +cat > m4/foo.m4 <<'END' > +AC_DEFUN([FOO_MACRO], [the_answer=42; AC_SUBST([the_answer])]) > +END > + > +$ACLOCAL -I m4 > +$AUTOCONF > +$AUTOMAKE > + > +./configure > +$MAKE test > + > +# Rename only one file and one macro. > + > +$sleep > +sed -e 's/FOO_MACRO/BAR_MACRO/' m4/foo.m4 > m4/bar.m4 > +rm -f m4/foo.m4 > +sed -e 's/FOO_MACRO/BAR_MACRO/' m4/macros.m4 > t > +mv -f t m4/macros.m4 > +using_gmake || $MAKE Makefile > +$MAKE test > +$MAKE distdir > +ls -l $distdir $distdir/* > +test -f $distdir/m4/bar.m4 > +test -f $distdir/m4/macros.m4 > +test ! -f $distdir/m4/foo.m4 > + > +# Rename both at once. > + > +$sleep > +sed -e 's/BAR_MACRO/QUUX_MACRO/' \ > + m4/bar.m4 > m4/quux.m4 > +sed -e 's/BAR_MACRO/QUUX_MACRO/' -e 's/MY_MACRO/A_MACRO/' \ > + m4/macros.m4 > m4/defs.m4 > +rm -f m4/macros.m4 m4/bar.m4 > +sed -e 's/BAR_MACRO/QUUX_MACRO/' -e 's/MY_MACRO/A_MACRO/' configure.in > t > +mv -f t configure.in > +using_gmake || $MAKE Makefile > +$MAKE test > +$MAKE distdir > +ls -l $distdir $distdir/* > +test -f $distdir/m4/quux.m4 > +test -f $distdir/m4/defs.m4 > +test ! -f $distdir/m4/bar.m4 > +test ! -f $distdir/m4/macros.m4 > --- /dev/null > +++ b/tests/remake-renamed-m4-macro.test > +# Test remake rules when the name of an m4 macro change. Try both with > +# and without indirection. > + > +. ./defs || Exit 1 > + > +cat >> configure.in <<'END' > +MY_MACRO > +AC_OUTPUT > +END > + > +cat > Makefile.am <<'END' > +ACLOCAL_AMFLAGS = -I m4 > +.PHONY: test > +test: > + test '$(the_answer)' = 42 > +END > + > +mkdir m4 > + > +cat > m4/macros.m4 <<'END' > +AC_DEFUN([MY_MACRO], [FOO_1]) > +END > + > +cat > m4/foo.m4 <<'END' > +AC_DEFUN([FOO_1], [the_answer=42 > + AC_SUBST([the_answer])]) > +END > + > +$ACLOCAL -I m4 > +$AUTOCONF > +$AUTOMAKE > + > +./configure > +$MAKE test > + > +$sleep > + > +for x in macros foo; do > + sed -e 's/FOO_1/FOO_2/' m4/$x.m4 > t > + mv -f t m4/$x.m4 > +done > +unset x Why this unset? It doesn't matter to keep it. Same below. > +using_gmake || $MAKE Makefile > +$MAKE test > + > +$sleep > + > +for f in m4/macros.m4 configure.in; do > + sed -e 's/MY_MACRO/YOUR_MACRO/' $f > t > + mv -f t $f > +done > +unset f > + > +using_gmake || $MAKE Makefile > +$MAKE test Thanks again, Ralf