Tk Framework Double Implementation Issue
Solution 1:
I know I created the bounty, but I got impatient, decided to investigate, and now I've got something that worked for me. I have a very similar python example to yours, which pretty much does nothing other than try to use Tkinter to display an image passed on the command line, like so:
calebhattingh $ python imageview.py a.jpg
objc[84696]: Class TKApplication is implemented inboth/Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. Oneof the two will be used. Which oneis undefined.
objc[84696]: Class TKMenu is implemented inboth/Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. Oneof the two will be used. Which oneis undefined.
objc[84696]: Class TKContentView is implemented inboth/Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. Oneof the two will be used. Which oneis undefined.
objc[84696]: Class TKWindow is implemented inboth/Users/calebhattingh/anaconda/envs/py35/lib/libtk8.5.dylib and/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk. Oneof the two will be used. Which oneis undefined.
Segmentation fault: 11
What's happening is that the binary file, ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL/_imagingtk.so
has been linked to a framework, and not the Tcl/Tk libs in the env. You can see this by using otool
to see the linking setup:
(py35)🎨 ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL
calebhattingh $ otool -L _imagingtk.so
_imagingtk.so:
/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl (compatibility version 8.5.0, current version 8.5.9)
/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk (compatibility version 8.5.0, current version 8.5.9)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
See those two "framework" lines? With anaconda we don't want that. We want to use the libraries in the env. So let's change them!
First make a backup of your binary (in case you want to revert):
$ cp _imagingtk.so _imagingtk.so.bak
Now run this on the command-line (assuming you are in the same folder as your envname/lib
):
$ install_name_tool -change "/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk""@rpath/libtk8.5.dylib" _imagingtk.so
$ install_name_tool -change "/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl""@rpath/libtcl8.5.dylib" _imagingtk.so
You see that @rpath
bit in there? That means whichever one you find on the path. Which works great for anaconda. The linking in the _imagingtk.so
library now looks like this:
(py35)🎨 ~/anaconda/envs/py35/lib/python3.5/site-packages/PIL
calebhattingh $ otool -L _imagingtk.so
_imagingtk.so:
@rpath/libtcl8.5.dylib (compatibility version 8.5.0, current version 8.5.9)
@rpath/libtk8.5.dylib (compatibility version 8.5.0, current version 8.5.9)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
After this, your code will run. Someone should probably try to get this upstream.
Addendum: The Tkinter binding in the python distribution, i.e., the currently-active conda env, has the following linking:
🎨 ~/anaconda/envs/py35/lib/python3.5/lib-dynload
calebhattingh $ otool -L _tkinter.cpython-35m-darwin.so
_tkinter.cpython-35m-darwin.so:
@loader_path/../../libtcl8.5.dylib (compatibility version 8.5.0, current version 8.5.18)
@loader_path/../../libtk8.5.dylib (compatibility version 8.5.0, current version 8.5.18)
/usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 111.0.0)
If you prefer, you can rather use install_name_tool
to use @loader_path/../../
instead of what I used above, i.e. @rpath/
. That will probably also work, and might even be better.
Solution 2:
I try to conduct my own investigation of this problem (in my case that was problem with matplotlib)
- I try to found binaries, linked with System Tcl/Tk Library paths
- With libraries i found file, which seems really interesting. It has name name
osx-tk.patch
and was placed in~/anaconda/pkgs/matplotlib-1.5.1-np111py35_0/info/recipe/
Found
osx-tk.patch
sources into GitHubAfter reading the patch and Conda documentation i became finally convinced about wrong package installation, and i remember, that i used
pip
for matplotlib installation!I deleted old package with
pip
and install new one withconda install matplotlib
command- Now everything started to work like a charm!
Brief summary:
Using pip
package manager with conda environment, i messed my dependencies, because conda may using special recipes, that point installer how to install package correctly in conda virtual environment
Ultra-Brief summary:
Delete package fully with dependencies and install it again with conda package manager (use rebinding only in difficult cases)
Solution 3:
I did exactly what @cjrh said for _imagetk.so
, but instead for _tkinter.so
in ~/anaconda/lib/python3.5/lib-dynload/
and it worked great!
cd ~/anaconda/lib/python3.5/lib-dynload
$ install_name_tool -change "/System/Library/Frameworks/Tk.framework/Versions/8.5/Tk""@rpath/libtk8.5.dylib" _tkinter.so
$ install_name_tool -change "/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl""@rpath/libtcl8.5.dylib" _tkinter.so
Post a Comment for "Tk Framework Double Implementation Issue"