Monday, October 8, 2012

C, Perl, Swig And Off64_t

On my project at work (called Proton) I've been working on dynamic language bindings, specifically Perl and Ruby. I had previously done the same language bindings for Qpid and so expected the same work would produce the same results in the new code base.

(I think all stories of frustration and despair start out this way, don't they?)

I ran into a stone wall, though, while doing the Perl bindings. Ruby fell into place correctly and I expected the same result with Perl. But I was surprised when, after setting up the Swig file and putting the CMake files into place that I got the error message:

error: unknown type name ‘off64_t’

when I tried to build the Perl bindings. The error wasn't in our code, but referred to code within the Perl distribution itself. After a fruitless day of searching for an answer, and only finding where others had reported similar problems, I felt stumped.

That is, until I hopped into the #perl channel on Freenode and asked other Perl developers there for help. And one guy, named mucker, came to the rescue. So, for anybody who's experience this problem and who has been frustrated trying to find a solution, here you go!

What you need to do is provide the same C compiler flags to your build that were used to build the Perl interpreter itself. To get the flags from the command line, you just do:

perl -MConfig -e "print \$Config{ccflags}"

which will output something like this:

mcpierce@mcpierce-laptop:~ $ perl -MConfig -e "print \$Config{ccflags}"
-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64

Assign that out to an environment variable and pass it into your build environment and your build will work.

And if you're using CMake as we do, you can add the following snippet to your Perl bindings section:
execute_process(COMMAND perl -MConfig -e "print \$Config{ccflags}" OUTPUT_VARIABLE PERLCFLAGS)

set (CMAKE_C_FLAGS ${PERLCFLAGS})
and your build will be just fine!