Building with Scons and an optional SWIG

I now regularly use Scons as a cross-platform software construction tool. It is easy, written in Python, and I know Python, so no problem learning a new language as for CMake. In some cases when I use SWIG, the target platform does not have the SWIG executable. But when compiling a module, Scons must use this executable, whatever you try to do. In this case, one need to create a new SharedLibrary builder, so that this attribute will determine if SWIG is present or if the generated .c or .cpp files must be used instead.

As the modules I try to create are shared libraries, I have to modify the SharedLibrary builder defined in env[‘BUILDERS’][‘SharedLibrary’]. A decorator will do the trick :

  1. import re
  2. import os.path
  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.cpp', 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.   cat=env.BeforeSWIGSharedLibrary(library, sourcesbis, **args)
  20.   return cat
  21.  
  22. env['BUILDERS']['BeforeSWIGSharedLibrary'] = env['BUILDERS']['SharedLibrary']
  23. env['BUILDERS']['SharedLibrary'] = SWIGSharedLibrary

Here, the new SharedLibrary builder is the SWIGSharedLibrary function. This function determines first if SWIG is present. If it is, nothing is done and the shared library is built as usual. If it is not, the corresponding _wrap.c or _wrap.cpp must be present. This is what the regular expression will do. Then, depending on which file is present, it is added to the sources list.Note that if the regular expression did not match, the name of the file is not modified, so other files than the *.i files are added to the sources list directly.

Finally, the function calls a method named BeforeSWIGSharedLibrary() which will be the previous SharedLibrary builder. This change of name and the actual registration of the new SharedLibrary builder is done with the last two lines.

A final note on this is that the created _wrap.* files must be compilable on the Windows platform. If the source file was created by SWIG under Linux and that specific functions are used under Linux and not Windows, the compilation may fail.

3 thoughts on “Building with Scons and an optional SWIG”

Leave a Reply