CSC/ECE 517 Fall 2013/ch1 1w04 y
Use SWIG to improve the performance of Ruby code
Introduction
What is SWIG
SWIG (Simplified Wrapper and Interface Generator) is a tool that allows programmers to mix C/C++ programs and libraries with several dynamic languages, including Tcl, Perl, Python, Ruby,and PHP. It was released in 1995, and the latest version is 2.0.10 which means it is still maintained and used widely.
Why we use SWIG
We all know that computer programming languages can be compiled or interpreted to execute instructions, and these languages can be divided into two basic groups: dynamic and static language.
As far as Ruby is concerned, it is a kind of dynamic language, which is high-level and useful for nearly everything as well as more flexible. On the other hand, Ruby also has many disadvantages as a script language. While using c/c++ code can do a support in many tasks to improve the memory usage and execution speed, we can not help thinking of combine these two kinds of languages and make the best use of them. That’s SWIG’s function, working by taking the declarations found in C/C++ header files and using them to generate the wrapper code that scripting languages need to access the underlying C/C++ code. In addition, SWIG provides a variety of customization features that let you tailor the wrapping process to suit your application. It is designed to work with existing c/c++ code, and turn common C/C++ libraries into components for use in popular scripting languages.
The primary purpose of using SWIG is to simplify the task of integrating c/c++ code with other programing languages, allowing people to focus on the underlying C program and using the high-level language interface, but not the tedious and complex chore of making the two languages talk to each other.
Besides, we can easily write test scripts to our code.
With the help and advantage of SWIG, we can make the program more robust and efficient.
Installation
Windows installation
Please see the dedicated Windows chapter for instructions on installing SWIG on Windows and running the examples. The Windows distribution is called swigwin and includes a prebuilt SWIG executable, swig.exe, included in the top level directory. Otherwise it is exactly the same as the main SWIG distribution. There is no need to download anything else.
Unix installation
You must use GNU make to build and install SWIG.
PCRE needs to be installed on your system to build SWIG, in particular pcre-config must be available. If you have PCRE headers and libraries but not pcre-config itself or, alternatively, wish to override the compiler or linker flags returned by pcre-config, you may set PCRE_LIBS and PCRE_CFLAGS variables to be used instead. And if you don't have PCRE at all, the configure script will provide instructions for obtaining it.
To build and install SWIG, simply type the following:
$ ./configure $ make $ make install
By default SWIG installs itself in /usr/local. If you need to install SWIG in a different location or in your home directory, use the --prefix option to ./configure. For example:
$ ./configure --prefix=/home/yourname/projects $ make $ make install
Note: the directory given to --prefix must be an absolute pathname. Do not use the ~ shell-escape to refer to your home directory. SWIG won't work properly if you do this.
The INSTALL file shipped in the top level directory details more about using configure. Also try
$ ./configure --help.
The configure script will attempt to locate various packages on your machine including Tcl, Perl5, Python and all the other target languages that SWIG supports. Don't panic if you get 'not found' messages -- SWIG does not need these packages to compile or run. The configure script is actually looking for these packages so that you can try out the SWIG examples contained in the 'Examples' directory without having to hack Makefiles. Note that the --without-xxx options, where xxx is a target language, have minimal effect. All they do is reduce the amount of testing done with 'make check'. The SWIG executable and library files installed cannot currently be configured with a subset of target languages.
SWIG used to include a set of runtime libraries for some languages for working with multiple modules. These are no longer built during the installation stage. However, users can build them just like any wrapper module as described in the Modules chapter. The CHANGES file shipped with SWIG in the top level directory also lists some examples which build the runtime library.
Note:
If you checked the code out via Git, you will have to run ./autogen.sh before ./configure. In addition, a full build of SWIG requires a number of packages to be installed. Full instructions at SWIG bleeding edge.
Macintosh OS X installation
SWIG is known to work on various flavors of OS X. Follow the Unix installation instructions above. However, as of this writing, there is still great deal of inconsistency with how shared libaries are handled by various scripting languages on OS X.
Users of OS X should be aware that Darwin handles shared libraries and linking in a radically different way than most Unix systems. In order to test SWIG and run the examples, SWIG configures itself to use flat namespaces and to allow undefined symbols (-flat_namespace -undefined suppress). This mostly closely follows the Unix model and makes it more likely that the SWIG examples will work with whatever installation of software you might have. However, this is generally not the recommended technique for building larger extension modules. Instead, you should utilize Darwin's two-level namespaces. Some details about this can be found here.
A SWIG example
We will take a look at how we can use SWIG with respect to Ruby by using an example to illustrate. We will begin from creating a .c file.
The C code
Here we create a C code file named example.c :
/* File : example.c */ /* Compute the least common multiple of positive integers */ int lcm(int x, int y) { int g; g = y; while (x > 0) { g = x; x = y % x; y = g; } return x * y / g; }
The SWIG interface
Then we create the SWIG interface file example.i:
/* File : example.i */ %module example %inline %{ extern int lcm(int x, int y); %}
Compile the file
Next we should compile the files we have, use the following command(Typically on the Unix System):
$ swig -ruby example.i $ gcc -c -fpic example.c example_wrap.c -I/usr/local/include $ gcc -shared example.o example_wrap.o -o example.so
The swig command produced a new file called example_wrap.c that should be compiled along with the example.c file. Most operating systems and scripting languages now support dynamic loading of modules.
Build the Ruby module
Since we have example.so, the shared object file here, we can next use ruby to access the function and variables declared in the SWIG interface file (You can also use the command line to generate .bundle file to work as the library file of Ruby.).
unix > irb unix > require ‘example’ unix > true unix > Example.lcm(10,45) unix > 90
In our example, our Ruby module has been compiled into a shared library that can be loaded into Ruby.
Also, SWIG Tutorial gives us more examples using other languages, like python,Tcl.
Conclusion
SWIG is a great tool in an amount of sceneries. It can be used to provide a scripting interface to C/C++ code, making it easier for users and add extensions to your Ruby code or replacing existing modules with high-performance alternatives.
References
[2] SWIG Tutorial