This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch][RFC] Filename based shared library versioning on AIX
- From: Michael Haubenwallner <michael dot haubenwallner at salomon dot at>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 31 Oct 2012 00:28:30 +0100
- Subject: [patch][RFC] Filename based shared library versioning on AIX
Hello!
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.
Attached patch is for libgcc_s only, patches for libtool have been posted
(although without any reply so far) to:
http://lists.gnu.org/archive/html/libtool-patches/2012-10/msg00001.html
How Import Files can be used for filename-based shared library versioning:
* Create the list of exported symbols from object files,
but with extra "weak" keyword, needed for the Import File later.
* Create shr.o using -G linker flag, using that list of exported symbols.
* Set F_LOADONLY on shr.o.
* Create shr.imp, where
first line is the "soname": #! libNAME.so.1(shr.o)
second line is the bitwidth: # 32
rest is list of symbols: symbol
eventually flagged as weak: weak_symbol weak
* Create libNAME.so.1 as archive, containing shr.o and shr.imp
* Create symlink libNAME.so -> libNAME.so.1
A little discussion about this already is in:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52623#c8
Comments?
Thank you!
/haubi/
>From 8973fb50f5b17296ae3bc8a06326dc7596565439 Mon Sep 17 00:00:00 2001
From: Michael Haubenwallner <michael.haubenwallner@salomon.at>
Date: Fri, 16 Mar 2012 14:49:20 +0100
Subject: [PATCH] AIX: Filename-based shlib versioning for libgcc_s
2012-10-30 Michael Haubenwallner <michael.haubenwallner@salomon.at>
(libgcc_s) Optional filename-based shared library versioning on AIX.
* Makefile.in (enable_aix_soname): Define.
* config/rs6000/t-slibgcc-aix: Implement filename-based versioning.
* configure.in: Accept --enable-aix-soname argument.
* configure: Recreate.
---
libgcc/Makefile.in | 1 +
libgcc/config/rs6000/t-slibgcc-aix | 79 +++++++++++++++++++++++++++++++-----
libgcc/configure | 26 ++++++++++++
libgcc/configure.ac | 17 ++++++++
4 files changed, 112 insertions(+), 11 deletions(-)
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 ed6eabf..361d772 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