Michael Haubenwallner added the comment:

Feels like it is up to me to shed some light on various topics here:

AIX defines (static) "Object" files and "Shared Object" files. Both can (but do 
not need to) be members of an "Archive Library".

When talking about (dynamically loading) a "shared library" on non-AIX systems, 
the correct wording for AIX is (dynamically loading) a "Shared Object" - 
independent of whether it is a standalone file or an archive member.

As you already agreed on, ctypes.util.find_library() indeed should return the 
location of the Shared Object - as either "/path/to/file" or 
"/path/to/file(member)". And ctypes.CDLL() should add the RTLD_MEMBER flag to 
_ctypes.dlopen() if there is the "(member)" part.

However, that does not necessarily mean the RTLD_MEMBER value needs to be 
available through the ctypes API. Instead, RTLD_MEMBER feels more appropriate 
for the _ctypes API - and on AIX only.

Anyway:
Unfortunately, there is no concept of embedding something like ELF's DT_SONAME 
tag into the Shared Object. The very (PATH,BASE,MEMBER) value as (specified to 
and) discovered by the linker is recorded into the just-linked executable (or 
Shared Object). This implies that the runtime loader does search for the very 
same filename (and member eventually) as the linker (at linktime).

However, to still get some kind of shared library versioning, multiple versions 
of one Shared Object are put into one single Archive Library, where the "old" 
versions get the LOADONLY flag set (via 'strip -e') - so executables linked 
against an old version still can load their "old" Shared Object, while the 
linker discovers the "current" version only.

But this "single-filename" based shared library versioning is a huge burden for 
packages managers - either human or software, even when they maintain their 
packages in a private prefix (like /opt/freeware, /usr/local and similar). 
Neither can they put their "current" Shared Object's version into the single 
(system's) Archive Library, nor can they mark existing Shared Objects as 
LOADONLY.
On the other hand, they also do not want to pull all the system versions into 
their own Archive Library.

So for package managers it is crucial to have "multi-filename" based shared 
library versioning instead.

But there is help:
AIX also provides (plain text) "Import Files": They contain a list of symbols 
for the linker, and a (PATH,BASE,MEMBER) tuple naming the Shared Object that 
provides these symbols at runtime.

So yes, Import Files can be used for "multi-filename" based shared library 
versioning.

Thus, libtool now offers the "--with-aix-soname=svr4" configure flag, where 
"libNAME.so.X" really is created as an Archive Library, containing the Shared 
Object "shr.o" with the LOADONLY flag set, and the Import File "shr.imp" 
referring to "libNAME.so.X(shr.o)" for runtime. Combined with the symlink 
"libNAME.so", for the "-lNAME" argument the linker discovers the Import File 
"libNAME.so(shr.imp)" now, while recording "libNAME.so.X(shr.o)" into the 
executable for the runtime loader.
Note that for 64bit the Shared Object and Import File is named "shr_64.o" and 
"shr_64.imp", respectively.

While libtool's "--with-aix-soname=svr4" variant creates "libNAME.a" from 
static Objects only, both libtool's "--with-aix-soname=aix" and 
"--with-aix-soname=both" - for backwards compatibility - create "libNAME.a" for 
traditional "single-filename" based versioning: Without any static Object - as 
even Shared Objects can be linked statically(!). But to statically link the 
Shared Object (as an archive member), neither the LOADONLY flag must be set, 
nor an Import File must be found (as Import Files cannot serve for static 
linking).

And "--with-aix-soname=aix", libtool still creates standalone 
"libNAME.so.X.Y.Z" along the (versioning-wise useless) symlinks.

So it is up to the package manager which "aix-soname" variant to choose within 
its prefix: For example, in Gentoo Prefix I'm using "--with-aix-soname=svr4" 
only.

But still, how to get ctypes.find_library() working - ideally for each variant, 
is another story. Right now it does not work for any variant, but I guess that 
search algorithm should follow how the linker discovers the (PATH,BASE,MEMBER) 
values to write into just-linked executables, combined with how the runtime 
loader finds the Shared Object to actually load.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue27435>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to