On 11/02/2012 12:16 AM, David Edelsohn wrote:
> I would like to introduce filename-based shared library versioning (known as
> the "soname" in ELF world) for AIX, activated by the '--enable-aix-soname'
> configure flag.

> As discussed in the Bugzilla, I think this is a good feature and a
> nice trick to support SVR4-like shared object naming on AIX (I think
> this really is Linux/SVR4 convention, not ELF file format convention).

Thank you!

> As you mention, this scheme is not compatible with the current shared
> object naming scheme of GCC/libtool on AIX and not backward compatible,

Well, as long as the old sharedlibs were not created as standalone shared
objects (lib.so), this is similar to a normal "soname"-bump on AIX, in that
it is still possible for the package manager to transfer the old shared
objects (with F_LOADONLY flag set) into the new archives.

As far as I can see, gcc does not provide this libtool-option (environment
variable LDFLAGS=-brtl) at all for its libraries (for good reason).

> so it definitely should not be the default.

Yes, of course.

> As Joseph mentioned, these options needs to be documented, but
> otherwise they are a good feature to add.

Here's the updated patch.

Thank you!
/haubi/
>From 3c9141f9df666ad972688b31e1cfecfbfd6ef6b6 Mon Sep 17 00:00:00 2001
From: Michael Haubenwallner <michael.haubenwall...@salomon.at>
Date: Fri, 16 Mar 2012 14:49:20 +0100
Subject: [PATCH] AIX: Filename-based shlib versioning for libgcc_s

2012-11-05  Michael Haubenwallner  <michael.haubenwall...@salomon.at>

	(libgcc_s) Optional filename-based shared library versioning on AIX.
	* gcc/doc/install.texi: Add --enable-aix-soname option.
	* Makefile.in (enable_aix_soname): Define.
	* config/rs6000/t-slibgcc-aix: Implement filename-based versioning.
	* configure.in: Accept --enable-aix-soname option.
	* configure: Recreate.
---
 gcc/doc/install.texi               |   29 +++++++++++++
 libgcc/Makefile.in                 |    1 +
 libgcc/config/rs6000/t-slibgcc-aix |   79 +++++++++++++++++++++++++++++++-----
 libgcc/configure                   |   26 ++++++++++++
 libgcc/configure.ac                |   17 ++++++++
 5 files changed, 141 insertions(+), 11 deletions(-)

diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 7b2441a..8f9425d 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -1336,6 +1336,30 @@ particularly useful if you intend to use several versions of GCC in
 parallel.  This is currently supported by @samp{libgfortran},
 @samp{libjava}, @samp{libmudflap}, @samp{libstdc++}, and @samp{libobjc}.
 
+@item @anchor{enable-aix-soname}--enable-aix-soname
+Traditional AIX shared library versioning (versioned @code{Shared Objects} as
+members of unversioned @code{Archive Library} files named @samp{lib.a}) causes
+numerous headaches for package managers.  However, @code{Import Files} as
+members of @code{Archive Library} files allow for @emph{filename-based} shared
+library versioning known on Linux/SVR4, where this is called the "SONAME".
+But as they prevent static linking, @code{Import Files} may be used with
+@code{Runtime Linking} only, where the linker does search for @samp{lib.so}
+library filenames first.
+
+When enabled, a shared library supporting @option{--enable-aix-soname} is
+created as @code{Shared Archive Library} using the @samp{lib.so} filename, for
+use @emph{with} @code{Runtime Linking} @emph{only}, while the @samp{lib.a}
+filename is created as the plain static @code{Archive Library} - @emph{except}
+for @samp{libgcc_s}, which is not used in static linking, so @file{libgcc_s.a}
+is the symlink referring to the versioned @samp{lib.so} filename.
+
+Package managers can still
+@uref{./specific.html#transfer-aix-shobj,,transfer} the old @code{Shared
+Objects} to the static @code{Archive Library} file (pointed to by the symlink)
+@samp{lib.a} when merging into the live filesystem.
+
+@option{--enable-aix-soname} is currently supported by @samp{libgcc_s}.
+
 @item --enable-languages=@var{lang1},@var{lang2},@dots{}
 Specify that only a particular subset of compilers and
 their runtime libraries should be built.  For a list of valid values for
@@ -3690,6 +3714,7 @@ APAR IY26685 (AIX 4.3) or APAR IY25528 (AIX 5.1).  It also requires a
 fix for another AIX Assembler bug and a co-dependent AIX Archiver fix
 referenced as APAR IY53606 (AIX 5.2) or as APAR IY54774 (AIX 5.1)
 
+@anchor{transfer-aix-shobj}
 @samp{libstdc++} in GCC 3.4 increments the major version number of the
 shared object and GCC installation places the @file{libstdc++.a}
 shared library in a common location which will overwrite the and GCC
@@ -3720,6 +3745,10 @@ Archive the runtime-only shared object in the GCC 3.4
 % ar -q libstdc++.a libstdc++.so.4 libstdc++.so.5
 @end smallexample
 
+You may also need this procedure when you start using the
+@uref{./configure.html#enable-aix-soname,,@option{--enable-aix-soname}}
+configure option.
+
 Linking executables and shared libraries may produce warnings of
 duplicate symbols.  The assembly files generated by GCC for AIX always
 have included multiple symbol definitions for certain global variable
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 43b14a0..b22e82b 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -41,6 +41,7 @@ long_double_type_size = @long_double_type_size@
 decimal_float = @decimal_float@
 enable_decimal_float = @enable_decimal_float@
 fixed_point = @fixed_point@
+enable_aix_soname = @enable_aix_soname@
 
 host_noncanonical = @host_noncanonical@
 target_noncanonical = @target_noncanonical@
diff --git a/libgcc/config/rs6000/t-slibgcc-aix b/libgcc/config/rs6000/t-slibgcc-aix
index a0fdd13..79a6f1f 100644
--- a/libgcc/config/rs6000/t-slibgcc-aix
+++ b/libgcc/config/rs6000/t-slibgcc-aix
@@ -17,24 +17,81 @@
 # along with GCC; see the file COPYING3.  If not see
 # <http://www.gnu.org/licenses/>.
 
-# Build a shared libgcc library.
+# Build a shared libgcc library, with optional filename-based versioning:
+#
+# To get a different *filename* used at runtime than at linktime, instead of
+# the Shared Object we need to give an Import File to the linker, which allows
+# to define a different filename for runtime.
+#
+# Packing both the Import File and the Shared Object into one archive file
+# allows for a file layout similar to what is known on SVR4/Linux platforms -
+# having the unversioned library name as symlink to the versioned one, while
+# still keeping the AIX specific multilib variant of having both 32bit and
+# 64bit Shared Objects within one archive file possible, even if we do not
+# create such libraries (yet?).
+#
+# However, static linking of Shared Objects via an Import File does not work.
+# So as long as a library needs to be statically linkable, we want to use .so
+# as extension for the unversioned symlink, even if that will be used with
+# runtime-linking enabled (-brtl or -G linker flag) only.
+#
+# But as libgcc_s never is statically linked anyway, we can create libgcc_s.a
+# as symlink to libgcc_s.so.1 too (rendering the use of the .so extension as
+# best-practice template here).
+#
+# Use these configure arguments to control the filename-based versioning:
+#
+#   --disable-aix-soname
+#       Do not provide filename-based versioning for shared libgcc (default).
+#
+#   --enable-aix-soname
+#       Create shared libgcc with filename-based versioning, for both linking
+#       with and without AIX runtime-linking enabled.
+#
+# For the symbols listed in the Import File:
+# It would be important to specify their 'weak' attribute, but it turns out
+# that libgcc_s doesn't have weak symbols at all. So there is no need for
+# extra effort to identify weak symbols here.
 SHLIB_EXT = .a
-SHLIB_LINK = $(CC) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
-	-Wl,-bE:@shlib_map_file@ -o @multilib_dir@/shr.o \
+SHLIB_SOVERSION = 1
+SHLIB_SONAME = `test no != $(enable_aix_soname) && echo '@shlib_base_name@.so.$(SHLIB_SOVERSION)' || echo '@shlib_base_name@$(SHLIB_EXT)'`
+SHLIB_MEMBER = `case $(enable_aix_soname):@multilib_dir@ in no:*) echo 'shr' ;; *64*) echo 'shr_64' ;; *) echo 'shr' ;; esac`
+SHLIB_BITS   = `case @multilib_dir@ in *64*) echo '64' ;; *) echo '32' ;; esac`
+SHLIB_LINK = soname=$(SHLIB_SONAME) ; shr=$(SHLIB_MEMBER) ; imp= ; \
+	$(CC) $(LIBGCC2_CFLAGS) -shared -nodefaultlibs \
+	-Wl,-bE:@shlib_map_file@ -o @multilib_dir@/$$shr.o \
 	@multilib_flags@ @shlib_objs@ -lc \
 	`case @multilib_dir@ in \
 	*pthread*) echo -L$(TARGET_SYSTEM_ROOT)/usr/lib/threads -lpthreads -lc_r $(TARGET_SYSTEM_ROOT)/usr/lib/libc.a ;; \
 	*) echo -lc ;; esac` ; \
-	rm -f @multilib_dir@/tmp-@shlib_base_name@.a ; \
-	$(AR_CREATE_FOR_TARGET) @multilib_dir@/tmp-@shlib_base_name@.a \
-	@multilib_dir@/shr.o ; \
-	mv @multilib_dir@/tmp-@shlib_base_name@.a \
-	   @multilib_dir@/@shlib_base_name@.a ; \
-	rm -f @multilib_dir@/shr.o
+	if test no != $(enable_aix_soname); then \
+	  imp=@multilib_dir@/$$shr.imp ; \
+	  $(STRIP_FOR_TARGET) -X32_64 -e @multilib_dir@/$$shr.o ; \
+	  { echo "\#! $$soname($$shr.o)" ; \
+	    echo "\# $(SHLIB_BITS)" ; \
+	    cat @shlib_map_file@ ; \
+	  } > $$imp ; \
+	fi ; \
+	rm -f @multilib_dir@/tmp-$$soname ; \
+	$(AR_CREATE_FOR_TARGET) @multilib_dir@/tmp-$$soname \
+	  $$imp @multilib_dir@/$$shr.o ; \
+	mv @multilib_dir@/tmp-$$soname \
+	   @multilib_dir@/$$soname ; \
+	rm -f $$imp @multilib_dir@/$$shr.o ; \
+	if test no != $(enable_aix_soname); then \
+	  rm -f @multilib_dir@/@shlib_base_name@$(SHLIB_EXT) ; \
+	  $(LN_S) $$soname @multilib_dir@/@shlib_base_name@$(SHLIB_EXT) ; \
+	fi
 SHLIB_INSTALL = \
 	$(mkinstalldirs) $(DESTDIR)$(slibdir)@shlib_slibdir_qual@; \
-	$(INSTALL_DATA) @multilib_dir@/@shlib_base_name@.a \
-		$(DESTDIR)$(slibdir)@shlib_slibdir_qual@/
+	soname=$(SHLIB_SONAME) ; \
+	$(INSTALL_DATA) @multilib_dir@/$$soname \
+		$(DESTDIR)$(slibdir)@shlib_slibdir_qual@/ ; \
+	if test no != $(enable_aix_soname) ; then \
+	  rm -f $(DESTDIR)$(slibdir)@shlib_slibdir_qual@/@shlib_base_name@$(SHLIB_EXT) ; \
+	  $(LN_S) $$soname \
+		  $(DESTDIR)$(slibdir)@shlib_slibdir_qual@/@shlib_base_name@$(SHLIB_EXT) ; \
+	fi
 SHLIB_LIBS = -lc `case @multilib_dir@ in *pthread*) echo -lpthread ;; esac`
 SHLIB_MKMAP = $(srcdir)/mkmap-flat.awk
 SHLIB_MAPFILES = libgcc-std.ver
diff --git a/libgcc/configure b/libgcc/configure
index 1425df6..13d063d 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -608,6 +608,7 @@ build_os
 build_vendor
 build_cpu
 build
+enable_aix_soname
 enable_shared
 libgcc_topdir
 target_alias
@@ -655,6 +656,7 @@ with_target_subdir
 with_cross_host
 with_ld
 enable_shared
+enable_aix_soname
 enable_version_specific_runtime_libs
 with_slibdir
 enable_maintainer_mode
@@ -1288,6 +1290,7 @@ Optional Features:
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
   --disable-shared        don't provide a shared libgcc
+  --enable-aix-soname     on AIX, do filename-based versioning for the shared libgcc
   --enable-version-specific-runtime-libs    Specify that runtime libraries should be installed in a compiler-specific directory
   --enable-maintainer-mode
                           enable make rules and dependencies not useful (and
@@ -2140,6 +2143,29 @@ fi
 
 
 
+# Check whether --enable-aix-soname was given.
+if test "${enable_aix_soname+set}" = set; then :
+  enableval=$enable_aix_soname;
+  case "${host}:${enable_shared}" in
+  powerpc*-*-aix[5-9]*:yes)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to do filename-based versioning for shared libgcc" >&5
+$as_echo_n "checking whether to do filename-based versioning for shared libgcc... " >&6; }
+    case ${enable_aix_soname} in
+    no) ;;
+    *) enable_aix_soname=yes ;;
+    esac
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_aix_soname" >&5
+$as_echo "$enable_aix_soname" >&6; }
+    ;;
+  *) enable_aix_soname=no ;;
+  esac
+
+else
+  enable_aix_soname=no
+fi
+
+
+
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
   as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 8b7aba5..32b3e70 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -66,6 +66,23 @@ AC_ARG_ENABLE(shared,
 ], [enable_shared=yes])
 AC_SUBST(enable_shared)
 
+AC_ARG_ENABLE(aix-soname,
+[  --enable-aix-soname     on AIX, do filename-based versioning for the shared libgcc],
+[
+  case "${host}:${enable_shared}" in
+  powerpc*-*-aix[[5-9]]*:yes)
+    AC_MSG_CHECKING([whether to do filename-based versioning for shared libgcc])
+    case ${enable_aix_soname} in
+    no) ;;
+    *) enable_aix_soname=yes ;;
+    esac
+    AC_MSG_RESULT($enable_aix_soname)
+    ;;
+  *) enable_aix_soname=no ;;
+  esac
+], [enable_aix_soname=no])
+AC_SUBST(enable_aix_soname)
+
 GCC_PICFLAG
 AC_SUBST(PICFLAG)
 
-- 
1.7.3.4

Reply via email to