Tools

A Build System for Complex Projects: Part 5

By Gigi Sayfan, November 12, 2009

Testing and extending the ibs build system

Ruby Bindings

A Ruby binding is a dynamic library with a C interface that follows some conventions and uses some special data types and functions from the Ruby C API. The end result is a module that can be consumed by Ruby code.

Here is the C code Bob came up with as a pilot. The "ruby.h" header contains the Ruby C API definitions. The Init_hello_ruby_world() is the entry point that Ruby calls when it loads the binding. This function defines a class called HelloWorld that has two methods called get_hello() and get_world(). The temporary implementation just returns the strings "hello" and "world". The final version will link of course to the C++ "Hello, World!" project and utilize its sophisticated services.

The result was a hello_ruby_world.bundle file, which is the binding itself (a .dll on Windows, and .so on Linux). Now, Bob invited Issac to examine the new toy. Issac, a big Ruby fan, immediately wrote a ruby test program to make sure the binding is indeed usable from Ruby. The program starts with two require statements (the equivalent of import in Python). Note that the first one requires the new binding hello_ruby_world. Next, it creates a test class that subclasses the standard Ruby Test::Unit::TestCase and defines a method instantiates the HelloWorld class from the binding and exercises its methods.

Bob was satisfied and it was time to integrate the new capability to generate Ruby bindings into ibs. The proper way to do it was to figure out how to create a NetBeans project and a VisualStudio project that contain the various incantations hidden in the Ruby-generated Makefile. But Bob was pressed for time and the Ruby binding was really needed just for the Max OS X platform. Consequently, Bob decided to utilize Python's agility and integrate the Ruby binding building as a standalone Python program that will have to be invoked by the developers or build master after the build of the C++ projects was over. I'll shortly discuss how to integrate ibs into a full-fledged automated software development life-cycle.

For starters, he created a standalone piece of code to build Ruby extensions. He assumed the following:

All the Ruby extensions will reside in sub-directories of <root dir>/src/ruby

The name of the extension will be the name of the directory it resides in

The developers will write the C extension code

The program he came up with automated the entire process. For each Ruby extension it: Generated an extconf.rb configuration file from a template (based on the project path); generated a Makefile from the configuration file; and finally created the extension bundle itself by running 'make'. This code demonstrates one of the simplest ways to invoke external processes like 'ruby' and 'make' from Python using the subprocess module. The subprocess.call() function used here doesn't provide a lot of control or interaction with the launched process, but in this case it's enough. The subprocess modules provides multiple ways to launch and interact with launched processes.

The program is based on the build_ruby_binding() function that accepts a project path (the directory that contains the extension's C code) and eventually creates the Ruby bindings bundle in the same directory. The build_all_ruby_bindings() function just iterates over all the sub-directories of the src/ruby directory and calls build_ruby_binding on each one.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!