Creating XCode Projects for SWIG Python-bindings

October 24th, 2008 · 9 Comments · Tutorials

SWIG makes the creation of bindings for C/C++ libraries easy for various high-level exits (Java, Perl, PHP, Python, etc.). However, in the case of Python on OS X, when the actual SWIG wrapper is finished the difficulties begin: one needs to create an adequate dynamic library for the Python runtime — and like with everything in life, the devil is in the details. I attempt to provide some helpful instructions on how to create an XCode project for compiling Python modules. The tutorial is based on XCode 2.4.1 and Python 2.5. The instructions may not be valid for newer versions of XCode / Python.

Some preliminary words on the SWIG documentation regarding this topic: there is a general SWIG tutorial featuring instructions on how to create wrappers for some of the most popular exits. In the case of Python there are special instructions on how to build an adequate dynamic library using command-line tools. Unfortunately, these instructions cover the basics, but are a bit misleading sometimes and leave out some important details. The following step-by-step tutorial should fill in the missing stuff.

The following tutorial uses the openFrameworks (0.04) library as an example. However, the process should be very similar for other libraries.

  1. Create the SWIG wrapper for the library you would like to create a Python-binding from. (On OS X you can use fink to install a command-line SWIG tool; instructions on how to build wrappers are available on the SWIG website.)
  2. Ensure both the SWIG wrapper files and the library source code are in the same directory, so you can easily create an XCode project for them.
  3. If there is an XCode project available for the original C/C++-based library, I suggest that you use this project and create a new target for the Python-binding. Otherwise you should first create an XCode project for the actual library and then attach a binding target to it as both the actual source code and the SWIG wrapper need to be compiled.
  4. Create the target by right-clicking on ‘Targets’ and then choose ‘Add’ » ‘New Target…’. Then select ‘BSD’ » ‘Dynamic Library’ as type of the new target:
    Creating the Target
    Finally provide a name for the target. In this case I have named the target ‘ofpython’.
  5. Now it is time to populate the target with source files and linked frameworks. Simply drag and drop the required source files and linked frameworks from the library target and add the SWIG wrapper source files. In the case of openFrameworks this looks like the following:
    Python Target
  6. As you can see I have added the Python.framework to the ofpython target. You must do so as well by right-clicking the target, then choose ‘Add’ » ‘Existing Frameworks…’ and select the Python.framework from ‘/Library/Frameworks’.
  7. Now let’s talk about the tricky part, target configuration. In order to enable Python to load the compiled module, there are a number of modifications that have to be done. The following is a step by step to-do list of each setting that has to be changed:
    1. Change the Product Name to the library name prefixed with an underscore. That is for the openFrameworks project (which is named ‘openframeworks’ internally) the right product name for the binding is ‘_openframeworks’. This ensures the module can be loaded properly (see discussion on ‘ImportError: dynamic module does not define init function’ issue).
    2. Add adequate Library Search Paths and Header Search Paths if necessary.
    3. Change the Mach-O-Type of the target to ‘Bundle’. (This is roughly discussed in the SwigFaqMaxOSXSharedLibraries also.)
    4. A number of settings have to be changed in order to enable correct linkage with the Bundle Mach-O-Type: firstly deactive ZeroLink. Then set Bundle Loader to the Python runtime (usually ‘/usr/bin/python’). Set CurrentLibraryVersion and Compatibility Version to an empty string as it is not supported with Bundle. Activate Perform Single-Object Prelink. Finally set Executable Prefix to an empty string (erase ‘lib’) and change Executable Extension from ‘dylib’ to ‘so’.
  8. Build the newly configured target.
  9. Finished.

Testing your Python module is easy as well. Just open up a terminal and change to the build directory of the target. Then launch a python shell and type ‘import mymodulename’. Afterwards all functions / classes from the module should be available in the Python environment.

Tags: ····

9 responses so far ↓

  • 1 bartm  Oct 16, 2009 at 3:30 pm

    This was very helpful, thanks. Is there a way to save the settings in step 7 as a template for future xcode projects?

  • 2 Kevin  Aug 18, 2011 at 5:56 am

    You sir, are a gentleman and a scholar. This was an incredibly helpful post.

  • 3 Dupront  Dec 16, 2011 at 3:23 pm

    I am new to swig and xcode.
    I just got an imac.

    I followed the instructions above to
    buid a dynamic library.
    Everything goes fine with xcode.
    But when i run my python script, I got the message

    ImportError: dlopen (path_to_the_library/ no suitable image found. Did find
    path_to_the_library/ mach-o, but wrong architecture

    What should I do now ?
    Thank you for any help!

  • 4 Tobias  Dec 16, 2011 at 10:22 pm

    Dear Dupront,

    you probably built the dynamic library with a different architecture than python is using on your system. Make sure both architectures match. You can find out which architecture your so is by doing file on the command line.

    As you just got your Mac I assume you’re running on OS X 10.7. On my system (10.7) Python runs in 32-bits mode by default. However, if you are using a different Python version, make sure it is built for the architecture you are planning to use. You should then configure your target in Xcode to match that architecture.

    See also:

  • 5 Brittney  Aug 16, 2012 at 10:32 am

    Hey there would you mind stating which blog platform you’re using? I’m looking to start
    my own blog soon but I’m having a hard time selecting between BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your layout seems different then most blogs and I’m looking for something unique.

    P.S My apologies for getting off-topic but I had to ask!

  • 6 Tobias  Aug 17, 2012 at 11:12 pm


    I am using WordPress. I used the cutline theme and adapted it with an override stylesheet. Both WordPress and Cutline are referenced in the blog footer. The cleanest solution for me was to set the class attribute of the html tag, so my personal adaptations are just optional on top of the original cutline theme. If you want to have a look at the CSS, its here:

    Hope this helps!

    PS: Btw. my site is not thought to be used for link building/spamming, so I removed your MySQL hosting link.

  • 7 Landscaping,  Oct 10, 2012 at 7:33 am

    My spouse and I stumbled over here from a different web page and thought I might check things out.
    I like what I see so now i’m following you. Look forward to looking over your web page repeatedly.

  • 8 Fred  Dec 5, 2012 at 11:12 am

    You are so cool! I don’t believe I’ve truly read a single thing like that before.

    So wonderful to discover somebody with a few
    genuine thoughts on this subject. Really.. thanks
    for starting this up. This website is something that is needed on the
    internet, someone with some originality!

  • 9 Cyrus  Jan 15, 2013 at 4:38 pm

    Awesome blog you have here but I was wondering if you knew of any discussion boards that cover
    the same topics discussed here? I’d really like to be a part of online community where I can get suggestions from other experienced individuals that share the same interest. If you have any recommendations, please let me know. Many thanks!

© 2013 Tobis Lensing. All rights reserved. Powered by Wordpress — based upon Cutline by Chris Pearson. This page reflects the personal opinion of the author and is in no way linked to institutions the author is working or has worked for. For more information, see the disclaimer and Privacy Policy.