Bare-bones embedding Ruby 1.9 in C++

tung's picture

So I never have waste time trying to figure this out again, here's how to embed the current Ruby 1.9 into a basic C++ program.

1. Install Ruby 1.9

I'm running Arch Linux, so I can install the ruby1.9 package from AUR.

yaourt -S ruby1.9

2. Write the C++ code

This should be roughly identical to main.c in the Ruby source code.

// main.cpp
#include <ruby.h>
 
RUBY_GLOBAL_SETUP
 
int main(int argc, char *argv[])
{
    ruby_sysinit(&argc, &argv);
    {
        RUBY_INIT_STACK;
        ruby_init();
        return ruby_run_node(ruby_options(argc, argv));
    }
}

This took a lot of trawling over the intertubes and chasing red herrings. It's here so that you need not suffer my pain.

3. Compile against Ruby headers

For some reason, the Ruby 1.9 headers are in 3 places, instead of Ruby 1.8's 1 place.

c++ -I/opt/ruby1.9/include/ruby-1.9.1/i686-linux \
    -I/opt/ruby1.9/include/ruby-1.9.1/ruby/backward \
    -I/opt/ruby1.9/include/ruby-1.9.1 \
    -c main.cpp

Replace "c++" with your compiler (for me it's "g + +").

4. Link against the Ruby library

c++ -L/opt/ruby1.9/lib -lruby -o main main.o

5. Try it out

The final binary should work almost identically to the Ruby 1.9 interpreter actual.

LD_LIBRARY_PATH=/opt/ruby1.9/lib ./main -e '5.times { puts "BOO" }'
BOO
BOO
BOO
BOO
BOO

6. Warning!

Ruby as a whole seems to be very sketchy on the docs. I remember matz himself saying that Ruby wasn't intended to be embedded, and that there was no formal embedding protocol. However, that message was from quite a while ago, and I'm not sure if it still applies.

Also, docs on Ruby on the Internet tend to become obsolete very quickly. This post is from mid-2009, for the record. ruby_exec and ruby_run, used in some posts online about embedding Ruby, don't seem to exist in Ruby 1.9.