Search code examples
macosshared-librariessetuptoolsdistutilspython-c-extension

How to create a .dylib C extension on mac os x with distutils and/or setuptools?


I need to make a C extension with distutils (and/or setuptools) that can be used BOTH dynamically at runtime, and at compile time (for different purposes). This isn't a problem on Linux, but it's an issue on OS X. By default, distutils creates a "bundle" on OS X (and names it .so), which can be used at runtime, but NOT at compile time. I need to make a .dylib, which can be linked to at compile time, and I need to do it within a setup.py that I can package for PyPI.

No matter what I try, distutils keeps creating a bundle, and when I try to link against this library, I get an error. You can check explicitly whether distutils created a bundle or dynamically linked library by using file on the command line:

file libA.so
libA.so: Mach-O 64-bit bundle x86_64

The following cc command gives me what I want:

cc -fPIC -shared source1.o source2.o -o libA.so
file libA.so
libA.so: Mach-O 64-bit dynamically linked shared library x86_64

Solution

  • Here's what worked for me (added lines in my setup.py):

    if sys.platform == 'darwin':
        from distutils import sysconfig
        vars = sysconfig.get_config_vars()
        vars['LDSHARED'] = vars['LDSHARED'].replace('-bundle', '-dynamiclib')
    

    This configuration seems to be hard-wired in the module _sysconfigdata. It's also overridable using environment variables, so this works as well:

    LDSHARED="cc -dynamiclib -undefined dynamic_lookup -arch x86_64 -arch i386 -Wl,-F." python setup.py install