If it won't be simple, it simply won't be. [Hire me, source code] by Miki Tebeka, CEO, 353Solutions

Tuesday, April 24, 2007

Auto building C extension

Not as good as Perl's inline module, however this little tricks will build the C extension the 1'st time the module is loaded. (Works on Linux, probably on Mac and Windows with development tools installed)

Let's call our module autobuild, the in the autobuild directory we'll have:

__init__.py

def _build():
from os.path import getmtime, isfile, dirname, join
from sys import executable
from os import system

from setup import DYNLIB, SRC_FILE

MODULE_DIR = dirname(__file__)

def _run(cmd):
return system("(cd \"%s\" && %s) > /dev/null 2>&1" % (MODULE_DIR, cmd))

_full_src = join(MODULE_DIR, SRC_FILE)
_full_dynlib = join(MODULE_DIR, DYNLIB)

if (not isfile(_full_dynlib)) or (getmtime(_full_dynlib) < getmtime(_full_src)):
assert _run("%s setup.py build_ext -i" % executable) == 0, "build error"

_build()
del _build
from _greet import *

setup.py


from distutils.core import Extension, setup

MODULE_NAME = "_greet"
DYNLIB = MODULE_NAME + ".so"
SRC_FILE = MODULE_NAME + ".c"

if __name__ == "__main__":
setup(ext_modules=[Extension(MODULE_NAME, [SRC_FILE])])

_greet.c

#include <python.h>
#include <stdio.h>

static PyObject *
greet_greet(PyObject *self, PyObject *args)
{
char *name;

if (!PyArg_ParseTuple(args, "s", &name)) {
return NULL;
}

printf("Hello %s\n", name);

return Py_BuildValue("");
}

static PyMethodDef GreetMethods[] = {
{ "greet", greet_greet, METH_VARARGS,
"Print a friendly greeting."
},
{NULL, NULL, 0, NULL} /* Sentinel */
};

PyMODINIT_FUNC
init_greet(void)
{
Py_InitModule("_greet", GreetMethods);
}

No comments:

Blog Archive