[Pythonmac-SIG] dlopenflags and sharing symbols across python extension modules
Zachary Pincus
zpincus at stanford.edu
Mon Mar 6 02:56:08 CET 2006
Thanks again Bob for the feedback.
> MH_BUNDLE is not MH_DYLIB and neither are ELF. Everything you
> think you know about shared libraries isn't quite the same on Mac
> OS X. I suggest you read up on Mach-O, I don't really have time to
> answer all of your questions about it.
My admittedly limited knowledge of shared libraries is primarily mac-
based -- I only brought up the ELF cases by way of comparison. At any
rate, regardless of differences between the formats they *all* have a
way to the support weak external references needed for C++ RTTI with
templates.
The sections Apple's of documentation about coalesced sections and
weak definitions discuss how Mach-O supports these features. I think
it's not really that different from how they are supported on ELF.
http://developer.apple.com/documentation/DeveloperTools/Conceptual/
MachORuntime/Reference/reference.html
The problem is that on Macs, Python is not exposing the necessary
mechanism for loading modules so that weak external references are
resolved. On Linux and other platforms where Python respects
sys.setdlopenflags(), this mechanism *is* exposed.
Specifically, the problem is here:
http://svn.python.org/view/python/trunk/Python/dynload_next.c?
rev=36531&view=auto
Python is using NSCreateObjectFileImageFromFile and NSLinkImage to
load and link the bundles. The flags passed to NSLinkImage are *hard
coded* at compile time, so either all bundles are loaded globally or
none are. Contrast this to the case where dlopen is used, and the
dlopenflags are looked up at library load time via
'dlopenflags = PyThreadState_GET()->interp->dlopenflags':
http://svn.python.org/view/python/trunk/Python/dynload_shlib.c?
rev=41910&view=auto
Now, perhaps it is really necessary that on the Mac, the flags be
hard coded and that no run-time selection will work. If so, then I'll
have to implement my own dlopen() based solution as I described earlier.
Otherwise, Mac Python's bundle loading code should have a way to
expose the global symbol loading mechanism (necessary for C++ RTTI
with templates) to user code. There are two ways that I imagine this
could be added:
(1) Provide run-time support for setting the NSLinkImage flags. This
could be as simple as consulting the dlopenflags set in the sys
module (and just noting in the documentation that on Macs, the
'dlopenflags' are really 'NSLinkImage flags'). Or there could be some
mac-specific module where the NSLinkImage flags are defined, and
where there is a SetNSLinkImageFlags command to call.
(2) Move to using dlopen() to load the libraries instead of
NSLinkImage. This might need some minor changes to dynload_shlib.c,
and it would need the configure script to be smart enough to choose
dynload_next.c on 10.2 and below.
Neither of these seem too hard. I could try to work up a patch for
one of these two fixes, if people agree that one or the other is a
better approach. (I might need some guidance, but I would like to
help get this issue resolved.)
>> Basically, this looks like it would be replicating how Python loads
>> modules on Linux. It's too bad that's how it would have to be done,
>> unless there's a better way that I can't think of right now. Anyone
>> have any thoughts/suggestions/guidance?
>
> It'd probably factor it such that the shared stuff (C++ classes) is
> in shared libraries and the Python C API stuff is in the extensions.
Agreed. Unfortunately, parts of the first version of these libraries
are SWIG-generated, and I'm not sure I can teach SWIG to do that
refactoring. Would the stub/proxy approach I suggested work at all,
or will I have to figure out a way to get swig to emit the C++ stuff
in a different place?
Thanks for your suggestions and clarifications!
Zach
More information about the Pythonmac-SIG
mailing list