Monday, June 27, 2011

Forcing have_header to properly handle C++ header files...

The Problem

In working on the Qpid Ruby bindings, I've decided to keep on as proper a path as possible with the environment. So part of that is to have the gem's installation verify that the header files necessary to build the native libraries are present.

But that right away became a problem, since the underly Qpid code is written in C++ and, by default, Ruby's native extensions default to using C. So when, in extconf.rb, the code attempts to verify certain headers from Qpid that themselves depend on C++ headers the verification would "fail" since C can't find those headers.

For example, in qpid/messaging/Address.h there's an include for the string header in C++:

#include <string>

In mkmf Ruby attempts to validate that qpid/messaging/Address.h is present by creating a temporary c program that has:

/* begin */
#include <qpid/messaging/Address.h>
/* end */

Inside of Address.h there is:

#include <string>

and while GCC is compiling the the temporary sources the preprocessor choke son the above include and Ruby decides that Address.h doesn't exist.

The Solution

To force Ruby to use your C++ compiler to validate headers as well, simply use:

$CFLAGS = "-x c++"

or else add:

with_cflags("-x c++")

depending on which way you prefer to defined the compiler flags. Once you do that, C++ will be used to verify headers and libraries.

And if you're using C++ for your Ruby extensions then that's what you'd want to do anyway.