Tags : FBuild : December 2009
Example python extension builder
posted on December 30, 2009 - 02:03 PM PST
by Erick Tryzelaar
filed under:
FBuild
Holger on the fbuild mailing list was trying to use fbuild to create python c extensions, so I mocked up a simple builder for him. There's a little work looking up the include directory, and I'm hardcoding the gcc option "-undefined dynamic_lookup", but once done it's pretty simple:
import fbuild.builders.c
import fbuild.db
import fbuild.path
@fbuild.db.caches
def python_c_builder(ctx, python='python'):
"""Creates and returns a python C extension builder."""
# If we didn't explicitly chose which version of python to use, search the
# environment for python.
python = fbuild.builders.find_program(ctx, [python])
# Create a helper program that calls out to python to get the include and
# lib directories.
stdout, stderr = ctx.execute([python, '-c',
'import distutils.sysconfig; '
'print(distutils.sysconfig.get_python_inc())'],
quieter=1)
includepath = stdout.decode().strip()
# Return a fully specified python c extension builder.
return fbuild.builders.c.guess_shared(ctx,
includes=[includepath],
flags=['-undefined', 'dynamic_lookup'],
lib_prefix='',
lib_suffix='.so')
def build(ctx):
for python in ('python', 'python2.5', 'python2.6', 'python3.1'):
# Configure the python.
shared = python_c_builder(ctx, python)
# Copy the src file so we don't have collisions.
fbuild.path.Path('build/%s' % python).makedirs()
fbuild.path.Path('spam.c').copy('build/%s' % python)
# Build the extension module.
shared.build_lib('%s/spam' % python, ['build/%s/spam.c' % python])
# Test if we can actually import the module.
ctx.execute([python, '-c', 'import spam; spam.system("echo hello world!")'],
cwd='build/%s' % python)
Which results in:
looking for program python : ok /opt/local/bin/python
determining platform : {'bsd', 'darwin', 'macosx', 'posix'}
looking for program gcc : ok /usr/bin/gcc
checking gcc : ok
checking gcc with -g : ok
checking gcc with -O2 : ok
checking gcc with -undefined dynamic_lookup -fPIC: ok
checking gcc with -undefined dynamic_lookup -dynamiclib: ok
checking gcc with -undefined dynamic_lookup: ok
checking if gcc -undefined dynamic_lookup -fPIC can make objects: ok
checking if gcc -undefined dynamic_lookup -fPIC can make libraries: ok
checking if gcc -undefined dynamic_lookup -fPIC can make exes: ok
checking if gcc -undefined dynamic_lookup -fPIC can link lib to exe: ok
* gcc -undefined dynamic_lookup -fPIC : build/python/spam.c -> build/python/spam.os
* gcc -undefined dynamic_lookup -dynamiclib: build/python/spam.os -> build/python/spam.so
hello world!
looking for program python2.5 : ok /opt/local/bin/python2.5
checking gcc : ok
checking gcc with -g : ok
checking gcc with -O2 : ok
checking gcc with -undefined dynamic_lookup -fPIC: ok
checking gcc with -undefined dynamic_lookup -dynamiclib: ok
checking gcc with -undefined dynamic_lookup: ok
checking if gcc -undefined dynamic_lookup -fPIC can make objects: ok
checking if gcc -undefined dynamic_lookup -fPIC can make libraries: ok
checking if gcc -undefined dynamic_lookup -fPIC can make exes: ok
checking if gcc -undefined dynamic_lookup -fPIC can link lib to exe: ok
* gcc -undefined dynamic_lookup -fPIC : build/python2.5/spam.c -> build/python2.5/spam.os
* gcc -undefined dynamic_lookup -dynamiclib: build/python2.5/spam.os -> build/python2.5/spam.so
hello world!
looking for program python2.6 : ok /opt/local/bin/python2.6
* gcc -undefined dynamic_lookup -fPIC : build/python2.6/spam.c -> build/python2.6/spam.os
* gcc -undefined dynamic_lookup -dynamiclib: build/python2.6/spam.os -> build/python2.6/spam.so
hello world!
looking for program python3.1 : ok /opt/local/bin/python3.1
checking gcc : ok
checking gcc with -g : ok
checking gcc with -O2 : ok
checking gcc with -undefined dynamic_lookup -fPIC: ok
checking gcc with -undefined dynamic_lookup -dynamiclib: ok
checking gcc with -undefined dynamic_lookup: ok
checking if gcc -undefined dynamic_lookup -fPIC can make objects: ok
checking if gcc -undefined dynamic_lookup -fPIC can make libraries: ok
checking if gcc -undefined dynamic_lookup -fPIC can make exes: ok
checking if gcc -undefined dynamic_lookup -fPIC can link lib to exe: ok
* gcc -undefined dynamic_lookup -fPIC : build/python3.1/spam.c -> build/python3.1/spam.os
* gcc -undefined dynamic_lookup -dynamiclib: build/python3.1/spam.os -> build/python3.1/spam.so
hello world!
I should be able to get a prototype builder out soon.