Problem with C library linked to Python interpreter, on Mac OS X - python

I'm trying to use a C library that is supposed to be available from Python. The library compiles fine on Mac OS X (10.6.0, i386) with GCC (version: i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659).
When I try to import the python module from python, I get the error:
$ python
Enthought Python Distribution -- www.enthought.com
Version: 7.0-2 (64-bit)
Python 2.7.1 |EPD 7.0-2 (64-bit)| (r271:86832, Dec 3 2010, 15:56:20)
[GCC 4.0.1 (Apple Inc. build 5488)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>> import mymodule
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule/__init__.py", line 2, in <module>
from mymodule import *
ImportError: dlopen(/Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule/mymodule.so, 2): Symbol not found: _b_char
Referenced from: /Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule/mymodule.so
Expected in: flat namespace
in /Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule/mymodule.so
To respond to Ned's questions, this is the output I get:
$ file $(python -c 'import sys;print(sys.executable)')
/Library/Frameworks/EPD64.framework/Versions/Current/bin/python: Mach-O 64-bit executable x86_64
$ python -c 'import sys;print(sys.maxsize > 2**32)' ;
True
$ cd /Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule
$ file mymodule.so
mymodule.so: Mach-O 64-bit bundle x86_64
$ otool -L mymodule.so
mymodule.so:
/usr/local/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 125.2.1)
$ file /usr/lib/libSystem.B.dylib
/usr/lib/libSystem.B.dylib: Mach-O universal binary with 3 architectures
/usr/lib/libSystem.B.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
/usr/lib/libSystem.B.dylib (for architecture i386): Mach-O dynamically linked shared library i386
/usr/lib/libSystem.B.dylib (for architecture ppc7400): Mach-O dynamically linked shared library ppc
$ file /usr/local/lib/libgcc_s.1.dylib
/usr/local/lib/libgcc_s.1.dylib: Mach-O universal binary with 4 architectures
/usr/local/lib/libgcc_s.1.dylib (for architecture i386): Mach-O dynamically linked shared library i386
/usr/local/lib/libgcc_s.1.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
/usr/local/lib/libgcc_s.1.dylib (for architecture ppc): Mach-O dynamically linked shared library ppc
/usr/local/lib/libgcc_s.1.dylib (for architecture ppc64): Mach-O 64-bit dynamically linked shared library ppc64
It seems that there's a common architecture, but I'm unsure about whether that's true for the libraries references by otool -L -- those seem to have multiple versions.
Another thing I noticed is that when I make this package and compile it and then make the Python module, the "build" directory of the module (i.e. the directory at the same level as the setup.py file) has these Mac OS X 10.5 files:
$ cd build/
$ ls
lib.macosx-10.5-x86_64-2.7 temp.macosx-10.5-x86_64-2.7
However, I am using Mac OS X 10.6. What controls which version is used to compile a Python package using distutils? I'm afraid this might be causing the problem.
Any idea what could be causing this? Thanks.

It is hard to know exactly what the problem is without more information but it appears you are using a 64-bit version of Python (from EPD). Is the library that you built also built as a 64-bit library? You should be able to tell by doing something like this:
file $(python -c 'import sys;print(sys.executable)') # see archs that Python was built with
python -c 'import sys;print(sys.maxsize > 2**32)' ; # see if running as 64-bit (false if 32-bit)
cd /Library/Frameworks/EPD64.framework/Versions/7.0/lib/python2.7/site-packages/mymodule
file mymodule.so # see what architectures the C extension module is built with
otool -L mymodule.so # see what libraries are referenced by the C extension module
file /path/to/lib1 # see what archs the referenced lib module(s) are built with
There needs to be a common arch among all of them.
Update: Based on your additional information, the most suspicious looking item is the library reference to /usr/local/lib/libgcc_s.1.dylib. That would seem to indicate you have a local copy of gcc or other compiler installed in /usr/local. Are you sure you aren't mixing compilers here? Try cleaning the build directory and explicitly setting export CC=/usr/bin/gcc-4.0 before building your module. Or move that other compiler out of /usr/local. (The 10.5 thing should not be an issue. That just indicates that the EPD Python distribution was built to run on 10.5 and later systems.)

Related

Undefined symbol when importing Python Sybase module on OSX 10.6

I'm trying to get the python-sybase module working on OSX 10.6, but I've run into a bit of a snag.
When I do
import Sybase
I get
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "Sybase.py", line 15, in <module>
from sybasect import *
ImportError: dlopen(/Library/Python/2.6/site-packages/python_sybase-0.40pre2-py2.6-macosx-10.6-universal.egg/sybasect.so, 2): Symbol not found: _blk_alloc
Referenced from: /Library/Python/2.6/site-packages/python_sybase-0.40pre2-py2.6-macosx-10.6-universal.egg/sybasect.so
Expected in: flat namespace
in /Library/Python/2.6/site-packages/python_sybase-0.40pre2-py2.6-macosx-10.6-universal.egg/sybasect.so
I took a look at sybasect.so, and sure enough, _blk_alloc is undefined. The function is located in Sybase's sybblk.dylib, which is installed, and its containing directory is in LD_LIBRARY_PATH.
When I compiled python-sybase using python setup.py build, the gcc command appears to find all of the right libs correctly, but for some reason those libs don't appear to be linked after installing sybasect.so to the Python module dir.
The gcc command is
gcc-4.2 -Wl,-F. -bundle -undefined dynamic_lookup -arch i386 -arch ppc -arch x86_64 build/temp.macosx-10.6-universal-2.6/blk.o build/temp.macosx-10.6-universal-2.6/databuf.o build/temp.macosx-10.6-universal-2.6/cmd.o build/temp.macosx-10.6-universal-2.6/conn.o build/temp.macosx-10.6-universal-2.6/ctx.o build/temp.macosx-10.6-universal-2.6/datafmt.o build/temp.macosx-10.6-universal-2.6/iodesc.o build/temp.macosx-10.6-universal-2.6/locale.o build/temp.macosx-10.6-universal-2.6/msgs.o build/temp.macosx-10.6-universal-2.6/numeric.o build/temp.macosx-10.6-universal-2.6/money.o build/temp.macosx-10.6-universal-2.6/datetime.o build/temp.macosx-10.6-universal-2.6/date.o build/temp.macosx-10.6-universal-2.6/sybasect.o -L/Applications/Sybase/System/OCS-15_0/lib -lsybblk -lsybct -lsybcs -lsybtcl -lsybcomn -lsybintl -lsybunic -o build/lib.macosx-10.6-universal-2.6/sybasect.so
The -L/Applications/Sybase/System/OCS-15_0/lib location is correct, and that folder contains all of the right .dylib's.
When I run otool the output is:
$ otool -L build/lib.macosx-10.6-universal-2.6/sybasect.so
build/lib.macosx-10.6-universal-2.6/sybasect.so:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.11)
I was expecting to see the Sybase libs in there.
I'm a little new to linking on Mac. How do I ensure that sybasect.so references the Sybase libs?
Fixed it.
The problem was that the various Sybase libraries I was linking to were 32-bit only, but I was running Python in 64 bit mode. The fix was just running python in 32-bit mode.
I used the command defaults write com.apple.versioner.python Prefer-32-Bit -bool yes since I don't have any particular need for 64 bit mode.

How to use opencv with python on macos

I am porting a python+opencv app developped on windows to mac.
On windows i have the cv2.pyd in my virtualenv site-packages and it goes well.
I am new to mac and I don't understand hot it should work. I didn't find any binaries for opencv python bindings and it seems that the rightway is to use macport.
macport is copying the cv.py and cv2.so in the opts/.../site-packages.
At this point how to use it?
I tried to copy manually these two files but I am getting an error
>>> import cv
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/cv.py", line 1, in <module>
from cv2.cv import *
ImportError: dlopen(/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/cv2.so, 2): no suitable image found. Did find:
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/cv2.so: mach-o, but wrong architecture
What's wrong?
Update:
As asked by #Vortexfive:
$ file /Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/cv2.so
/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/cv2.so: Mach-O 64-bit dynamically linked shared library x86_64
$ file /Library/Frameworks/Python.framework/Versions/2.6/bin/python
/Library/Frameworks/Python.framework/Versions/2.6/bin/python: Mach-O universal binary with 2 architectures
/Library/Frameworks/Python.framework/Versions/2.6/bin/python (for architecture ppc): Mach-O executable ppc
/Library/Frameworks/Python.framework/Versions/2.6/bin/python (for architecture i386): Mach-O executable i386
It seems there is a mismatch. How to fix it?
It seems there's a mismatch in target architectures. You can try to install opencv in macports with the +universal variant.
Another option is to update your version of Python. Newer versions are compiled for x86_64 too I believe.
As a third alternative you can install opencv with the +python27 in macports. You can then select the macports version of Python by doing sudo port select python27.
In my case, which the arch is matched:
$ file ../../release.mac/lib/cv2.so
../../release.mac/lib/cv2.so: Mach-O 64-bit dynamically linked shared library x86_64
$ file `which python`
/usr/bin/python: Mach-O universal binary with 2 architectures
/usr/bin/python (for architecture x86_64): Mach-O 64-bit executable x86_64
/usr/bin/python (for architecture i386): Mach-O executable i386
But not aware that the python run in 32 bit mode:
$ defaults read com.apple.versioner.python Prefer-32-Bit
1
Fixed by:
$ VERSIONER_PYTHON_PREFER_32_BIT=0 python
or
$ defaults write com.apple.versioner.python Prefer-32-Bit -bool no

Forcing 32 bit Python on MAC 10.7 or 10.8

I have MAC OS X 10.8 and i have updated my python to version 2.7.3 using Python's official binary from their website.
I am trying to run a python script which needs to be executed using 32 bit python.
How can i force to run 32-bit python instead of 64-bit?
Command file /usr/bin/python gives me following output.
Alis-Mac:~ ali$ file /usr/bin/python
/usr/bin/python: Mach-O universal binary with 2 architectures
/usr/bin/python (for architecture i386): Mach-O executable i386
/usr/bin/python (for architecture x86_64): Mach-O 64-bit executable x86_64
I have also tried the following.
export VERSIONER_PYTHON_PREFER_32_BIT=yes
But this has not even helped because now, i have custom python i guess.
My script has wxpython code in it and i am building app for OSX using platypus so, i have to force my script to run with 32-bit python. Please help.
for now install virtualbox and develop your app in a 32Bit Ubuntu
you can also install pycharm which can allow you to debug through vagrant

"no matching architecture in universal wrapper" problem in wxPython?

I am running Python 2.7 under Mac OS 10.6.4, and I just installed wxPython from the wxPython2.8-osx-unicode-2.8.11.0-universal-py2.7.dmg binary. I am getting a weird error on the import wx line in my Python scripts. FYI, I can import the wx module just fine from PyCrust. I don't really see what I have done wrong here. Could anyone please assist?
File "prod_cons_wx.py", line 6, in <module>
import wx
File "/usr/local/lib/wxPython-unicode-2.8.11.0/lib/python2.7/site-packages/wx-2.8-mac-unicode/wx/__init__.py", line 45, in <module>
from wx._core import *
File "/usr/local/lib/wxPython-unicode-2.8.11.0/lib/python2.7/site-packages/wx-2.8-mac-unicode/wx/_core.py", line 4, in <module>
import _core_
ImportError: dlopen(/usr/local/lib/wxPython-unicode-2.8.11.0/lib/python2.7/site-packages/wx-2.8-mac-unicode/wx/_core_.so, 2): no suitable image found. Did find:
/usr/local/lib/wxPython-unicode-2.8.11.0/lib/python2.7/site-packages/wx-2.8-mac-unicode/wx/_core_.so: no matching architecture in universal wrapper
It appears that C extension modules included with the wxPython 2.7 dmg here are 32-bit only.
$ cd /usr/local/lib/wxPython-unicode-2.8.11.0/lib/python2.7/site-packages/wx-2.8-mac-unicode/wx
$ file *.so
_animate.so: Mach-O universal binary with 2 architectures
_animate.so (for architecture ppc): Mach-O bundle ppc
_animate.so (for architecture i386): Mach-O bundle i386
_aui.so: Mach-O universal binary with 2 architectures
_aui.so (for architecture ppc): Mach-O bundle ppc
_aui.so (for architecture i386): Mach-O bundle i386
...
Unfortunately, platform.architecture() does not give an accurate indication of which arch an OS X multiple architecture Python is running in. For example, using the 3-arch python.org installer for Python 2.7, platform.architecture() always reports 64-bit even when running in 32-bit mode:
$ cd /Library/Frameworks/Python.framework/Versions/2.7
$ file python2.7
python2.7: Mach-O universal binary with 3 architectures
python2.7 (for architecture i386): Mach-O executable i386
python2.7 (for architecture ppc7400): Mach-O executable ppc
python2.7 (for architecture x86_64): Mach-O 64-bit executable x86_64
$ arch -x86_64 ./python2.7 -c 'import platform, sys; print "{0}, {1:x}".format(platform.architecture()[0], sys.maxint)'
64bit, 7fffffffffffffff
$ arch -i386 ./python2.7 -c 'import platform, sys; print "{0}, {1:x}".format(platform.architecture()[0], sys.maxint)'
64bit, 7fffffff
$ arch -ppc ./python2.7 -c 'import platform, sys; print "{0}, {1:x}".format(platform.architecture()[0], sys.maxint)'
64bit, 7fffffff
The reliable way is to examine sys.maxint for Python 2 or sys.maxsize for Python 3.
You don't indicate in your question how you invoke Python. Is it via a shebang line in a script file? If so, you may not be running the Python you think you are. Also, you don't indicate which Python 2.7 you have installed. For instance, there are currently two installers for Python 2.7 from python.org: one supports both 32- and 64-bit execution, the other is 32-bit only. Try the following:
$ file $(python2.7 -c 'import sys;print(sys.executable)')
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python: Mach-O universal binary with 3 architectures
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python (for architecture i386): Mach-O executable i386
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python (for architecture ppc7400): Mach-O executable ppc
/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python (for architecture x86_64): Mach-O 64-bit executable x86_64
So: if you have a multi-arch version of Python, you'll need to force it to run in 32-bit mode to make use of the pre-compiled wxPython.
Just to clarify 'Ned Deily's' suggestion re: use arch -i386 python2.7 script.py to run in 32-bit mode. The exact command line is arch -i386 python pywrap spare.py. This will allow you to run PyCrust (in 32-bit mode on OSX 10.6.x).
There are two files for 32bit system, python2.7-32 and pythonw2.7-32.
You can use these two files to run your script.
I link python to the python2.7-32 and link pythonw to the pythonw2.7-32.
My scripts all are working well.
you can try.
There's now a developmental release with 64-bit Cocoa support at http://downloads.sourceforge.net/wxpython/wxPython2.9-osx-2.9.4.0-cocoa-py2.7.dmg found at this page: http://www.wxpython.org/download.php#stable
That worked for me.
How have you installed python on Snow Leopard OSX (10.6) Series?
Is your python compiled for 64 bit or 32 bit.
Try doing the following:
import platform
print platform.architecture()
Check out if the binary (wxpython dmg) was compiled for 32 or 64 bit.
You might have to look for a package that is compatible with your architecture or you might have to compile from source on your machine.
I would suggest that you use macports.
install macports from macport.org
sudo /opt/local/bin/port install python27
sudo /opt/local/bin/port install python_select
sudo /opt/local/python_select python27
sudo /opt/local/bin/port install py27-wxpython
and this should work for you!

How to force using 64 bit python on Mac OS X?

I got the following error when compiling sip with --arch x86_64 option.
prosseek:siplib smcho$ python -c 'import sip; print sip'
Traceback (most recent call last):
File "", line 1, in
ImportError: dlopen(./sip.so, 2): no suitable image found. Did find:
./sip.so: mach-o, but wrong architecture
I found that the prebuilt Mac OS X python (snow leopard) is universal, and it doesn't get the 64 bit library. I guess it's running on 32bit mode.
file /usr/bin/python
/usr/bin/python: Mach-O universal binary with 3 architectures
/usr/bin/python (for architecture x86_64): Mach-O 64-bit executable x86_64
/usr/bin/python (for architecture i386): Mach-O executable i386
/usr/bin/python (for architecture ppc7400): Mach-O executable ppc
prosseek:siplib smcho$ file sip.so
sip.so: Mach-O 64-bit bundle x86_64
How can I force python to run on 64bit mode? When I run the same code on Textmate, there's no problem. So, I think Textmate should run on 64 bit mode anyway.
Added
This link shows how to identify if a python that I'm running is 32bit or 64bit. And I checked my python is 32 bit.
This link shows how to make 32/64bit python. But it doesn't work for me.
Try using arch(1), and supply the specific version of Python:
arch -x86_64 /usr/bin/python2.6
Actually the system should choose the first suitable architecture for you. As
$ file /usr/bin/python2.5
/usr/bin/python2.5: Mach-O universal binary with 2 architectures
/usr/bin/python2.5 (for architecture i386): Mach-O executable i386
/usr/bin/python2.5 (for architecture ppc7400): Mach-O executable ppc
$ file /usr/bin/python2.6
/usr/bin/python2.6: Mach-O universal binary with 3 architectures
/usr/bin/python2.6 (for architecture x86_64): Mach-O 64-bit executable x86_64
/usr/bin/python2.6 (for architecture i386): Mach-O executable i386
/usr/bin/python2.6 (for architecture ppc7400): Mach-O executable ppc
If that python somehow chooses 2.5, then you can't use 64-bit, but if it chooses 2.6 then the x86_64 variant should be automatically selected, as commented below. If it's the former, try to get python_select and change the version to 2.6.
Okay, be REALLY careful when you do this, it's going to require other things to also be 64-bit. All of a sudden, if mod_python won't work, then you need to recompile apache. Then all your python modules like tkinter/tix. If you're on 10.5 like me, don't go there, just live with 32-bit for it.
And if you don't know about http://www.macports.org/ then remember that it's your friend. :-)

Categories