<p dir="ltr">On May 10, 2016 09:00, "Matthew Brett" <<a href="mailto:matthew.brett@gmail.com">matthew.brett@gmail.com</a>> wrote:<br>
><br>
> Hi,<br>
><br>
> On Tue, May 3, 2016 at 4:47 PM, Matthew Brett <<a href="mailto:matthew.brett@gmail.com">matthew.brett@gmail.com</a>> wrote:<br>
> > On Tue, May 3, 2016 at 5:35 AM, Olivier Grisel <<a href="mailto:olivier.grisel@ensta.org">olivier.grisel@ensta.org</a>> wrote:<br>
> >>> I tested it with:<br>
> >>><br>
> >>> import matplotlib<br>
> >>> matplotlib.use('PyQt5')<br>
> >><br>
> >> Typo, this was supposed to read:<br>
> >><br>
> >> matplotlib.use('Qt5Agg')<br>
> ><br>
> > Meanwhile, I tried removing (patchelf --remove-needed) the<br>
> > requirements of _tkagg.so on the vendored libtk, libtcl, and added<br>
> > back the requirement (patch --add-needed) on general `libtk.so' and<br>
> > 'libtcl.so'. This removed the segfault and allowed me to display<br>
> > `plt.range(10)'. I suppose then, that the tk / tcl ABI that we are<br>
> > using is relatively stable across versions 8.4 (on the docker image)<br>
> > and 8.6 (on Debian sid).<br>
> ><br>
> > Worth experimenting with this - or too much of a hack?<br>
><br>
> I have experimented with this. It does seem that we can get away with<br>
> using the system tcl / tk libraries as installed, at least on a couple<br>
> of Debian systems I have.<br>
><br>
> Now there's a new problem, to do with linux library namespaces. We<br>
> need the _tkagg.so file to use the same libraries as the Python<br>
> Tkinter package at run time. There can be more than one tcl / tk<br>
> version installed on a given system, so, as things stand, we'd need to<br>
> inspect the Tkinter extension modules to see what they are using, and<br>
> then work out a way to use those libraries at run time. Here are the<br>
> questions for the experts out there:<br>
><br>
> * Can anyone think of a way of using the symbol namespace of the<br>
> tkinter extension modules directly, to pick up the symbols we need<br>
> rather than re-importing the libraries?</p>
<p dir="ltr">It would be a bit of a weird hack, but we could have _tkagg.so "link" against the tkinter extension module. The idea would be that we don't care about the symbols that the tkinter extension exports, but we'd take advantage on the fact the on ELF, linking against one .so automatically gives you not just its symbols, but also the symbols of all the libraries that it links against, transitively.</p>
<p dir="ltr">This would probably look like:</p>
<p dir="ltr">_tkagg.so has a DT_NEEDED entry naming tkinter.so (or whatever Python calls this module)</p>
<p dir="ltr">Before loading _tkagg.so, we use Python level introspection figure out where tkinter.so lives</p>
<p dir="ltr">We add its directory to LD_LIBRARY_PATH</p>
<p dir="ltr">we import _tkagg.so</p>
<p dir="ltr">We take its directory back off of LD_LIBRARY_PATH</p>
<p dir="ltr">Very weird, but I can't see why it wouldn't work, and probably more reliable than anything where we try to reimplement the dynamic loader's search logic ourselves.</p>
<p dir="ltr">> * If we do discover which libraries Tkinter is using, what would be a<br>
> good way of pulling in these libraries at run-time?<br>
><br>
> Cheers,<br>
><br>
> Matthew<br>
</p>