libtool
[Top][All Lists]
Advanced

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

RFC: on AIX, which "soname"-equivalent to prefer with runtime linking?


From: Michael Haubenwallner
Subject: RFC: on AIX, which "soname"-equivalent to prefer with runtime linking?
Date: Fri, 21 Jan 2011 15:19:14 +0100
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.9) Gecko/20101016 Lightning/1.0b3pre Thunderbird/3.1.3

Hello!

On AIX, with runtime linking (-brtl linker flag) enabled, the current way
how libtool creates shared libraries prevents any form of "soname" support,
as there is no way to have the runtime loader to load a different version of
some shared object (either standalone or as archive member) than the linker
would record into the next binary when linking against this library.

However, there are ways to get an equivalent of "soname" support even with
runtime linking enabled.

What I'm after now is to get a consensus over which way to prefer as
"best practice" to create shared libraries with "soname" support with
runtime linking enabled, even for projects not using libtool but doing
their own platform specifics instead.

So please comment on how my proposed way below is wrong, how it should
be improved/completed/whatever, as well as whether you can or would
accept/support/push it for libtool/your project/whatever, etc.

After playing around with different ways[1], this is my proposed one,
using an AIX feature called "Import Files":

*) Create the shared object "shr.o" (using '-G' linker flag).
*) Set the LOADONLY flag for "shr.o" (using 'strip -e').
*) Create the Import File "shr.imp", containing
   - this header:
       #! libNAME.so.1(shr.o)
       # autoload
       #! libNAME.so.1(shr.o)
   - the list of symbols exported.
*) Create the archive library "libNAME.so.1.2.3" from both
   "shr.imp" and "shr.o".
*) Create the symlinks as usual:
   libNAME.so.1 -> libNAME.so.1.2.3
   libNAME.so -> libNAME.so.1.2.3

Using this way, for existing packages it might be necessary to give the
package manager the choice whether to "--enable-aix-soname", or to keep
the old way the package used to create "libNAME.so" before.

The reasons to choose this way:

*) Need to distinguish different sonames on filename level rather than within
   an unversioned archive file. This is possible with Import Files only, being
   either standalone or an archive member.

   Having multiple unversioned archive files around in directories potentially
   searched at runtime is calling for problems like this one I really had[2]:
   - AIX provides /usr/lib/libiconv.a containing "shr.o"
   - GNU-iconv provides /myprefix/lib/libiconv.a containing "libiconv.so.2",
     and eventually "shr.o" extracted from /usr/lib/libiconv.a to keep existing
     binaries running even when LIBPATH is set to "/myprefix/lib".
   - mybinary linked against GNU-iconv has an encoded runpath "/myprefix/lib:"
     "/usr/lib:/lib" to find the correct libiconv.a even with LIBPATH unset.
   - When calling mybinary from within IBM-Java, "/usr/lib:/lib" is _prepended_
     to LIBPATH, so /usr/lib/libiconv.a is found first - which obviously does
     not contain "libiconv.so.2" and causes mybinary to fail.

*) It is possible to dlopen() with or without a version number:
   - dlopen("libNAME.so(shr.o)", RTLD_MEMBER), besides the preferred
   - dlopen("libNAME.so.1(shr.o)", RTLD_MEMBER), and even
   - dlopen("libNAME.so.1.2.3(shr.o)", RTLD_MEMBER) does work.

   I've choosen "shr.o" as the shared object member name to have at least
   some recognition value when one already knows the traditional AIX way
   of shared libraries.

   While the name "shr.o" of the shared object is irrelevant, it should be
   identical among different libraries, so developers using dlopen() could
   take "(shr.o)" as another "AIX-constant" like RTLD_MEMBER.

   However, it is necessary to create the "shr.o" and "shr.imp" within some
   library-specific subdirectory, to avoid race-conditions when building
   multiple libraries in parallel, or when there is some sourcefile "shr.c".

*) Immediately setting the LOADONLY flag avoids resolving symbols by
   "libNAME.so(shr.o)" when these symbols are not listed for whatever
   reason in the Import File to be provided by "libNAME.so.1(shr.o)".

   I did have the situation where a subsequent binary got references
   to both "libNAME.so.1(shr.o)" and "libNAME.so(shr.o)".

*) '# autoload' keeps a reference to the shared object in the
   target binary even when not referenced by some static object.

   Linking against standalone shared objects does this nevertheless.

   Unfortunately, another shared object having undefined symbols provided
   by this shared object does not trigger the latter to be referenced.

   So omitting the '# autoload' to get some '--as-needed' equivalent may
   not work as expected in all circumstances.

*) The AIX way of multilib (32bit/64bit) does work, by having both
   the 32bit "shr.o" and the 64bit "shr_64.o" in the same archive
   (other platforms call this something like "fat binary"), even if
   libtool does not support that by design (yet?).

   Import Files can declare symbols for either 32bit, 64bit or both
   if necessary. And it is possible to have multiple Import Files in
   one archive. This would be "shr.imp" and "shr_64.imp" respectively.

   While it is even possible to have a 32bit "shr.o" and a 64bit "shr.o"
   in the same archive, I don't think it would be a good idea to do so,
   even if this could allow for libtool.la files to support such .

*) One could think of wrapping the AIX linker to understand the '-soname'
   flag, creating the shared library using this way.

   This would allow for easy patching packages not using libtool, but
   enabling runtime linking and creating the symlinks, to simply add
   the '-soname=libNAME.so.1(shr.o)' linker flag even on AIX.

References:
[1] http://bugs.gentoo.org/show_bug.cgi?id=213277
[2] http://bugs.gentoo.org/show_bug.cgi?id=213277#c11

Thank you!
/haubi/



reply via email to

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