How is Ruby built?

Note: This is a rant, I'm not actually going to explain anything of use

For a rather long time, I've used clang on my Linux machine as the default value of the $CC environment variable. I've simply found it to be a faster and more friendly compiler to work with than the default gcc.

When I first came to Ruby, I tried building Ruby 1.8.7 with clang and it failed utterly. After bitching on Twitter, as I'm prone to doing, Joe Damato pointed out that Ruby 1.8 isn't really valid C. Instead it is a hodge podge of macros, C code, assembly and tears.

I later found out that Ruby 1.9 seems to cope with being built with clang properly, so I built a couple of 1.9 variants with RVM for my personal projects.

Everything was all fine and good until I tried building a native extension for a 1.9 Ruby:

compiling em.cpp
cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid for C/ObjC but not for C++ [enabled by default]
cc1plus: error: unrecognized command line option ‘-Wshorten-64-to-32’
cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid for C/ObjC but not for C++ [enabled by default]
make: *** [em.o] Error 1

I lost hours trying to figure out what the hell was going on here. I was convinced for hours that EventMachine (the gem being built here) had a bug in it. Then I was convinced that RVM had a bug in it, but I finally landed on Ruby's build system itself.

I should point out that the warning shorten-64-to-32 only exists in patched versions of compilers shipped with Mac OS X. It certainly doesn't exist on any compiler on Linux, so where the hell did this flag come from?

Somehow, and arriving at this "somehow" took me a number of miserable hours, the difference between using clang(1) and gcc(1) to build Ruby resulted in a single nonsense CXXFLAGS value which didn't come back to bite me until I tried to build a native extension.

How the shit does Ruby get built!?

comments powered by Disqus