diff --git a/Makefile.am b/Makefile.am index bb569d602d..acc00c75ad 100644 --- a/Makefile.am +++ b/Makefile.am @@ -12,6 +12,10 @@ # include directory for aclocal ACLOCAL_AMFLAGS = -I m4 +CLEANFILES = +DISTCLEANFILES = +MAINTAINERCLEANFILES = + # Autotools' SUBDIRS (our values are listed below) allow for powerful recursive # recipe automation, with one notable weakness: the dirs are processed in a # loop sequentially, even in parallel builds (each such sub-make is parallel @@ -91,13 +95,24 @@ SUBDIRS_ALL_LIBS_LOCAL = \ #all all-recursive all-am-local all-local: all-fanout-maybe all-recursive: all-fanout-maybe +all: all-fanout-cleanup + +# Run as part of "all", but after the autotools-standard "all-recursive" +# where we quiesce nut_version.h regeneration attempts for each subdir +all-fanout-cleanup: all-recursive + @rm -f include/.all.nut_version-generated.timestamp \ + clients/.all.libupsclient_version-generated.timestamp + # Verbosity for fanout rule tracing; 0/1 (or "default" that may auto-set # to 0 or 1 in some rules below) SUBDIR_MAKE_VERBOSE = default # Run the standard build if going sequential (or with unknown MAKEFLAGS), # or fanout if parallel (presuming GNU/BSD/Sun make at least): +CLEANFILES += include/.all.nut_version-generated.timestamp clients/.all.libupsclient_version-generated.timestamp all-fanout-maybe: @dotMAKE@ + @rm -f include/.all.nut_version-generated.timestamp \ + clients/.all.libupsclient_version-generated.timestamp +@if [ x"$(NUT_MAKE_SKIP_FANOUT)" = xtrue ] ; then \ if [ x"$(SUBDIR_MAKE_VERBOSE)" != x0 ] ; then \ echo " SUBDIR-MAKE $@: skip optimization for parallel make - NUT_MAKE_SKIP_FANOUT is set" ; \ @@ -216,6 +231,10 @@ SUBDIR_TGT_RULE = ( \ all-libs-local/include: @dotMAKE@ +@NUT_VERSION_H_GENERATED=false; export NUT_VERSION_H_GENERATED; \ $(SUBDIR_TGT_RULE) + @[ -s include/nut_version.h ] + @touch -r include/nut_version.h -d '-10 seconds' include/.all.nut_version-generated.timestamp && exit ; \ + touch -d '1970-01-01' include/.all.nut_version-generated.timestamp && exit ; \ + touch include/.all.nut_version-generated.timestamp ### Delivers: libcommon.la libcommonclient.la libcommonstr.la libcommonstrjson.la ### (consume only one of these at a time!) @@ -239,6 +258,10 @@ all-libs-local/common: all-libs-local/include @dotMAKE@ all-libs-local/clients: all-libs-local/common @dotMAKE@ +@NUT_VERSION_H_GENERATED=true; export NUT_VERSION_H_GENERATED; \ $(SUBDIR_TGT_RULE) + @[ -s clients/libupsclient-version.h ] + @touch -r clients/libupsclient-version.h -d '-10 seconds' clients/.all.libupsclient_version-generated.timestamp && exit ; \ + touch -d '1970-01-01' clients/.all.libupsclient_version-generated.timestamp && exit ; \ + touch clients/.all.libupsclient_version-generated.timestamp ### Delivers: libdummy_main.la libdummy_serial.la libdummy_upsdrvquery.la ### Delivers: libdummy_mockdrv.la libserial-nutscan.la @@ -630,8 +653,8 @@ distcleancheck: realclean: maintainer-clean # Files made by our targets: -CLEANFILES = *-spellchecked *.adoc-parsed cppcheck*.xml config.log.inplace-outer -DISTCLEANFILES = ChangeLog +CLEANFILES += *-spellchecked *.adoc-parsed cppcheck*.xml config.log.inplace-outer +DISTCLEANFILES += ChangeLog # Most of the files generated by custom rules in the configure script # or by autogen.sh are cleaned by the Makefile.am in their directories. @@ -647,7 +670,7 @@ DISTCLEANFILES += include/config.h.in~ # from their installation, or made by `automake` etc. on the system # which generates `configure`; rebuilding NUT after deleting these # requires `autogen.sh` script to be re-run (and tools available): -MAINTAINERCLEANFILES = INSTALL +MAINTAINERCLEANFILES += INSTALL MAINTAINERCLEANFILES += aclocal.m4 config.guess config.sub MAINTAINERCLEANFILES += configure MAINTAINERCLEANFILES += depcomp install-sh ltmain.sh test-driver ar-lib @@ -1048,10 +1071,13 @@ ChangeLog.adoc: ChangeLog @dotMAKE@ +cd $(abs_top_builddir)/docs && $(MAKE) $(AM_MAKEFLAGS) ../ChangeLog.adoc nut_version.h include/nut_version.h: @dotMAKE@ + @rm -f include/.all.nut_version-generated.timestamp +cd $(abs_top_builddir)/include && $(MAKE) $(AM_MAKEFLAGS) nut_version.h +# May depend on nut_version.h at least when we ENABLE_SHARED_PRIVATE_LIBS # May involve (re-)build of libupsclient.la -libupsclient-version.h clients/libupsclient-version.h: @dotMAKE@ +libupsclient-version.h clients/libupsclient-version.h: include/nut_version.h @dotMAKE@ + @rm -f clients/.all.libupsclient_version-generated.timestamp +cd $(abs_top_builddir)/include && $(MAKE) $(AM_MAKEFLAGS) libupsclient-version.h tools/gitlog2changelog.py: tools/gitlog2changelog.py.in @dotMAKE@ diff --git a/clients/.gitignore b/clients/.gitignore index f629dd6aed..7cd848259f 100644 --- a/clients/.gitignore +++ b/clients/.gitignore @@ -1,3 +1,4 @@ +/.all.libupsclient_version-generated.timestamp /libupsclient-version.h /libupsclient-version.h.tmp* /upsimage.cgi diff --git a/clients/Makefile.am b/clients/Makefile.am index f2ca5a3d27..ab81516a16 100644 --- a/clients/Makefile.am +++ b/clients/Makefile.am @@ -201,9 +201,27 @@ endif HAVE_WINDOWS # dlname='libupsclient-6.dll' # library_names='libupsclient.dll.a' # libdir='//lib' +# Note that volatile dependencies like nut_version.h can cause re-evaluation +# of the libupsclient.la goal even if ultimately nothing has changed, and so +# cause needless evaluations of libupsclient-version.h. We try a couple of +# ways to skip this rebuild noise for common NUT parallel `make -j N all` runs. CLEANFILES += libupsclient-version.h libupsclient-version.h.tmp* libupsclient-version.h: libupsclient.la - @echo " GENERATE-HEADER $@" ; \ + @if [ -s '$@' -a -s '$?' ] ; then \ + if test -n "`find '$@' -newer '$?' 2>/dev/null`" ; then \ + if [ x"$(MAINTAINER_GENERATE_HEADER_DEBUG)" = xyes ] ; then \ + echo "=== SKIP (include) $@ (libupsclient.la is older than the generated file - not remade when re-evaluated)" >&2; \ + fi ; \ + exit 0; \ + fi ; \ + if test -n "`find '$@' -newer '.all.libupsclient_version-generated.timestamp' 2>/dev/null`" ; then \ + if [ x"$(MAINTAINER_GENERATE_HEADER_DEBUG)" = xyes ] ; then \ + echo "=== SKIP (include) $@ (.all.libupsclient_version-generated.timestamp was made in this larger run and is older than the generated file)" >&2; \ + fi ; \ + exit 0 ; \ + fi ; \ + fi ; \ + echo " GENERATE-HEADER $@" ; \ RES=0; \ dlname_filter() { sed -e 's/^[^=]*=//' -e 's/^"\(.*\)"$$/\1/' -e 's/^'"'"'\(.*\)'"'"'$$/\1/' ; }; \ SOFILE_LIBUPSCLIENT="`$(EGREP) '^dlname' '$?' | dlname_filter`" \ diff --git a/include/.gitignore b/include/.gitignore index 69570ffa44..232a47c4e0 100644 --- a/include/.gitignore +++ b/include/.gitignore @@ -1,5 +1,6 @@ /config.h /config.h.in +/.all.nut_version-generated.timestamp /nut_version.h /nut_version.h.tmp* /stamp-h1 diff --git a/include/Makefile.am b/include/Makefile.am index 0c8974891a..281ae4868f 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -45,12 +45,20 @@ MAINTAINERCLEANFILES = Makefile.in .dirstamp # (e.g. a commit tagged as 2.8.3-rc5 can have its own NUT_VERSION based # on 2.8.2-something, but is assumed as a pre-release for 2.8.3 SEMVER) nut_version.h: @FORCE_NUT_VERSION@ - @if [ -s '$@' ] && ( [ x"$(NUT_VERSION_H_GENERATED)" = xtrue ] || [ x"$${NUT_VERSION_H_GENERATED}" = xtrue ] ) ; then \ - if [ x"$(MAINTAINER_GENERATE_HEADER_DEBUG)" = xyes ] ; then \ - echo "=== SKIP (include) $@ (NUT_VERSION_H_GENERATED makevar=$(NUT_VERSION_H_GENERATED) shellvar=$${NUT_VERSION_H_GENERATED})" >&2; \ + @if [ -s '$@' ] ; then \ + if [ x"$(NUT_VERSION_H_GENERATED)" = xtrue ] || [ x"$${NUT_VERSION_H_GENERATED}" = xtrue ] ; then \ + if [ x"$(MAINTAINER_GENERATE_HEADER_DEBUG)" = xyes ] ; then \ + echo "=== SKIP (include) $@ (NUT_VERSION_H_GENERATED makevar=$(NUT_VERSION_H_GENERATED) shellvar=$${NUT_VERSION_H_GENERATED})" >&2; \ + fi ; \ + exit 0 ; \ fi ; \ - exit 0 ; \ - fi ; \ + if test -n "`find '$@' -newer '.all.nut_version-generated.timestamp' 2>/dev/null`" ; then \ + if [ x"$(MAINTAINER_GENERATE_HEADER_DEBUG)" = xyes ] ; then \ + echo "=== SKIP (include) $@ (.all.nut_version-generated.timestamp was made in this larger run and is older than the generated file)" >&2; \ + fi ; \ + exit 0 ; \ + fi ; \ + fi; \ if [ x"$(MAINTAINER_GENERATE_HEADER_DEBUG)" = xyes ] ; then \ echo " GENERATE-HEADER $@ (NUT_VERSION_H_GENERATED makevar=$(NUT_VERSION_H_GENERATED) shellvar=$${NUT_VERSION_H_GENERATED})"; \ else \