Problem with C library linked to Python interpreter, on Mac OS X
Question: 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.


Answer: 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.)

