libtool-patches
[Top][All Lists]
Advanced

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

[PATCH] AIX: Optional filename-based shlib versioning


From: Michael Haubenwallner
Subject: [PATCH] AIX: Optional filename-based shlib versioning
Date: Mon, 24 Nov 2014 14:09:10 +0100

Support filename-based shared library versioning on AIX with the lib.so
library filename extension, which is used with runtime linking only.
Runtime linking is enabled by the -brtl linker flag for executables and
the -G linker flag for Shared Objects. The behaviour is similar to
Linux/SVR4 DT_SONAME, hence the name "aix-soname=svr4".

(--with-aix-soname=aix): Default, the current situation.
  (lib.a): When the -brtl linker flag is found in LDFLAGS, create from
    static objects only. Otherways, create as traditional shared library
    archive from the Shared Object built without runtime linking, with
    in-archive versioning.
  (lib.so): When the -brtl linker flag is found in LDFLAGS, create as
    the standalone Shared Object built with the -G linker flag, without
    any versioning support. Otherways, do not create it at all.
  (executables): When the -brtl linker flag is found in LDFLAGS, prefer
    to link against libraries with the .so filename extension.
    Otherways, link against libraries with the .a filename extension.
  (module): When the -brtl linker flag is found in LDFLAGS, same as for
    lib.so.  Otherways, same as for lib.a.

(--with-aix-soname=svr4): Filename-based shared library versioning.
  (lib.a): Create from static objects.
  (lib.so): Create as shared library archive from the Shared Object
    named shr.o or shr_64.o, built with the -G linker flag, and the
    F_LOADONLY flag set, plus an Import File named shr.imp or
    shr_64.imp, respectively, necessary to allow for filename-based
    versioning.
  (executables): Add the -brtl linker flag to LDFLAGS, to prefer linking
    against shared libraries with the .so filename extension.
  (module): Same as for lib.so.

(--with-aix-soname=both): One shared library is created with the
filename-based, another one with the in-archive versioning scheme for
backwards compatibility. The library_names value in the .la file
specifies either the one or the other, depending on whether the -brtl
linker flag is specified in LDFLAGS.
  (lib.a): Create as traditional shared library archive from the Shared
    Object built without runtime linking, with in-archive versioning.
  (lib.so): Create as shared library archive from the Shared Object
    named shr.o or shr_64.o, built with the -G linker flag, and the
    F_LOADONLY flag set, plus an Import File named shr.imp or
    shr_64.imp, respectively, necessary to allow for filename-based
    versioning.
  (executables): When the -brtl linker flag is found in LDFLAGS, prefer
    to link against libraries with the .so filename extension.
    Otherways, link against libraries with the .a filename extension.
  (module): Same as for both lib.a and lib.so.

* Makefile.am: (TESTS_ENVIRONMENT) Pass with_aix_soname value via
lt_cv_with_aix_soname into testsuite.

* configure.ac: AC_SUBST with_aix_soname.

* libltdl/loaders/dlopen.c: (vm_open) Use RTLD_MEMBER flag for dlopen
when the filename does specify an archive member between "()".
Otherways, retry with appending LT_SHARED_LIB_MEMBER when loading fails
without but archive file seems to exist.

* m4/libtool.m4: (dynamic_linker) Describe configured shared library
versioning variant according to with_aix_soname and runtime linking.
(soname_spec, library_names_spec, shlibpath_overrides_runpath,
postinstall_cmds, postuninstall_cmds, hardcode_direct,
hardcode_direct_absolute, no_undefined_flag, allow_undefined_flag) Set
according to with_aix_soname and runtime linking configuration.
(export_symbols_cmds) Decorate symbols with the weak keyword.
(archive_expsym_cmds) Create both shared libraries according to
with_aix_soname and runtime linking configuration. Filter -brtl linker
flag from compiler_flags for shared libraries due to its side effects.
(enable_static) Respect with_aix_soname for disabling as well.

* m4/ltdl.m4: (LT_SHARED_LIB_MEMBER) Define, set based on the value of
the shared_archive_member_spec libtool variable.

* m4/ltoptions.m4: (_LT_WITH_AIX_SONAME) New. Provides commandline
option --with-aix-soname=aix|svr4|both. Declares
(shared_archive_member_spec) as libtool variable.
(_LT_SET_OPTIONS) Define LT_INIT options "aix-soname=aix",
"aix-soname=svr4", "aix-soname=both". Default is "aix-soname=aix".

* tests/deplibs-ident.at: To define whether this test should XFAIL, use
hardcode_action, hardcode_direct, hardcode_direct_absolute configuration
settings instead of platforms aix, bitrig, hppa-hpux, interix or openbsd.

* tests/versioning.at: When shared_archive_member_spec is defined and
LDFLAGS contain -brtl, we can run the versioning check.
---
 Makefile.am              |   1 +
 configure.ac             |   1 +
 libltdl/loaders/dlopen.c |  40 +++++++++
 m4/libtool.m4            | 221 ++++++++++++++++++++++++++++++++++++++++-------
 m4/ltdl.m4               |   5 ++
 m4/ltoptions.m4          |  50 +++++++++++
 tests/deplibs-ident.at   |  11 ++-
 tests/versioning.at      |  14 ++-
 8 files changed, 306 insertions(+), 37 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 38f2dbd..60a067e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -740,6 +740,7 @@ TESTS_ENVIRONMENT = MAKE="$(MAKE)" CC="$(CC)" 
CFLAGS="$(CFLAGS)" \
        F77="$(F77)" FFLAGS="$(FFLAGS)" \
        FC="$(FC)" FCFLAGS="$(FCFLAGS)" \
        GCJ="$(GCJ)" GCJFLAGS="$(GCJFLAGS)" \
+       lt_cv_with_aix_soname="$(with_aix_soname)" \
        lt_cv_to_host_file_cmd="$(to_host_file_cmd)" \
        lt_cv_to_tool_file_cmd="$(to_tool_file_cmd)"
 
diff --git a/configure.ac b/configure.ac
index c4dbe9f..dc777ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -156,6 +156,7 @@ LT_LANG(Windows Resource)
 
 # Ensure the correct file name (and path) conversion function
 # is available to the test suite.
+AC_SUBST([with_aix_soname])dnl
 AC_SUBST([to_host_file_cmd])dnl
 AC_SUBST([to_tool_file_cmd])dnl
 
diff --git a/libltdl/loaders/dlopen.c b/libltdl/loaders/dlopen.c
index 758d7f4..b79df3e 100644
--- a/libltdl/loaders/dlopen.c
+++ b/libltdl/loaders/dlopen.c
@@ -168,6 +168,9 @@ vm_open (lt_user_data LT__UNUSED loader_data, const char 
*filename,
 {
   int          module_flags = LT_LAZY_OR_NOW;
   lt_module    module;
+#ifdef RTLD_MEMBER
+  int          len = LT_STRLEN (filename);
+#endif
 
   if (advise)
     {
@@ -191,8 +194,45 @@ vm_open (lt_user_data LT__UNUSED loader_data, const char 
*filename,
 #endif
     }
 
+#ifdef RTLD_MEMBER /* AIX */
+  if (len >= 4) /* at least "l(m)" */
+    {
+      /* Advise loading an archive member only if the filename really
+        contains both the opening and closing parent, and a member. */
+      if (filename[len-1] == ')')
+       {
+         const char *opening = strrchr(filename, '(');
+         if (opening && opening < (filename+len-2) && strchr(opening+1, '/') 
== NULL)
+           module_flags |= RTLD_MEMBER;
+       }
+    }
+#endif
+
   module = dlopen (filename, module_flags);
 
+#if defined RTLD_MEMBER && defined LT_SHARED_LIB_MEMBER
+  if (!module && len && !(module_flags & RTLD_MEMBER) && errno == ENOEXEC)
+    {
+      /* Loading without a member specified failed with "Exec format error".
+        So the file is there, but either has wrong bitwidth, or is an
+        archive eventually containing the default shared archive member.
+        Retry with default member, getting same error in worst case. */
+      const char *member = LT_SHARED_LIB_MEMBER;
+
+      char *attempt = MALLOC (char, len + strlen (member) + 1);
+      if (!attempt)
+       {
+         LT__SETERROR (NO_MEMORY);
+         return module;
+       }
+
+      sprintf (attempt, "%s%s", filename, member);
+      module = vm_open (loader_data, attempt, advise);
+      FREE (attempt);
+      return module;
+    }
+#endif
+
   if (!module)
     {
       DL__SETERROR (CANNOT_OPEN);
diff --git a/m4/libtool.m4 b/m4/libtool.m4
index 6143541..c50201c 100644
--- a/m4/libtool.m4
+++ b/m4/libtool.m4
@@ -2342,20 +2342,70 @@ aix[[4-9]]*)
       fi
       ;;
     esac
+    # Using Import Files as archive members, it is possible to support
+    # filename-based versioning of shared library archives on AIX. While
+    # this would work for both with and without runtime linking, it will
+    # prevent static linking of such archives. So we do filename-based
+    # shared library versioning with .so extension only, which is used
+    # when both runtime linking and shared linking is enabled.
+    # Unfortunately, runtime linking may impact performance, so we do
+    # not want this to be the default eventually. Also, we use the
+    # versioned .so libs for executables only if there is the -brtl
+    # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only.
+    # To allow for filename-based versioning support, we need to create
+    # libNAME.so.V as an archive file, containing:
+    # *) an Import File, referring to the versioned filename of the
+    #    archive as well as the shared archive member, telling the
+    #    bitwidth (32 or 64) of that shared object, and providing the
+    #    list of exported symbols of that shared object, eventually
+    #    decorated with the 'weak' keyword
+    # *) the shared object with the F_LOADONLY flag set, to really avoid
+    #    it being seen by the linker.
+    # At run time we better use the real file rather than another symlink,
+    # but for link time we create the symlink libNAME.so -> libNAME.so.V
+
+    case $with_aix_soname:$aix_use_runtimelinking in
     # AIX (on Power*) has no versioning support, so currently we cannot 
hardcode correct
     # soname into executable. Probably we can add versioning support to
     # collect2, so additional links can be useful in future.
-    if test yes = "$aix_use_runtimelinking"; then
+    aix:yes) # traditional libtool
+      dynamic_linker='AIX unversionable lib.so'
       # If using run time linking (on AIX 4.2 or later) use lib<name>.so
       # instead of lib<name>.a to let people know that these are not
       # typical AIX shared libraries.
       library_names_spec='$libname$release$shared_ext$versuffix 
$libname$release$shared_ext$major $libname$shared_ext'
-    else
+      ;;
+    aix:no) # traditional AIX only
+      dynamic_linker='AIX lib.a[(]lib.so.V[)]'
       # We preserve .a as extension for shared libraries through AIX4.2
       # and later when we are not doing run time linking.
       library_names_spec='$libname$release.a $libname.a'
       soname_spec='$libname$release$shared_ext$major'
-    fi
+      ;;
+    svr4:*) # full svr4 only
+      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]"
+      library_names_spec='$libname$release$shared_ext$major 
$libname$shared_ext'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *:yes) # both, prefer svr4
+      dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], 
lib.a[(]lib.so.V[)]"
+      library_names_spec='$libname$release$shared_ext$major 
$libname$shared_ext'
+      # unpreferred sharedlib libNAME.a needs extra handling
+      postinstall_cmds='test -n "$linkname" || 
linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog 
"$dir/$func_stripname_result.$libext" 
"$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z 
"$striplib" || $striplib "$destdir/$func_stripname_result.$libext"'
+      postuninstall_cmds='for n in $library_names $old_library; do :; 
done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || 
func_append rmfiles " $odir/$func_stripname_result.$libext"'
+      # We do not specify a path in Import Files, so LIBPATH fires.
+      shlibpath_overrides_runpath=yes
+      ;;
+    *:no) # both, prefer aix
+      dynamic_linker="AIX lib.a[(]lib.so.V[)], 
lib.so.V[(]$shared_archive_member_spec.o[)]"
+      library_names_spec='$libname$release.a $libname.a'
+      soname_spec='$libname$release$shared_ext$major'
+      # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra 
handling
+      postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname 
$destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib 
$destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" 
".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)'
+      postuninstall_cmds='test -z "$dlname" || func_append rmfiles " 
$odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname 
"" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"'
+      ;;
+    esac
     shlibpath_var=LIBPATH
   fi
   ;;
@@ -4764,13 +4814,17 @@ m4_if([$1], [CXX], [
   case $host_os in
   aix[[4-9]]*)
     # If we're using GNU nm, then we don't want the "-C" option.
-    # -C means demangle to AIX nm, but means don't demangle with GNU nm
-    # Also, AIX nm treats weak defined symbols like other global defined
-    # symbols, whereas GNU nm marks them as "W".
+    # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+    # Without the "-l" option, or with the "-B" option, AIX nm treats
+    # weak defined symbols like other global defined symbols, whereas
+    # GNU nm marks them as "W".
+    # While the 'weak' keyword is ignored in the Export File, we need
+    # it in the Import File for the 'aix-soname' feature, so we have
+    # to replace the "-B" option with "-P" for AIX nm.
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | 
awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == 
"W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > 
$export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | 
awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == 
"W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } 
else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
     else
-      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | 
awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 
3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e 
'\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 
2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") 
|| (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 
== "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | 
sort -u > $export_symbols'
     fi
     ;;
   pw32*)
@@ -5214,19 +5268,35 @@ _LT_EOF
        no_entry_flag=
       else
        # If we're using GNU nm, then we don't want the "-C" option.
-       # -C means demangle to AIX nm, but means don't demangle with GNU nm
-       # Also, AIX nm treats weak defined symbols like other global
-       # defined symbols, whereas GNU nm marks them as "W".
+       # -C means demangle to GNU nm, but means don't demangle to AIX nm.
+       # Without the "-l" option, or with the "-B" option, AIX nm treats
+       # weak defined symbols like other global defined symbols, whereas
+       # GNU nm marks them as "W".
+       # While the 'weak' keyword is ignored in the Export File, we need
+       # it in the Import File for the 'aix-soname' feature, so we have
+       # to replace the "-B" option with "-P" for AIX nm.
        if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-         _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | 
awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == 
"W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > 
$export_symbols'
+         _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | 
awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == 
"W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } 
else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
        else
-         _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience 
| awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && 
([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+         _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e 
'\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 
2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") 
|| (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 
== "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | 
sort -u > $export_symbols'
        fi
        aix_use_runtimelinking=no
 
        # Test if we are trying to use run time linking or normal
        # AIX style linking. If -brtl is somewhere in LDFLAGS, we
-       # need to do runtime linking.
+       # have runtime linking enabled, and use it for executables.
+       # For shared libraries, we enable/disable runtime linking
+       # depending on the kind of the shared library created -
+       # when "with_aix_soname:aix_use_runtimelinking" is:
+       # "aix:no"   lib.a(lib.so.V) shared, rtl:no,  for executables
+       # "aix:yes"  lib.so          shared, rtl:yes, for executables
+       #            lib.a           static archive
+       # "both:no"  lib.so.V(shr.o) shared, rtl:yes
+       #            lib.a(lib.so.V) shared, rtl:no,  for executables
+       # "both:yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+       #            lib.a(lib.so.V) shared, rtl:no
+       # "svr4:*"   lib.so.V(shr.o) shared, rtl:yes, for executables
+       #            lib.a           static archive
        case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
          for ld_flag in $LDFLAGS; do
          if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then
@@ -5234,6 +5304,13 @@ _LT_EOF
            break
          fi
          done
+         if test svr4:no = "$with_aix_soname:$aix_use_runtimelinking"; then
+           # With aix-soname=svr4, we create the lib.so.V shared archives only,
+           # so we don't have lib.a shared libs to link our executables.
+           # We have to force runtime linking in this case.
+           aix_use_runtimelinking=yes
+           LDFLAGS="$LDFLAGS -Wl,-brtl"
+         fi
          ;;
        esac
 
@@ -5253,6 +5330,14 @@ _LT_EOF
       _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
       _LT_TAGVAR(link_all_deplibs, $1)=yes
       _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+      case $with_aix_soname:$aix_use_runtimelinking in
+      aix:*) ;; # traditional, no import file
+      svr4:* | *:yes) # use import file
+       # The Import File defines what to hardcode.
+       _LT_TAGVAR(hardcode_direct, $1)=no
+       _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+       ;;
+      esac
 
       if test yes = "$GCC"; then
        case $host_os in aix4.[[012]]|aix4.[[012]].*)
@@ -5280,6 +5365,11 @@ _LT_EOF
        if test yes = "$aix_use_runtimelinking"; then
          shared_flag="$shared_flag "'$wl-G'
        fi
+       # Need to ensure runtime linking is disabled for the traditional
+       # shared library, or the linker may eventually find shared libraries
+       # /with/ Import File - we do not want to mix them.
+       shared_flag_aix='-shared'
+       shared_flag_svr4='-shared $wl-G'
       else
        # not using gcc
        if test ia64 = "$host_cpu"; then
@@ -5292,6 +5382,8 @@ _LT_EOF
          else
            shared_flag='$wl-bM:SRE'
          fi
+         shared_flag_aix='$wl-bM:SRE'
+         shared_flag_svr4='$wl-G'
        fi
       fi
 
@@ -5299,7 +5391,7 @@ _LT_EOF
       # It seems that -bexpall does not export symbols beginning with
       # underscore (_), so it is better to generate a list of symbols to 
export.
       _LT_TAGVAR(always_export_symbols, $1)=yes
-      if test yes = "$aix_use_runtimelinking"; then
+      if test aix:yes = "$with_aix_soname:$aix_use_runtimelinking"; then
        # Warning - without using the other runtime loading flags (-brtl),
        # -berok will link without error, but may produce a broken library.
        _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
@@ -5330,8 +5422,20 @@ _LT_EOF
            _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
          fi
          _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-         # This is similar to how AIX traditionally builds its shared 
libraries.
-         _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o 
$output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags 
$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS 
$output_objdir/$libname$release.a $output_objdir/$soname'
+         _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r 
$output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+         # -brtl affects multiple linker settings, -berok does not and is 
overridden later
+         compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e 
"s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+         if test svr4 != "$with_aix_soname"; then
+           # This is similar to how AIX traditionally builds its shared 
libraries.
+           _LT_TAGVAR(archive_expsym_cmds, 
$1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o 
$output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry 
'$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR 
$AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+         fi
+         if test aix != "$with_aix_soname"; then
+           _LT_TAGVAR(archive_expsym_cmds, 
$1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o 
$output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs 
$wl-bnoentry 
'$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e 
$output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! 
$soname($shared_archive_member_spec.o)"; if test shr_64 = 
"$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 
32"; fi; cat $export_symbols ) > 
$output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS 
$output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o 
$output_objdir/$realname.d/$shared_archive_member_spec.imp'
+         else
+           # used by -dlpreopen to get the symbols
+           _LT_TAGVAR(archive_expsym_cmds, 
$1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  
$output_objdir/$realname.d/$soname $output_objdir'
+         fi
+         _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, 
$1)"'~$RM -r $output_objdir/$realname.d'
        fi
       fi
       ;;
@@ -6056,8 +6160,12 @@ if test -n "$compiler"; then
     ;;
 
   aix[[4-9]]*)
-    if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then
-      test yes = "$enable_shared" && enable_static=no
+    if test ia64 != "$host_cpu"; then
+      case $enable_shared:$with_aix_soname:$aix_use_runtimelinking in
+      yes:aix:yes) ;; # shared object as lib.so file only
+      yes:svr4:*) ;; # shared object as lib.so archive member only
+      yes:*:*) enable_static=no ;; # shared object in lib.a archive as well
+      esac
     fi
     ;;
   esac
@@ -6245,7 +6353,19 @@ if test yes != "$_lt_caught_CXX_error"; then
 
           # Test if we are trying to use run time linking or normal
           # AIX style linking. If -brtl is somewhere in LDFLAGS, we
-          # need to do runtime linking.
+          # have runtime linking enabled, and use it for executables.
+          # For shared libraries, we enable/disable runtime linking
+          # depending on the kind of the shared library created -
+          # when "with_aix_soname:aix_use_runtimelinking" is:
+          # "aix:no"   lib.a(lib.so.V) shared, rtl:no,  for executables
+          # "aix:yes"  lib.so          shared, rtl:yes, for executables
+          #            lib.a           static archive
+          # "both:no"  lib.so.V(shr.o) shared, rtl:yes
+          #            lib.a(lib.so.V) shared, rtl:no,  for executables
+          # "both:yes" lib.so.V(shr.o) shared, rtl:yes, for executables
+          #            lib.a(lib.so.V) shared, rtl:no
+          # "svr4:*"   lib.so.V(shr.o) shared, rtl:yes, for executables
+          #            lib.a           static archive
           case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
            for ld_flag in $LDFLAGS; do
              case $ld_flag in
@@ -6255,6 +6375,13 @@ if test yes != "$_lt_caught_CXX_error"; then
                ;;
              esac
            done
+           if test svr4:no = "$with_aix_soname:$aix_use_runtimelinking"; then
+             # With aix-soname=svr4, we create the lib.so.V shared archives 
only,
+             # so we don't have lib.a shared libs to link our executables.
+             # We have to force runtime linking in this case.
+             aix_use_runtimelinking=yes
+             LDFLAGS="$LDFLAGS -Wl,-brtl"
+           fi
            ;;
           esac
 
@@ -6274,6 +6401,14 @@ if test yes != "$_lt_caught_CXX_error"; then
         _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
         _LT_TAGVAR(link_all_deplibs, $1)=yes
         _LT_TAGVAR(file_list_spec, $1)='$wl-f,'
+        case $with_aix_soname:$aix_use_runtimelinking in
+        aix:*) ;; # no import file
+        svr4:* | *:yes) # use import file
+          # The Import File defines what to hardcode.
+          _LT_TAGVAR(hardcode_direct, $1)=no
+          _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+          ;;
+        esac
 
         if test yes = "$GXX"; then
           case $host_os in aix4.[[012]]|aix4.[[012]].*)
@@ -6300,6 +6435,11 @@ if test yes != "$_lt_caught_CXX_error"; then
          if test yes = "$aix_use_runtimelinking"; then
            shared_flag=$shared_flag' $wl-G'
          fi
+         # Need to ensure runtime linking is disabled for the traditional
+         # shared library, or the linker may eventually find shared libraries
+         # /with/ Import File - we do not want to mix them.
+         shared_flag_aix='-shared'
+         shared_flag_svr4='-shared $wl-G'
         else
           # not using gcc
           if test ia64 = "$host_cpu"; then
@@ -6312,6 +6452,8 @@ if test yes != "$_lt_caught_CXX_error"; then
            else
              shared_flag='$wl-bM:SRE'
            fi
+           shared_flag_aix='$wl-bM:SRE'
+           shared_flag_svr4='$wl-G'
           fi
         fi
 
@@ -6320,10 +6462,11 @@ if test yes != "$_lt_caught_CXX_error"; then
         # underscore (_), so it is better to generate a list of symbols to
        # export.
         _LT_TAGVAR(always_export_symbols, $1)=yes
-        if test yes = "$aix_use_runtimelinking"; then
+       if test aix:yes = "$with_aix_soname:$aix_use_runtimelinking"; then
           # Warning - without using the other runtime loading flags (-brtl),
           # -berok will link without error, but may produce a broken library.
-          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+          # The "-G" linker flag allows undefined symbols.
+          _LT_TAGVAR(no_undefined_flag, $1)='-bernotok'
           # Determine the default libpath from the value encoded in an empty
           # executable.
           _LT_SYS_MODULE_PATH_AIX([$1])
@@ -6352,9 +6495,21 @@ if test yes != "$_lt_caught_CXX_error"; then
              _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
            fi
            _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-           # This is similar to how AIX traditionally builds its shared
-           # libraries.
-           _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o 
$output_objdir/$soname $libobjs $deplibs $wl-bnoentry $compiler_flags 
$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS 
$output_objdir/$libname$release.a $output_objdir/$soname'
+           _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r 
$output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d'
+           # -brtl affects multiple linker settings, -berok does not and is 
overridden later
+           compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED 
-e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`'
+           if test svr4 != "$with_aix_soname"; then
+             # This is similar to how AIX traditionally builds its shared
+             # libraries. Need -bnortl late, we may have -brtl in LDFLAGS.
+             _LT_TAGVAR(archive_expsym_cmds, 
$1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o 
$output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry 
'$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR 
$AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname'
+           fi
+           if test aix != "$with_aix_soname"; then
+             _LT_TAGVAR(archive_expsym_cmds, 
$1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o 
$output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs 
$wl-bnoentry 
'$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e 
$output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! 
$soname($shared_archive_member_spec.o)"; if test shr_64 = 
"$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 
32"; fi; cat $export_symbols ) > 
$output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS 
$output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o 
$output_objdir/$realname.d/$shared_archive_member_spec.imp'
+           else
+             # used by -dlpreopen to get the symbols
+             _LT_TAGVAR(archive_expsym_cmds, 
$1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV  
$output_objdir/$realname.d/$soname $output_objdir'
+           fi
+           _LT_TAGVAR(archive_expsym_cmds, 
$1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d'
           fi
         fi
         ;;
@@ -7535,8 +7690,12 @@ if test yes != "$_lt_disable_F77"; then
         fi
         ;;
       aix[[4-9]]*)
-       if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then
-         test yes = "$enable_shared" && enable_static=no
+       if test ia64 != "$host_cpu"; then
+         case $enable_shared:$with_aix_soname:$aix_use_runtimelinking in
+         yes:aix:yes) ;; # shared object as lib.so file only
+         yes:svr4:*) ;; # shared object as lib.so archive member only
+         yes:*:*) enable_static=no ;; # shared object in lib.a archive as well
+         esac
        fi
         ;;
     esac
@@ -7669,8 +7828,12 @@ if test yes != "$_lt_disable_FC"; then
         fi
         ;;
       aix[[4-9]]*)
-       if test ia64 != "$host_cpu" && test no = "$aix_use_runtimelinking"; then
-         test yes = "$enable_shared" && enable_static=no
+       if test ia64 != "$host_cpu"; then
+         case $enable_shared:$with_aix_soname:$aix_use_runtimelinking in
+         yes:aix:yes) ;; # shared object as lib.so file only
+         yes:svr4:*) ;; # shared object as lib.so archive member only
+         yes:*:*) enable_static=no ;; # shared object in lib.a archive as well
+         esac
        fi
         ;;
     esac
diff --git a/m4/ltdl.m4 b/m4/ltdl.m4
index eeb37ac..59505fc 100644
--- a/m4/ltdl.m4
+++ b/m4/ltdl.m4
@@ -569,6 +569,11 @@ if test "$libltdl_cv_shrext" != "$libltdl_cv_shlibext"; 
then
   AC_DEFINE_UNQUOTED([LT_SHARED_EXT], ["$libltdl_cv_shrext"],
     [Define to the shared library suffix, say, ".dylib".])
 fi
+if test -n "$shared_archive_member_spec"; then
+  m4_pattern_allow([LT_SHARED_LIB_MEMBER])dnl
+  AC_DEFINE_UNQUOTED([LT_SHARED_LIB_MEMBER], 
["($shared_archive_member_spec.o)"],
+    [Define to the shared archive member specification, say "(shr.o)".])
+fi
 ])# LT_SYS_MODULE_EXT
 
 # Old name:
diff --git a/m4/ltoptions.m4 b/m4/ltoptions.m4
index de6520e..061c1f6 100644
--- a/m4/ltoptions.m4
+++ b/m4/ltoptions.m4
@@ -82,6 +82,8 @@ m4_if([$1],[LT_INIT],[
   _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
   _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
                   [_LT_ENABLE_FAST_INSTALL])
+  _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both 
aix-soname=svr4],
+                  [_LT_WITH_AIX_SONAME([aix])])
   ])
 ])# _LT_SET_OPTIONS
 
@@ -319,6 +321,54 @@ dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
 dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
 
 
+# _LT_WITH_AIX_SONAME([DEFAULT])
+# ----------------------------------
+# implement the --with-aix-soname flag, and support the `aix-soname=aix'
+# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
+# is either `aix', `both' or `svr4'.  If omitted, it defaults to `aix'.
+m4_define([_LT_WITH_AIX_SONAME],
+[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, 
both, both, aix))])dnl
+shared_archive_member_spec=
+case $host:$enable_shared in
+(power*-*-aix[[5-9]]*:yes)
+  AC_MSG_CHECKING([which variant of shared library versioning to provide])
+  AC_ARG_WITH([aix-soname],
+    [AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
+      [shared library versioning (aka "SONAME") variant to provide on AIX, 
@<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
+    [case $withval in
+     (aix|svr4|both) ;;
+     (*) AC_MSG_ERROR([Unknown argument to --with-aix-soname]);;
+     esac
+     lt_cv_with_aix_soname=$with_aix_soname],
+    [AC_CACHE_VAL([lt_cv_with_aix_soname],
+      [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
+     with_aix_soname=$lt_cv_with_aix_soname])
+  AC_MSG_RESULT([$with_aix_soname])
+  if test aix != "$with_aix_soname"; then
+    # For the AIX way of multilib, we name the shared archive member
+    # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
+    # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
+    # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
+    # the AIX toolchain works better with OBJECT_MODE set (default 32).
+    if test 64 = "${OBJECT_MODE-32}"; then
+      shared_archive_member_spec=shr_64
+    else
+      shared_archive_member_spec=shr
+    fi
+  fi
+  ;;
+(*) with_aix_soname=aix ;;
+esac
+
+_LT_DECL([], [shared_archive_member_spec], [0],
+    [Shared archive member basename, for filename based shared library 
versioning on AIX])dnl
+])# _LT_WITH_AIX_SONAME
+
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
+LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
+
+
 # _LT_WITH_PIC([MODE])
 # --------------------
 # implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
diff --git a/tests/deplibs-ident.at b/tests/deplibs-ident.at
index 9c5e823..7b0f9bd 100644
--- a/tests/deplibs-ident.at
+++ b/tests/deplibs-ident.at
@@ -67,10 +67,13 @@ int main() { return a1() + a2() + a3() + c(); }
   AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o b$EXEEXT b.$OBJEXT 
../liba1.la ../liba2.la ../liba3.la ../../c/libcee.la -rpath /nowhere],
           [0],[stdout],[ignore])
   AT_CHECK([$EGREP 'cee.*cee' stdout], 1, [ignore], [ignore])
-  AT_XFAIL_IF([case $host in
-                 *-*-aix*|*-*-bitrig*|hppa*-*-hpux*|*-*-interix*|*-*-openbsd*) 
false;;
-                 *):;;
-               esac])
+  AT_XFAIL_IF([dnl
+    eval `$LIBTOOL --config | $EGREP 
'^hardcode_(direct|direct_absolute|action)='`
+    case $hardcode_action:$hardcode_direct:$hardcode_direct_absolute in
+      relink:yes:no) :;;
+      *:no:*) :;;
+      *:*:*) false;;
+    esac])
   dnl This is currently broken in libtool
 )
 
diff --git a/tests/versioning.at b/tests/versioning.at
index dac032c..4b7eb7b 100644
--- a/tests/versioning.at
+++ b/tests/versioning.at
@@ -24,7 +24,7 @@
 AT_SETUP([versioning])
 AT_KEYWORDS([libtool])
 
-eval "`$LIBTOOL --config | $EGREP '^(objdir|host_os)='`"
+eval "`$LIBTOOL --config | $EGREP 
'^(objdir|host_os|shared_archive_member_spec)='`"
 
 # Setup some library and program sources:
 # a library (a1), a new revision (a2), a compatible update (a3),
@@ -228,9 +228,15 @@ AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o 
liba.la liba4.lo ]dnl
 AT_CHECK([$LIBTOOL --mode=install cp liba.la $libdir], [], [ignore], [ignore])
 AT_CHECK([$LIBTOOL --mode=clean rm -f liba.la], [], [ignore], [ignore])
 
-# This test does not work on AIX, not even with runtimelinking, because
-# the linker always records the unversioned name as dependency.
-AT_CHECK([:; case $host_os in aix*) exit 77;; esac])
+# This test does work on AIX when the 'aix-soname' feature is enabled and 
active
+# only, which is reflected in shared_archive_member_spec being set and LDFLAGS
+# containing -brtl. Otherways, even with runtimelinking, the linker always
+# records the unversioned name as dependency.
+AT_CHECK([:; case $host_os^$shared_archive_member_spec^$LDFLAGS in
+aix*^^*) exit 77;;
+aix*^*^*-brtl*) ;;
+aix*^*^*) exit 77 ;;
+esac])
 
 test_installed
 
-- 
1.8.5.5




reply via email to

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