Posted on Jan 17, 2008

Ruby for Windows – Part 1

Last year Curt Hibbs handed me the keys to the kingdom: RubyInstaller
(check it on RubyForge), it’s time to share some details about this with the community.

I’ll try to summarize the background of the current issues and share some of my ideas. I’d like to hear your ideas too.

This is 1st article of 3. I’ll try to keep them short.

Why ‘for Windows’ is so complex?

There are several differences between Windows and any other OS, two of them are the biggest ones:

  1. Lack of out of the box development environment.
  2. Coexistence of C Runtime Libraries.
1. The Development environment

The first point, is the simpler of the two: to compile any code (Ruby or other project) you need a compiler, a linker and a series of tools often labeled as development toolchain.
Things get a bit more complex since you can have multiple development toolchains installed under Windows, just to name the bigger ones:

  • Microsoft Visual C toolchain (Either bundled with Visual Studio or standalone as DDK or SDK).
  • GNU toolchain (known as MinGW)

Some projects support better Visual C and others GCC and the GNU tools.

The GNU toolchain is better known in the unix scene, since Linux, FreeBSD and other OS rely on it as the only compiler for the OS

Instead, there are several versions of Microsoft toolchain, from VC6 to VC9 (just released).

Correctly install and configure any of these toolchains is a bit problematic, mostly due differences between versions (configuration files, registry editing, etc.) and the lack of unified documentation showing the general settings and correct usage for most command line development.

2. The C Runtime (CRT, libc)

The C Runtime is the lower layer between userland and the OS, and provides the basic functionality that allow things like memory allocation and release of it, IO handling and some functions like threading, process spawning and forking.

Applications link against this C Runtime, which often is a shared object or DLL.

Unix Operating Systems rely on just one C runtime for all the applications installed, and changing it requires recompilation or re-installation of the whole system, since there are changes introduced between versions that break backward compatibility.

On the Windows side, multiple C Runtimes can co-exists, mostly due changes in the naming conventions for the DLL CRT:

  • MSVCRT.DLL, almost standard in Windows NT/2000/XP OS, default up to version 6.0
  • MSVCR71.DLL, introduced in Visual Studio 2003, part of VC7 compiler, version 7.1
  • MSVCR80.DLL, part of Visual Studio/Express 2005 and Windows SDK for Vista, version 8.0
  • MSVCR90.DLL, part of Visual Studio/Express 2008.

The problem with this flexibility is that programs compiled and linked against version 6.0 cannot be called or used in programs linked with version 7.1 or 8.0, and vice versa.

There are more issues here, but I’ll leave the references for you to read ;-)

So, how does this affect us?

Let me describe a hypothetical scenario:

  • Joe works at ACME and has just discovered Ruby.
  • He visits the Ruby Home Page and jumps to the download section.
  • Since he is using Windows at his work, he grabs the One-Click Installer and installs it on his system.
  • He then starts writing scripts and finds that he needs a gem to do something special with his data.
  • Joe opens a console and types gem install somegem
  • The installation process halts with some spitting out some errors after Building native extensions…
  • After some digging, he finds out that requires a compiler, and this compiler isn’t available (VC6).
  • He decides to try with VC8, so he downloads it along with some packages and after some tweaking, gets it installed.
  • He tries again to install the gem, but fails due MSVC version mismatch
  • Then he jumps into the forums and mailing lists asking for help.
  • Frustrated, he decides to drop Ruby for another language.

Other languages, contrary to Ruby, provide a mechanism to workaround these compiler issues (Python and their distutils package, as example).

Adding that functionality to Ruby is doable, but requires time to implement and then tweak every extension that requires compilation (that could be a backward compatibility nightmare).

In the next part of this article I’ll describe the situation regarding Ruby on Windows and its dependency on some libraries. Also debunk the 32 versus 64 bits myth (of Ruby for Windows, of course).

Until next week!

References

I’ve collected a few links on the discussion that drove me to write this post.

Luis Lavena on Will 1.8.6 remain compiled with VC6?

Gary Wright on Windows Compilation Madness

Gonzalo Garramuño on What’s the status of compiler/compiling on windows?

Jay Levitt on Interesting ruby bootstrap experience on Windows

Austin Ziegler on Ruby on Windows: A Note for Microsoft

1 Comment