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