Chapter 2. Building from Source Code

Table of Contents
The Basics
Things That Can Go Wrong

If you're planning to use FXRuby on Windows, with the standard Cygwin-based Ruby installation for Windows, you may wish to just download the pre-compiled FXRuby binaries. Otherwise, you will need to compile the shared library for FXRuby from the source code.

The Basics

These instructions assume that you've already downloaded, compiled and installed FOX. Next, you'll need to download the FXRuby source code tarball and unpack it by typing:

$ tar xzf FXRuby-0.99.173.tar.gz

This will create a new directory called FXRuby-0.99.173. Change to the top-level directory and configure the build by typing:

$ ruby setup.rb config

and then start the build by typing:

$ ruby setup.rb setup

It will take quite awhile to build FXRuby, even on a fast machine, so this might be a good time to take a coffee break. If you run into problems during the compilation, please check the next section for a list of things that could go wrong, and workarounds for those problems.

Once it's finished compiling, install FXRuby by typing:

$ ruby setup.rb install

As a quick sanity check, to make sure that all is well, you should probably fire up irb and try to import FXRuby:

$ irb
irb(main):001:0> require 'fox'
true
irb(main):002:0>

If the import failed (usually with a message along the lines of "Cannot load library"), check the list of things that can go wrong for known problems. If that still doesn't solve your problem, drop me an e-mail or ask around on the Ruby newsgroup or mailing list; it's quite likely that someone else has run into this problem too. Once you do have a working FXRuby installation, you're ready to check out the example programs.

Things That Can Go Wrong

"Too many arguments to function..."

The include files for Ruby 1.6 still have several function prototypes in the older "K & R" C style, where the function's argument list is not included; for example, the function rb_thread_wait_for() takes a single argument of type struct timeval, but its prototype in intern.h is:

    void rb_thread_wait_for();

Because FXRuby is written in C++, and C++ requires strict ANSI C-style function prototypes, code that attempts to call one of these functions will fail to compile under some compilers (including some versions of gcc). The error message will look something like this:

FXRbApp.cpp: In method `long int FXRbApp::onChoreThreads (FXObject *, unsigned int, void *)':
/usr/local/lib/ruby/1.6/i686-linux/intern.h:172: too many arguments to function `void rb_thread_wait_for ()'
FXRbApp.cpp:100: at this point in file
make: *** [FXRbApp.o] Error 1

This problem with the Ruby header files appears to have been corrected for Ruby 1.7, but for the time being you should probably do one of two things to work around the problem:

"ANSI C++ prohibits conversion from..."

Along the lines of the previous topic, there's another problematic declaration in the Ruby header files; this time it's for the rb_rescue2() function. The compiler error goes something like this:

FXRuby.cpp: In function 'long int FXRbHandleMessage(FXObject *, const char *, FXObject *, unsigned int, void *)':
FXRuby.cpp:536: ANSI C++ prohibits conversion from '(long unsigned int)' to '(...)'
FXRuby.cpp:536: ANSI C++ prohibits conversion from '(long unsigned int)' to '(...)'
make: *** [FXRuby.o] Error 1

As with the previously mentioned problems, this problem with the Ruby header files appears to have been corrected for Ruby 1.7, but for the time being you should probably do one of two things to work around the problem:

"Virtual Memory Exhausted"

For FXRuby releases earlier than version 0.99.173 it was common for the compiler to run out of memory trying to compile core_wrap.cpp, with an error message like:

core_wrap.cpp: In function 'void Init_core()':
core_wrap.cpp:108596: virtual memory exhausted

This failure was due to the use of optimizations by the compiler; the FXRuby source code makes heavy use of C++ templates and some versions of gcc require a lot of memory to process these. Starting with FXRuby version 0.99.173, the extconf.rb script should disable compiler optimizations when it generates the FXRuby Makefile. If you suspect that it's not disabling optimizations (or can see this by watching the compile command lines), try modifying the compiler flags (CFLAGS) in the Makefile by hand to do so.

"Cannot load library"

On Linux and other Unix systems that support shared libraries, FOX is typically installed as a shared library named libFOX.so. After all of the source files for FXRuby are compiled, the last step is to link all of the FXRuby object files together with the FOX library (and possibly other system libraries) to produce a new shared library, named fox.so, that Ruby can import as an extension module.

There are a few things that can go wrong when you try to import this extension into Ruby. A common problem is that the operating system cannot locate the FOX shared library (libFOX.so) when it tries to dynamically load the FXRuby extension module; when this happens, the error message will look something like:

$ irb
irb(main):001:0> require 'fox'
LoadError: libFOX-0.99.so.173: cannot open shared object file: No such file or directory - /usr/local/lib/ruby/1.6/i586-linux/fox.so
        from (irb):1:in 'require'
        from (irb):1
    

One workaround for this problem is to modify the LD_LIBRARY_PATH environment variable to include the directory where libFOX.so is installed. For example, if libFOX.so is installed in /usr/local/lib, try setting:

$ export LD_LIBRARY_PATH=/usr/local/lib
$ irb
irb(main):001:0> require 'fox'

If this works, you can of course permanently add the LD_LIBRARY_PATH setting to your login file(s) so that you don't have to remember to type it each time. Another approach that should work for Linux is to modify your /etc/ld.so.conf file to include the installation directory (e.g. /usr/local/lib) but I'm a little fuzzy on the details of this operation. If you know how this works, and have verified that it fixes this problem for importing the FXRuby extension into Ruby, please clue me in so I can include the information here.

Another problem that has been reported by users of both Debian GNU/Linux and NetBSD 1.5 is an error message along the lines of:

/usr/lib/libstdc++.so.2: Undefined symbol "__vt_9exception"...

The fix for this problem is reported to be to modify the FXRuby Makefile and add -lgcc to the LIBS line.