Thoughts and tutorials on programming

Thursday, July 23, 2009

How to compile using visual studio for ruby

Extension building in ruby on windows is a little complicated, because the "mainstream" one click installer uses mingw for its build, which is based on a rather outdated msvcrt.dll [version 6 I believe--the one used by Visual Studio 6, no longer in production].

It is, however, according to Charlie Savage, possible to mix code built from newer compilers into it [1].


Mixing runtime libraries
========================

The most obvious criticism of this plan is that it will lead to mixing of microsoft runtime c libraries. From my experience this works as long as extension developers follow the rules described here:

http://msdn.microsoft.com/en-us/library/ms235460(VS.80).aspx

To be more concrete, this boils down to two simple rules:

* If you call ALLOC or ALLOC_N, use xfree and not free
* Don't call sprintf or printf in an extension, instead use rb_f_sprintf/rb_vsprintf/rb_io_printf

If an extension violate these two rules then its obvious, a segmentation fault happens. Thus these bugs are easy to find and easy to fix.

Since VC6 is thankfully no longer available, supporting msvc absolutely, positively requires mixing c runtime libraries and therefore extension writers must follow these two simple rules.

(Note that if you use rb_x_malloc and its siblings, they will use the right free call for you).

i.e. (summarizing) "If it uses ALLOC, xfree, doesn't use STDIN/STDOUT, it can link against any runtime it wants" [though nobu did note there may be a problem with errno's differing, probably not a problem.]

That being said it would appear that you need to also avoid the /MD compiler directive in MS compilers, as well [2].

Also, users may need to download a redistributable for the version of C compiler you used.

However, it should work.
Note that for distributing gems, you can use Luis Lavena's "rake compiler" to build your binaries for you [3].
Good luck!
[1] http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/22727
[2] http://groups.google.com/group/thin-ruby/browse_thread/thread/c15b2472eb97c2ba/ea7c5127035d193b
[3] http://github.com/luislavena/rake-compiler/tree/master ex: ext.cross_platform = ['i386-mswin32', 'i386-mingw32']

Contributors

Followers