From decd002437a649c617bd2bd4079bf6e603c474e8 Mon Sep 17 00:00:00 2001 From: Stefano Lattarini Date: Tue, 3 Jul 2012 11:46:56 +0200 Subject: [PATCH] [ng] built sources: avoid unconditional recursive make invocation With this change, the times for a null-build of GNU coreutils (as averaged from ten builds on an aging Debian system) drops from ~3.8 seconds to ~2.6 seconds. With this change, the semantic of $(BUILT_SOURCES) support is slightly altered, in that $(BUILT_SOURCES) will now be built not only before the "all", "check" or "install" targets, but before *any* target. We believe that not only this change in semantics is justified by the enhanced performance, but that the new semantics is actually better than the old one. So a double win. The new and more complex implementation is a price worth paying for those improvements. * lib/am/all-target.am: New implementation of $(BUILT_SOURCES) support, using more GNU make features (mostly, automatic remake of include files and automatic restart in the face of rebuilt makefiles). This new implementation should ensure that $(BUILT_SOURCES) will be built before before any other target. * lib/am/check-target.am, lib/am/install.am: Simplify: now there's no need to explicitly cater for $(BUILT_SOURCES) in the 'check' and 'install' targets. * t/built-sources-subdir.sh: Adjust and enhance a little. * t/remake-gnulib-remove-header.sh: Trivial adjustment (relying on the fact that .PHONY works correctly for GNU make, also when applied to targets that are existing files). * t/suffix-hdr.sh: Adjust, to avoid GNU make erroneously remove a generated header thinking it is an intermediate file. * t/yacc-deleted-headers.sh: Adjust: we should expect non-existing $(BUILT_SOURCES) to be rebuilt by *any* make invocation. * t/yacc-mix-c-cxx.sh: Likewise. * NG-NEWS (Source Files with Unknown Extensions): Adjust the example to mirror the change. (Miscellaneous): Document the new $(BUILT_SOURCES) semantic. Signed-off-by: Stefano Lattarini --- NG-NEWS | 6 +++- lib/am/all-target.am | 26 ++++++++++------ lib/am/check-target.am | 6 ---- lib/am/install.am | 5 ---- t/built-sources-subdir.sh | 4 ++- t/remake-gnulib-remove-header.sh | 3 +- t/suffix-hdr.sh | 2 +- t/yacc-deleted-headers.sh | 51 +++----------------------------- t/yacc-mix-c-cxx.sh | 5 +--- 9 files changed, 33 insertions(+), 75 deletions(-) diff --git a/NG-NEWS b/NG-NEWS index 8e77df7bb..22e2dfc52 100644 --- a/NG-NEWS +++ b/NG-NEWS @@ -358,7 +358,7 @@ Source Files with Unknown Extensions # This will work. %.h: %.my-hdr $(preprocess-header) $< >$@ - foo_SOURCES = foo.c + foo_SOURCES = foo.c foo.h EXTRA_DIST = foo.my-hdr BUILT_SOURCES = foo.h @@ -386,6 +386,10 @@ Miscellaneous * The Automake-generated clean targets do not exit successfully anymore if an error occurs while removing a file or directory. +* The semantic of $(BUILT_SOURCES) support has been slightly altered; now, + the files listed in $(BUILT_SOURCES) will be built not only before the + "all", "check" or "install" targets, but before *any* target. + ----- Copyright (C) 2012 Free Software Foundation, Inc. diff --git a/lib/am/all-target.am b/lib/am/all-target.am index 25b075a94..9e69726cb 100644 --- a/lib/am/all-target.am +++ b/lib/am/all-target.am @@ -21,14 +21,22 @@ ifdef SUBDIRS .PHONY: all-recursive endif -all-am: all-local %ALL-DEPS% - -# We need to make sure config.h is built before we recurse. -# We also want to make sure that built sources are built -# before any ordinary 'all' targets are run. -ifeq ($(strip %LOCAL-HEADERS% $(BUILT_SOURCES)),) -all: $(if $(SUBDIRS),all-recursive,all-am) +# We need to make sure $(BUILT_SOURCES) files are built before +# any "ordinary" target (all, check, install, ...) is run. +# Ditto for config.h (or files specified in AC_CONFIG_HEADERS). +# But of course, we shouldn't attempt to build any of them when +# running in dry mode. +am.built-early = %LOCAL-HEADERS% $(BUILT_SOURCES) +ifeq ($(am__make_dryrun),true) +# A trick to make the "make -n" output more useful, albeit not +# completely accurate. +all check install: | $(am.built-early) else -all: %LOCAL-HEADERS% $(BUILT_SOURCES) - $(MAKE) $(if $(SUBDIRS),all-recursive,all-am) +$(foreach x,$(am.built-early),$(eval -include .am/built-sources/$(x))) +.am/built-sources/%: | % + @$(am__ensure_target_dir_exists) + @touch $@ endif + +all-am: all-local %ALL-DEPS% +all: $(if $(SUBDIRS),all-recursive,all-am) diff --git a/lib/am/check-target.am b/lib/am/check-target.am index cc3d25d55..225c5667d 100644 --- a/lib/am/check-target.am +++ b/lib/am/check-target.am @@ -29,10 +29,4 @@ check-am: all-am $(if %CHECK-DEPS%,$(MAKE) %CHECK-DEPS%,@:) $(MAKE) %CHECK-TESTS% check-local -# Handle recursion. We have to honor BUILT_SOURCES like for 'all:'. -ifdef BUILT_SOURCES -check: $(BUILT_SOURCES) - $(MAKE) $(if $(SUBDIRS),check-recursive,check-am) -else check: $(if $(SUBDIRS),check-recursive,check-am) -endif diff --git a/lib/am/install.am b/lib/am/install.am index 80af8a1e2..197290547 100644 --- a/lib/am/install.am +++ b/lib/am/install.am @@ -56,12 +56,7 @@ install-data: install-data-am uninstall: uninstall-am endif -ifdef BUILT_SOURCES -install: $(BUILT_SOURCES) - $(MAKE) $(if $(SUBDIRS),install-recursive,install-am) -else install: $(if $(SUBDIRS),install-recursive,install-am) -endif .PHONY: install-am install-am: all-am diff --git a/t/built-sources-subdir.sh b/t/built-sources-subdir.sh index 7c03771f0..cc162bb99 100755 --- a/t/built-sources-subdir.sh +++ b/t/built-sources-subdir.sh @@ -42,11 +42,12 @@ libfoo_a_SOURCES = foo.c BUILT_SOURCES = foo.h foo.h: echo \#define FOO_DEFINE 1 >$@ +CLEANFILES = $(BUILT_SOURCES) END cat > lib/foo.c << 'END' #include -int foo () { return !FOO_DEFINE; } +int foo (void) { return !FOO_DEFINE; } END @@ -56,5 +57,6 @@ $AUTOMAKE --copy --add-missing ./configure $MAKE +$MAKE distcheck : diff --git a/t/remake-gnulib-remove-header.sh b/t/remake-gnulib-remove-header.sh index ec94af55c..5cbe96fdb 100755 --- a/t/remake-gnulib-remove-header.sh +++ b/t/remake-gnulib-remove-header.sh @@ -41,7 +41,8 @@ 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 +.PHONY: stdio.h +stdio.h: rm -f $@ endif MOSTLYCLEANFILES = stdio.h diff --git a/t/suffix-hdr.sh b/t/suffix-hdr.sh index aced454a8..c3bc52270 100755 --- a/t/suffix-hdr.sh +++ b/t/suffix-hdr.sh @@ -26,7 +26,7 @@ END cat > Makefile.am << 'END' noinst_PROGRAMS = zardoz -nodist_zardoz_SOURCES = foo.c +nodist_zardoz_SOURCES = foo.c bar.h EXTRA_DIST = bar.my-h foo.my-c BUILT_SOURCES = bar.h %.c: %.my-c diff --git a/t/yacc-deleted-headers.sh b/t/yacc-deleted-headers.sh index d522b8c40..e02ae39a5 100755 --- a/t/yacc-deleted-headers.sh +++ b/t/yacc-deleted-headers.sh @@ -101,53 +101,9 @@ $MAKE headers='parse1.h p2-parse2.h parse3.h parse4.h' -# Check that we remake only the necessary headers. - -rm -f $headers -$MAKE parse1.h -test -f parse1.h -test ! -e p2-parse2.h -test ! -e parse3.h -test ! -e parse4.h - -rm -f $headers -$MAKE p2-parse2.h -test ! -e parse1.h -test -f p2-parse2.h -test ! -e parse3.h -test ! -e parse4.h - -rm -f $headers -$MAKE parse3.h -test ! -e parse1.h -test ! -e p2-parse2.h -test -f parse3.h -test ! -e parse4.h -# Since we declared parse3.h into $(p3_SOURCES), make should be -# able to rebuild it automatically before remaking 'p3'. -rm -f $headers -$MAKE clean-p3 -test ! -e parse3.h # Sanity check. -$MAKE build-p3 -test -f parse3.h - -$MAKE - -rm -f $headers -$MAKE parse4.h -test ! -e parse1.h -test ! -e p2-parse2.h -test ! -e parse3.h -test -f parse4.h - -# Now remake all the headers together. - rm -f $headers $MAKE $headers -test -f parse1.h -test -f p2-parse2.h -test -f parse3.h -test -f parse4.h +for h in $headers; do test -f $h; done # Most headers should be remade by "make all". @@ -156,8 +112,9 @@ $MAKE all test -f parse1.h test -f p2-parse2.h test -f parse3.h -# parse4.h is not declared in any *_SOURCES variable, nor #included -# by any C source file, so it shouldn't be rebuilt by "make all". +# parse4.h is not declared in any *_SOURCES variable, nor in +# BUILT_SOURCES, nor #included by any C source file, so it +# shouldn't be rebuilt by "make all". test ! -e parse4.h : diff --git a/t/yacc-mix-c-cxx.sh b/t/yacc-mix-c-cxx.sh index b688992c7..eb4b3057a 100755 --- a/t/yacc-mix-c-cxx.sh +++ b/t/yacc-mix-c-cxx.sh @@ -181,13 +181,10 @@ for try in 0 1; do # Minimal checks about recovering from header removal. rm -f p.h parse.hh parse3.hxx - $run_make p.h parse.hh + $run_make $debug_info test -f p.h test -f parse.hh - test ! -e parse3.hxx - $run_make - $debug_info test -f parse3.hxx cd $srcdir -- 2.47.2