Building Ruby with Visual Studio

Traditionally the most popular way to run Ruby on Windows is using DevKit, which installs a complete Msys/MingW64 environment. This environment makes it easy to install Ruby’s dependencies (zlib, libyaml, openssl and ffi) and lets users build native extensions.

More recently, Microsoft’s Windows Subsystem for Linux (WSL) has also become a popular way to run Ruby on Windows. WSL installs a native Linux environment, making it easy to install Ruby’s dependencies and built native extensions.

MSVC

What is almost unheard of it using Ruby built with Microsoft’s C++ compiler, MSVC. This is contrast to Python, which has used MSVC for its Windows builds for years.

It is actually easy to build Ruby with MSVC, unlike years ago when I last wrote about it.

However, two issues have made it difficult to create a working system.

First, installing libraries used to require building them from source, which could take days to figure out how to do and often involved changing the library’s source code or build scripts. You could skip this step if you used Mingw64 to install libraries, but that defeats the purpose of using MSVC. Using Mingw64 libraries also introduces problems of mixing and matching MSVC runtime libraries which can easily lead to segmentation faults if you aren’t careful. But all of this changed when Microsoft released vcpkg, which makes it as easy to install libraries on Windows as on Linux and MacOS.

Second, MSVC used to have dreadful C support. So even if you could install dependent libraries, native extensions often times did not build. Fortunately, the last few MSVC releases have greatly improved its C support and have mostly addressed this issue.

So with both of these issues now resolved, its easy to create a working system.

Building Ruby

First install Visual Studio (community edition is fine), which also includes vcpkg (or can install vcpkg separately).

Then open a Developer Command Prompt (Windows Terminal will automatically list it) and install Ruby’s dependencies:

vcpkg install zlib:x64-windows
vcpkg install libffi:x64-windows
vcpkg install libyaml:x64-windows
vcpkg install openssl:x64-windows

Then setup paths to vckpg directories if they are not already:

set INCLUDE=c:\source\vcpkg\installed\x64-windows\include;%INCLUDE%
set LIB=c:\source\vcpkg\installed\x64-windows\lib;%LIB%
set PATH=<vcpkg dir>\installed\x64-windows\bin;%PATH%

Then build ruby:

cd <ruby_source_dir>
win32\configure.bat --prefix=<install path>
nmake
nmake install

Building Extensions

Building extensions is similar to above.

First open a Developer Command Prompt and make sure paths to vckpg directories are setup:

set INCLUDE=c:\source\vcpkg\installed\x64-windows\include;%INCLUDE%
set LIB=c:\source\vcpkg\installed\x64-windows\lib;%LIB%
set PATH=<vcpkg dir>\installed\x64-windows\bin;%PATH%

Then build an extension. For example:

gem install ruby-prof

Of course if the extension requires a library, then use vcpkg to install it before building the extension.

Note though, you may still run into extensions that won’t build, perhaps because they use *nix specific libraries or APIs or some part of the C language MSVC doesn’t support (C++ is not an issue). But for the most part, most native extensions now correctly build.

Why Use MSVC?

Now that it fairly easy to create MSVC Ruby builds, why would you want to?

For me, it is the MSVC debugger and profiler. Unlike most developers, I love debuggers, especially ones with nice UIs. I find stepping through code in a debugger really helps me understand it, especially when working in C or C++. Thus most of ruby-prof and rice were written using MSVC. MSVC profiling tools also helped me make ruby-prof much faster then it used to be.

Until recently, nothing compared to MSVC for me. I don’t enjoy using GDB via the command line, Eclipse’s CDT tools never worked as well and Netbeans died off after a strong start. Xcode is fine on MacOS, but has poor C++ support.

In recent years, a strong contender to MSVC – JetBrain’s CLion – has emerged. Its tooling has gotten quite good and it works nicely both on Windows and Linux.

Should Ruby use MSVC?

This is a theoretical question, since Ruby isn’t going to switch to MSVC builds for Windows.

However, the big benefit of using MSVC is not needing to install MSYS and Mingw64, which are big / complex dependencies. Of course, DevKit takes of this for you now.

The disadvantages are:

  • Using a proprietary compiler (MSVC vs GCC)
  • Losing the ability to cross compile native extensions from Linux to Windows, since most Ruby developers do not work on Windows
  • Fixing any native extensions that do not build on MSVC

Leave a Reply

Your email address will not be published. Required fields are marked *

Top