[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: RFC: on AIX, which "soname"-equivalent to prefer with runtime linkin
Re: RFC: on AIX, which "soname"-equivalent to prefer with runtime linking?
Fri, 21 Jan 2011 10:48:13 -0600
The "-brtl" isn't a "run-time linking" flag, but more exactly, it's a system-5 shared library compatibility mode flag. It is intended to provide a more familiar shared library style, not additional features. With AIX style shared libraries, you can put multiple versions of a shared library, and static versions, in the same archive file, 32 bit & 64 bit etc. AIX shared libraries are very flexible, however, because no other operating system (to my knowledge) supports the same features, those features are not portable.
On Fri, Jan 21, 2011 at 8:19 AM, Michael Haubenwallner <address@hidden>
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, 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:
- 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:
- 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.