If you're planning to use FXRuby on Windows, with the Pragmatic Programmers' Ruby installer 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.
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-1.0.3.tar.gz |
This will create a new directory called FXRuby-1.0.3. Change to the top-level directory and configure the build by typing:
$ ruby install.rb config |
By default, the install.rb script will look for the FOX include files and library in the standard /usr/local/include/fox and /usr/local/lib directories, respectively. You can override these locations by passing a few additional arguments to install.rb during this step, e.g.
$ ruby install.rb config -- \ --with-fox-include=/home/lyle/fox-1.0.3/include \ --with-fox-lib=/home/lyle/fox-1.0.3/src/.libs |
Once the build has been configured, you can start the build by typing:
$ ruby install.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 list of things that can go wrong for workarounds for those problems.
Once it's finished compiling, install FXRuby by typing:
$ ruby install.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.
This section describes how to compile FXRuby using Microsoft Visual C++, for use with a Ruby that was also compiled using Visual C++.
This discussion assumes that you've built Ruby using the instructions and build files distributed with the standard Ruby source code. To review, you should have started by unpacking the source code tarball, changing into the top-level source code directory (e.g. C:\ruby-1.6.7) and then typing:
C:\ruby-1.6.7>win32\configure type 'nmake' to make ruby for mswin32. C:\ruby-1.6.7>nmake |
After the compilation finished, you installed Ruby somewhere by typing, e.g.,
C:\ruby-1.6.7>nmake DESTDIR=C:\ruby install |
Similarly, I'm assuming that you built the FOX library using the Developer Studio project files distributed with the standard FOX source code distribution. Although it's possible to build FXRuby against either the static library build of FOX (fox.lib) or the DLL build (foxdll.dll), these instructions currently cover only the static library build. Before you get started building FXRuby itself, you'll need to rename the static FOX library from its default filename (fox.lib) to foxst.lib. The reason for this rename is a charming little quirk in Microsoft's LINK utility and the fact that the eventual output name for the FXRuby DLL is also fox.so; for now, just take my word for it. So if your FOX source code distribution and build are found in the C:\fox-1.0.3 directory, you'd need to rename the file:
C:\fox-1.0.3\lib>rename fox.lib foxst.lib |
Now you can configure the FXRuby build by typing:
C:\FXRuby-1.0.3>ruby install.rb config --make-prog=nmake -- \ --with-fox-include=C:\fox-1.0.3\include \ --with-fox-lib=C:\fox-1.0.3\lib |
Once the build has been configured, you can start the build by typing:
C:\FXRuby-1.0.3> ruby install.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. Because Visual C++ is such a strict compiler (usually a good thing), you will probably run into a few problems with non-ANSI declarations in the Ruby header files. If you do run into problems during the compilation, just check the next section for a list of things that could go wrong, and workarounds for those problems. None of them are showstoppers and none require you to restart the compile from scratch (just type ruby install.rb setup to pick up where you left off).
Once it's finished compiling, install FXRuby by typing:
C:\FXRuby-1.0.3> ruby install.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:
C:\FXRuby-1.0.3> 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.
"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. For example, the error message from gcc 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 |
while the error message from Microsoft's Visual C++ compiler looks something like this:
FXRbApp.cpp(109): error C2660: 'rb_thread_wait_for' : function does not take 1 parameters NMAKE : fatal error U1077: 'cl' : return code '0x2' Stop. |
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:
If you're using gcc version 2.95 or earlier, try modifying the compiler flags (CFLAGS) in the FXRuby Makefile to include the -fno-strict-prototype option; this should instruct the compiler to allow these kinds of discrepancies. Unfortunately, this flag is not supported in more recent versions of gcc (most notably, the questionable "2.96" version shipped with some popular Linux distributions).
A more direct approach is to just fix the offending declarations in the Ruby include file(s), i.e. change the declaration for rb_thread_wait_for() in intern.h to read:
void rb_thread_wait_for(struct timeval); |
and change the declaration for rb_gc_mark() in intern.h to read:
void rb_gc_mark(VALUE); |
"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). If you'd like to do this instead, you'll need to (as root):
Edit your /etc/ld.so.conf file and add the directory where libFOX.so is installed; and,
At the shell prompt, type ldconfig to reload the linker configuration.
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.