automake-ng
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Automake-NG] [PATCH] [ng] built sources: avoid unconditional recursive


From: Stefano Lattarini
Subject: [Automake-NG] [PATCH] [ng] built sources: avoid unconditional recursive make invocation
Date: Tue, 3 Jul 2012 17:01:11 +0200

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 <address@hidden>
---
 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 8e77df7..22e2dfc 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 25b075a..9e69726 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 cc3d25d..225c566 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 80af8a1..1972905 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 7c03771..cc162bb 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 <foo.h>
-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 ec94af5..5cbe96f 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 aced454..c3bc522 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 d522b8c..e02ae39 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 b688992..eb4b305 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
-- 
1.7.9.5




reply via email to

[Prev in Thread] Current Thread [Next in Thread]