I've been meaning to figure out how to build Rubinius on Windows 7 for awhile, but something always seemed to get in the way. You know the story, little things like paying work, business trips, a good jam session, other projects, whatever.
I finally took some time and have made progress solving the puzzle. Thankfully, the Rubinius team has been busy hacking on the core as well as their build environment. There's still a lot to do to make the build environment more usable for Windows Ruby hackers, but I was pleased with how relatively simple it was to progress as far as I did.
While I haven't been able to build Rubinius yet, this post is a snapshot of where I'm at and what I've had to do to get there. In summary:
ruby configure
and rake
.The instructions that follow assume you've already installed and configured a Git client such as MSysGit.
If you haven't already done so, install a 1.9 version of the RubyInstaller,
add it's bin
directory to your PATH
environment variable, and make sure
you've got the Rake gem installed by typing rake --version
. If Rake isn't
present, ensure you're connected to the Internet and type gem install rake
.
The RubyInstaller is easy to install regardless of whether you use the installer
or the 7-Zip archive. If you installed it and tried typing ruby --version
in a Command Prompt with no results, drop by our Google Group
and ask for help.
One of the features I've built into the RubyInstaller build recipes is the ability to easily create different "flavors" of MinGW-based build toolchains. We're going to take advantage of that feature and build a 32bit, MinGW-w64 based flavor and use it to build Rubinius. To build it, simply do the following:
# clone the RubyInstaller GitHub repository C:\>git clone git://github.com/oneclick/rubyinstaller.git ... # build your custom DevKit C:\>cd rubyinstaller C:\rubyinstaller>rake devkit 7z=1 dkver=mingw64-32-4.5.4 ... # find your MinGW-w64 DevKit in C:\rubyinstaller\pkg
Unfortunately, you've got one more tweak to make before the MinGW-w64 DevKit is usable for building Rubinius. You've got to remove the prefixing from the toolchain executable names.
Until the MinGW-w64 standard downloads are available in non-cross-compiling
versions, or I update the DevKit build recipes (on my TODO), you'll need to
manually strip the name prefixing from the relevant executables in your
<DEVKIT_INSTALL_DIR>\mingw\bin
directory. Here's a Ruby script and example
to help you out.
# file: deprefix.rb
def usage_and_exit(code)
STDERR.puts 'usage: ruby deprefix.rb ROOT_DIR PREFIX'
exit(code)
end
usage_and_exit(-1) unless ARGV.length == 2
dir = ARGV[0].gsub('\\', File::SEPARATOR)
prefix = ARGV[1]
usage_and_exit(-2) unless File.directory?(dir)
Dir.glob(File.join(dir, "#{prefix}-*.exe")).each do |f|
d = File.dirname(f)
b = File.basename(f)
puts "renaming #{f} => #{d}/#{b.split(/-/)[3]}"
File.rename(f, "#{d}/#{b.split(/-/)[3]}")
end
Copy the above script as deprefix.rb
into the root directory of wherever
you installed your MinGW-w64 DevKit (C:\DevKit-w64
for this post) and
run the script like so.
C:\DevKit-w64>ruby deprefix.rb mingw\bin i686-w64-mingw32 renaming mingw/bin/i686-w64-mingw32-addr2line.exe => mingw/bin/addr2line.exe renaming mingw/bin/i686-w64-mingw32-ar.exe => mingw/bin/ar.exe renaming mingw/bin/i686-w64-mingw32-as.exe => mingw/bin/as.exe renaming mingw/bin/i686-w64-mingw32-c++.exe => mingw/bin/c++.exe ... renaming mingw/bin/i686-w64-mingw32-windres.exe => mingw/bin/windres.exe C:\DevKit-w64>
Next, you need to clone the Rubinius source repository, create a new branch based
off of the 2.0.0pre
branch, and add the MinGW-w64 based DevKit to your PATH
env var like so.
# clone Rubinius and create a branch for hacking C:\projects>git clone git://github.com/rubinius/rubinius.git ... C:\projects>cd rubinius C:\projects\rubinius>git checkout -b win-build origin/2.0.0pre ... # add the MinGW-w64 DevKit tools to your PATH C:\projects\rubinius>\DevKit-w64\devkitvars.bat Adding the DevKit to PATH... C:\projects\rubinius>
You're now set up and ready to pull the trigger, so get building!
C:\projects\rubinius>ruby --version ruby 1.9.2p290 (2011-07-09 revision 32478) [i386-mingw32] C:\projects\rubinius>ruby configure --with-vendor-zlib ... # see how Rubinius configured itself C:\projects\rubinius>ruby configure --show Using the following configuration to build ------------------------------------------ module Rubinius BUILD_CONFIG = { :which_ruby => :ruby, :build_ruby => "C:/ruby192/bin/ruby.exe", :build_rake => "rake", :build_perl => "perl", :llvm => :prebuilt, ... :vendor_zlib => false, } end Setting the following defines for the VM ---------------------------------------- #define RBX_HOST "i686-pc-mingw32" #define RBX_CPU "i686" #define RBX_VENDOR "pc" #define RBX_OS "mingw32" ... #define RBX_ZLIB_PATH "" #define RBX_DEFAULT_18 true #define RBX_DEFAULT_19 false #define RBX_DEFAULT_20 false #define RBX_ENABLED_18 1 #define RBX_LITTLE_ENDIAN 1 #define RBX_HAVE_TR1_HASH 1 #define RBX_WINDOWS 1 # time to build! make a cup of green tea while you wait... C:\projects\rubinius>rake ...
After successfully building for quite awhile you should see the build fail with
an error similar to the following. This failure appears to be caused by the fact
that the zlib library hasn't been built. This isn't surprising given that
ruby configure --show
displayed :vendor_zlib => false
and #define RBX_ZLIB_PATH ""
.
UPDATE: there appears to be a bug in configure
and I've submitted a simple
pull request to fix the issue
of the zlib
library not being built.
... 2: CC vm/vmmethod.cpp Build time: 461.15241 seconds 1: LD vm/vm.exe C:/ruby192/bin/ruby.exe -S rake -r C:/projects/rubinius/config.rb -r C:/projects/rubinius/rakelib/ext_helper.rb -r C:/projects/rubinius/rakelib/dependency_grapher.rb build:build Building bootstrap Melbourne for MRI CXX bstrlib.c CXX encoding_compat.cpp CXX grammar18.cpp CXX grammar19.cpp CXX melbourne.cpp CXX node_types18.cpp CXX node_types19.cpp CXX quark.cpp CXX symbols.cpp CXX var_table18.cpp CXX var_table19.cpp CXX visitor18.cpp CXX visitor19.cpp LDSHARED build/melbourne20.so GEN runtime/platform.conf rake aborted! Compilation error generating constants rbx.platform.zlib: In file included from C:/projects/rubinius/rbx-ffi-generators-rbx-platform-zlib.c:2:0: vendor/zlib/zlib.h:34:19: fatal error: zconf.h: No such file or directory compilation terminated. Tasks: TOP => default => build => build:build => kernel:build => runtime/platform.conf (See full trace by running task with --trace)
While it's really too early for me to discuss the Rubinius build environment warts, one ugly does jump out.
rake distclean
doesn't do what you expect it to do. I had to
go into each vendor/
sub-directory and manually run either make distclean
or make clean
depending upon the library. The rake distclean
should
bring the the source tree back to a pristine state by cleaning the vendor/
subdirectories, while the rake clean
target should correctly skip cleaning
those subdirectories.While I've made a lot of progress in building Rubinius on Windows 7, unfortunately I'm not yet able to successfully and repeatedly build the Rubinius project. This likely has more to do with my current unfamiliarity with Rubinius than anything else.
In future posts I plan to summarize what I needed to do to successfully build Rubinius on Windows 7. Meanwhile, if you spot anything that I'm doing wrong or have any suggestions, I'd like to hear from you via email or Twitter.
And I'm sure Brian Ford and others on the Rubinius team would also like to hear about your progress.