Hello_C
Hello_C

Reputation: 51

Compiling and linking C extension for Python in Xcode for Mac

I am trying to compile a simple C extension in Mac to use with Python, and all works well in the command line. Code and gcc command that works are presented below. Now I am trying to build the same extension in Xcode 4.5 (Mac OS10.8), and I tried several target settings for either dylib or static library, but I always get a file that cannot be loaded in Python showing the error:

./myModule.so: unknown file type, first eight bytes: 0x21 0x3C 0x61 0x72 0x63 0x68 0x3E 0x0A

My ultimate target is to create a workspace in XCode with the source code of a C/C++ extension and have python script that calls it in Xcode. So, if I need to debug the C/C++ extension I have XCode debugging capabilities. I am aware that XCode do not debug into Python script, but it can run it, correct ?

gcc -shared -arch i386 -arch x86_64 -L/usr/lib/python2.7 -framework python -I/usr/include/python2.7 -o myModule.so myModule.c -v

#include <Python.h>

/*
 * Function to be called from Python
 */
static PyObject* py_myFunction(PyObject* self, PyObject* args)
{
    char *s = "Hello from C!";
    return Py_BuildValue("s", s);
}   

/*
 * Another function to be called from Python
 */
static PyObject* py_myOtherFunction(PyObject* self, PyObject* args)
{
    double x, y;
    PyArg_ParseTuple(args, "dd", &x, &y);
    return Py_BuildValue("d", x*y);
}

/*
 * Bind Python function names to our C functions
 */
static PyMethodDef myModule_methods[] = {
    {"myFunction", py_myFunction, METH_VARARGS},
    {"myOtherFunction", py_myOtherFunction, METH_VARARGS},
    {NULL, NULL}
};

/*
 * Python calls this to let us initialize our module
 */
void initmyModule()
{
    (void) Py_InitModule("myModule", myModule_methods);
}

Upvotes: 4

Views: 3116

Answers (2)

Jade
Jade

Reputation: 784

I've had success debugging unit-tested C extensions in XCode 4.6 using setuptools, virtualenv, unittest and GDB as the debugger.

I use virtualenvwrapper to create a virtualenv for the project and then set ~/.virtualenvs/module_name/bin/python as the executable to debug.

The single argument to pass to the virtualenv python interpreter in the Run configuration is the path to your test.py.

I then set GDB rather than None as the debugger launching it automatically.

The last step is to pass "setup.py install" as the arguments to your build tool (~/.virtualenvs/module_name/bin/python) on your test target's External Build Tool Configuration pane. The virtualenv provides a fairly simple way for you to install the shared object for your C extension into the test script python interpreter's library path without actually installing it into the global site-packages for your host.

With this setup I can call the extension code from a python script (the ultimate aim) and still debug the C code using XCode's GUI debug support.

If I haven't described this clearly please let me know and I'll share an example project.

Upvotes: 1

Nick ODell
Nick ODell

Reputation: 25259

This guy seems to be having the same problem.

I've figured out the problem. Even though I changed the setting in xcode to specify output type "dynamic library" or "bundle", xcode was ignoring the setting. Starting a new BSD dynamic library project solved the issues I was seeing. Thanks for the help!

Upvotes: 4

Related Questions