December 14th 2007

Creating a Python module with Scons and SWIG

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...Loading...

Some times ago, I proposed an optional build for SWIG if the SWIG binary was not found on the system. Here I propose an enhancement, a new library builder that will be registered in the environment env as PythonModule. It takes the same arguments as a classical SharedLibrary, but it does some additional steps :

  • It forces SWIG to create a Python wrapper (flag -python)
  • It checks if SWIG is present at all
  • It suppresses every prefix that the system might need (as lib in Linux)
  • On Windows and for Python >= 2.5, it changes the extension as pyd


Here is the code :

  1. import re
  2. import sys
  3.  
  4. def SWIGSharedLibrary(env, library, sources, **args):
  5.   swigre = re.compile('(.*).i')
  6.   if env.WhereIs('swig') is None:
  7.     sourcesbis = []
  8.     for source in sources:
  9.       cName = swigre.sub(r'\1_wrap.c', source)
  10.       cppName = swigre.sub(r'\1_wrap.cc', source)
  11.       if os.path.exists(cName):
  12.         sourcesbis.append(cName)
  13.       elif os.path.exists(cppName):
  14.         sourcesbis.append(cppName)
  15.       else:
  16.         sourcesbis.append(source)
  17.   else:
  18.     sourcesbis = sources
  19.  
  20.   if 'SWIGFLAGS' in args:
  21.     args['SWIGFLAGS'] += ['-python']
  22.   else:
  23.     args['SWIGFLAGS'] = ['-python'] + env['SWIGFLAGS']
  24.   args['SHLIBPREFIX']=""
  25.   if sys.version >= '2.5':
  26.     args['SHLIBSUFFIX']=".pyd"
  27.  
  28.   cat=env.SharedLibrary(library, sourcesbis, **args)
  29.   return cat
  30.  
  31. env['BUILDERS']['PythonModule'] = SWIGSharedLibrary

Once registered, a new SWIG module named mymodule can be created with :

env.PythonModule('_mymodule', ['myfile.i', 'myfile.c'])
Tags: , , ,

4 Comments »

4 Responses to “Creating a Python module with Scons and SWIG”

  1. Mark Gritter on 25 Jun 2008 at 3:44 AM #

    I’m a bit confused at registering a python function directly as a Builder, instead of creating a custom Builder with an action or generator. I’d like to do something similar (so I can use other builders like you use env.SharedLibrary), but I’m not sure this is a supported usage… What exactly goes on here?

  2. Matt on 25 Jun 2008 at 6:58 AM #

    In fact, the real builder is still SharedLibrary for SCons. What I do is preprocess the sources in case SWIG is not available (I change .i for _wrap.c or _wrap.cc), and then I add ‘-python’ so that swig really understands it has to create a Python module. Finally, I change the library suffix and prefix if needed before I call the real builder, SharedLibrary.

  3. Nick on 27 Apr 2010 at 12:56 AM #

    When cleaning, doesn’t seem to remove the objects that build the _mymodule.pyd.

  4. Matt on 27 Apr 2010 at 5:09 PM #

    Thanks for the report, I’ll check this.
    It’s surprising though, as the only thing I do is to decorate the SharedLibrary function.

Trackback URI | Comments RSS

Leave a Reply

« | »

  • Blog Vitals

    Blog Stats
    7,451,893
    189
    208
    42
  • Advertisement