Skip to content

Getting a Ruby C extension to compile on Windows

The Programming Ruby book is one of those must have references if you’re going to program Ruby. I still use it all the time when I’m looking up information on Ruby. One thing I’ve started playing with is getting a C extension to work with Ruby. Chapter 21 of Volume 2 of Programming Ruby gives you a great example for writing a C extension from scratch and getting it to compile and work in a UNIX-based environment however it falls short on handholding you through the Windows process. Here’s my notes on what you need:

Executive Summary

  1. Install Visual Studio Express or some other Visual C++ variant
  2. Install the Platform SDK (You need this if you want windows.h and you DO)
  3. Make minor changes in Ruby config.h (Not necessary for all versions of Visual Studio)
  4. Write the MyTest code and extconf.rb file from the book
  5. Run ruby extconf.rb to generate a nmake-based Makefile
  6. Startup a command prompt with the SDK environment variables set
  7. Run nmake to compile the library
  8. Done!

The detailed version

Download Visual Studio

Unless you’re using cygwin or mingw as your compiler you’ll probably want to get Visual Studio. The latest incarnation is Visual Studio 2005 which is a free download. I’ve found that it’s a pain to find the right URL to download it from on Microsoft but that’s Microsoft for you.

Download the Windows Platform SDK

Since the Windows version of Ruby ties in with many Win32 libraries it’s necessary to get the Platform SDK. If you DON’T download it you will see strange error messages when trying to compile your Ruby extension such as this:

c:\ruby\lib\ruby\1.8\i386-mswin32\win32/win32.h(32) : fatal error C1083: Cannot
open include file: 'windows.h': No such file or directory
NMAKE : fatal error U1077: '"C:\Program Files\Microsoft Visual Studio 8\VC\BIN\cl.EXE"' : return code '0x2'
Stop.

windows.h is NOT included by default in Visual Studio 2005 (but I believe it is in older versions of Visual Studio) so you need the platform SDKs to get the right development libraries. While it would be nice if the C-based version of Ruby could easily hook into the .Net platform, this would probably require significant hacking the mkmf library in Ruby to get it to work transparently. I doubt that will happen soon.

Once again, I found Microsoft’s website really annoying to navigate in order to try to find the Platform SDK so you might want to click here then make sure you have the latest platform SDK (As of this writing the latest was R1)

Tweak $RUBY_HOME/lib/ruby/1.8/i386-mswin32/config.h

For some versions Visual Studio (noteably Visual Studio 2005), the config file located in $RUBY_HOME/lib/ruby/1.8/i386-mswin32/config.h (Usually $RUBY_HOME installs to C:/Ruby) will require a tweak to allow compilation. Or you could rebuild Ruby from scratch yourself but I prefer to use the All-in-one installer. In the config.h file delete or comment out the following lines:

#if _MSC_VER != 1200
#error MSC version unmatch
#endif

Finally! Let’s compile it already

Okay now you’re ready to finally to actually compile your code. In order to get all the environment variables set properly you might want to launch a command prompt from the shortcuts the Platform SDK makes in the Start Menu then make sure to run vsvars32.bat from Visual Studio’s directory (Usually in C:\Program Files\Microsoft Visual Studio 8\VC\bin). Now with that all set you can finally compile something! (whew!):

C:\cygwin\home\foo\exttest>ruby extconf.rb
creating Makefile

C:\cygwin\home\foo\exttest>nmake

Microsoft (R) Program Maintenance Utility Version 8.00.50727.42
Copyright (C) Microsoft Corporation.  All rights reserved.

        cl -nologo -I. -Ic:/ruby/lib/ruby/1.8/i386-mswin32 -Ic:/ruby/lib/ruby/1.
8/i386-mswin32 -I. -MD -Zi -O2b2xg- -G6  -c -Tcmy_test.c
cl : Command line warning D9035 : option 'Og-' has been deprecated and will be r
emoved in a future release
cl : Command line warning D9002 : ignoring unknown option '-G6'
my_test.c
        cl -nologo -LD -Femy_test.so my_test.obj msvcrt-ruby18.lib  oldnames.lib
 user32.lib advapi32.lib wsock32.lib  -link -incremental:no -debug -opt:ref -opt
:icf -dll -libpath:"c:/ruby/lib" -def:my_test-i386-mswin32.def -implib:my_test-i
386-mswin32.lib -pdb:my_test-i386-mswin32.pdb
   Creating library my_test-i386-mswin32.lib and object my_test-i386-mswin32.exp

C:\cygwin\foo\exttest>irb
irb(main):001:0> require 'my_test'
=> true
irb(main):002:0> test = MyTest.new
=> #

References

{ 3 } Trackbacks

  1. [...] In a previous post I mentioned how to get the Ruby C extension to compile under Windows using Visual Studio Express/Studio 2005. However, I left out an important part regarding manifests which have been part of the development process in VC++7 and above. [...]

  2. CrackRadio.com » links for 2008-01-15 | January 15, 2008 at 1:24 pm | Permalink

    [...] Getting a Ruby C extension to compile on Windows (tags: ruby windows extension) [...]

  3. [...] blog posts by Al Hoang explain a [...]