[PATCH] Avoid invoking ranlib on libbackend.a

Patrick Palka patrick@parcs.ath.cx
Tue Jul 19 00:39:00 GMT 2016


On Mon, 18 Jul 2016, Segher Boessenkool wrote:

> On Mon, Jul 18, 2016 at 06:35:11AM -0500, Segher Boessenkool wrote:
> > Or, if using GNU ar, you can even use -S, if that helps (after testing
> > for it in configure, of course).
> 
> I meant -T.  Some day I will learn how to type, promise!

According to the documentation of GNU ar,

  "gnu ar can optionally create a thin archive, which contains a symbol
  index and references to the original copies of the member files of the
  archive. This is useful for building libraries for use within a local
  build tree, where the relocatable objects are expected to remain
  available, and copying the contents of each object would only waste time
  and space."

Since the objects which libbackend.a is composed of remain available
throughout the build process I think it should be safe to make
libbackend.a a thin archive.

So here's a patch which builds libbackend.a as a thin archive if the
toolchain supports it.  The time it takes to rebuild a
--disable-bootstrap tree after touching a single source file is now 7.5s
instead of 35+s -- a much better speedup than when simply eliding the
call to ranlib since the archive is now 1-5MB in size instead of 450MB.

Instead of changing AR_FLAGS, only the invocation of ar on libbackend.a
is changed because that is by far the largest archive (by a factor of
20x) and it seems less risky this way.

One thing that was not clear to me is whether the object file paths
stored in a thin archive are relative or absolute paths.  If they are
absolute paths then that would be a problem due to how the build system
moves build directories in between stages (gcc/ -> prev-gcc/ etc).  But
it looks like the object file paths are relative to the location of the
archive which is compatible.

Bootstrapped on x86_64-pc-linux-gnu.  Thoughts?

-- >8 --

Subject: [PATCH] Build libbackend.a as a thin archive if possible

gcc/ChangeLog:

	* configure.ac (thin_archive_support): New variable.  AC_SUBST it.
	* configure: Regenerate.
	* Makefile.in (THIN_ARCHIVE_SUPPORT): New variable.
	(USE_THIN_ARCHIVES): New variable.
	(libbackend.a): If USE_THIN_ARCHIVES then pass T to ar to build
	this archive as a thin archive.
---
 gcc/Makefile.in  | 17 +++++++++++++++++
 gcc/configure    | 20 ++++++++++++++++++--
 gcc/configure.ac | 13 +++++++++++++
 3 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 0786fa3..15a879b 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -275,6 +275,17 @@ else
 LLINKER = $(LINKER)
 endif
 
+THIN_ARCHIVE_SUPPORT = @thin_archive_support@
+
+USE_THIN_ARCHIVES = no
+ifeq ($(THIN_ARCHIVE_SUPPORT),yes)
+ifeq ($(AR_FLAGS),rc)
+ifeq ($(RANLIB_FLAGS),)
+USE_THIN_ARCHIVES = yes
+endif
+endif
+endif
+
 # -------------------------------------------
 # Programs which operate on the build machine
 # -------------------------------------------
@@ -1882,8 +1893,14 @@ compilations: $(BACKEND)
 # This archive is strictly for the host.
 libbackend.a: $(OBJS)
 	-rm -rf libbackend.a
+	@# Build libbackend.a as a thin archive if possible, as doing so
+	@# significantly reduces build times.
+ifeq ($(USE_THIN_ARCHIVES),yes)
+	$(AR) $(AR_FLAGS)T libbackend.a $(OBJS)
+else
 	$(AR) $(AR_FLAGS) libbackend.a $(OBJS)
 	-$(RANLIB) $(RANLIB_FLAGS) libbackend.a
+endif
 
 libcommon-target.a: $(OBJS-libcommon-target)
 	-rm -rf libcommon-target.a
diff --git a/gcc/configure b/gcc/configure
index ed44472..81c81b3 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -679,6 +679,7 @@ zlibinc
 zlibdir
 HOST_LIBS
 enable_default_ssp
+thin_archive_support
 libgcc_visibility
 gcc_cv_readelf
 gcc_cv_objdump
@@ -18475,7 +18476,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 18478 "configure"
+#line 18479 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -18581,7 +18582,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 18584 "configure"
+#line 18585 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -27846,6 +27847,21 @@ $as_echo "#define HAVE_AS_LINE_ZERO 1" >>confdefs.h
 
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking support for thin archives" >&5
+$as_echo_n "checking support for thin archives... " >&6; }
+thin_archive_support=no
+echo 'int main (void) { return 0; }' > conftest.c
+if ($AR --version | sed 1q | grep "GNU ar" \
+    && $CC $CFLAGS -c conftest.c \
+    && $AR rcT conftest.a conftest.o \
+    && $CC -o conftest conftest.a) >/dev/null 2>&1; then
+  thin_archive_support=yes
+fi
+rm -f conftest.c conftest.o conftest.a conftest
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $thin_archive_support" >&5
+$as_echo "$thin_archive_support" >&6; }
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking linker PT_GNU_EH_FRAME support" >&5
 $as_echo_n "checking linker PT_GNU_EH_FRAME support... " >&6; }
 gcc_cv_ld_eh_frame_hdr=no
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 086d0fc..63052ba 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4899,6 +4899,19 @@ if test "x$gcc_cv_as_line_zero" = xyes; then
 [Define if the assembler won't complain about a line such as # 0 "" 2.])
 fi
 
+AC_MSG_CHECKING(support for thin archives)
+thin_archive_support=no
+echo 'int main (void) { return 0; }' > conftest.c
+if ($AR --version | sed 1q | grep "GNU ar" \
+    && $CC $CFLAGS -c conftest.c \
+    && $AR rcT conftest.a conftest.o \
+    && $CC -o conftest conftest.a) >/dev/null 2>&1; then
+  thin_archive_support=yes
+fi
+rm -f conftest.c conftest.o conftest.a conftest
+AC_MSG_RESULT($thin_archive_support)
+AC_SUBST(thin_archive_support)
+
 AC_MSG_CHECKING(linker PT_GNU_EH_FRAME support)
 gcc_cv_ld_eh_frame_hdr=no
 if test $in_tree_ld = yes ; then
-- 
2.9.2.321.g3e7e728



More information about the Gcc-patches mailing list