vcvars

Load the MSVC build environment for native Ruby extensions on Windows — no Developer Command Prompt required.

If you use a native MSVC build of Ruby (an x64-mswin64 Ruby, built with cl.exe + nmake), building C extensions is painful: cl.exe and nmake.exe aren't on your PATH until you open a "Developer Command Prompt" and run vcvars64.bat. Forget that step and you get:

'nmake' is not recognized as an internal or external command

vcvars is to MSVC Ruby what ridk enable is to RubyInstaller's MinGW: it finds Visual Studio (via vswhere), loads the toolchain into your process, and gets out of the way. Pure Ruby — no compiler needed to install it (which is the whole point).

This is the gap nothing else filled: rake-compiler hardcodes nmake and assumes cl is already on PATH; rb_sys, ffi-compiler, and rake-compiler-dock are all MinGW/GCC-oriented. None of them activate the MSVC environment for a native mswin build.

Install

gem install vcvars

Quick start

Build a C extension without a Developer Prompt

In a Rakefile that uses rake-compiler:

require "vcvars/rake"          # <- finds VS and loads the MSVC toolchain (mswin only)
require "rake/extensiontask"

spec = Gem::Specification.load("my_ext.gemspec")
Rake::ExtensionTask.new("my_ext", spec) { |e| e.lib_dir = "lib/my_ext" }

Now rake compile just works from an ordinary shell. (require "vcvars/rake" is a no-op on a MinGW/UCRT Ruby and inside an already-active dev environment.)

Run any command inside the MSVC environment

vcvars exec -- rake compile
vcvars exec -- nmake
vcvars exec -- ruby extconf.rb

Diagnose a broken toolchain

vcvars doctor
[ OK ] Ruby is a native MSVC (mswin) build
       3.4.8 x64-mswin64_140  RUBY_SO_NAME=x64-vcruntime140-ruby340
[INFO] Ruby CRT linkage: MD
[ OK ] Ruby headers present
[ OK ] Ruby import library present
[WARN] Developer environment is NOT active
       cl.exe / nmake.exe are not on PATH ... Use `vcvars exec -- <cmd>` ...
[ OK ] Visual Studio located
       Visual Studio Community 2026 (18.5...) at C:\Program Files\Microsoft Visual Studio\18\Community
[ OK ] vcvars activation works (cl.exe resolvable)

doctor knows the usual suspects and how to fix each: dev env not loaded, C1083 (missing ruby.h), LNK2019/LNK2001 (unresolved externals), LNK2005 (CRT /MD vs /MT mismatch), LNK1112 (x64/x86 arch mismatch), LNK1104 (LIB unset), warnings-promoted-to-errors, and mswin-vs-mingw mix-ups.

Scaffold a new MSVC-ready extension gem

vcvars new my_ext
cd my_ext
bundle install
rake compile && rake test

The generated gem has a correct, portable extconf.rb, a warning-clean sample .c (clean under Ruby's aggressive -we flags), a Rakefile already wired to vcvars/rake, and a passing test.

Emit the environment for your shell

vcvars env --format powershell | Invoke-Expression
vcvars env --format bat > vcenv.bat && call vcenv.bat   # cmd.exe
vcvars env --format json                                # machine-readable

Library API

require "vcvars"

Vcvars.mswin?       # => true on a native MSVC Ruby
Vcvars.active?      # => is a developer environment already loaded in this process?
Vcvars.activate!    # locate VS + import the MSVC env into ENV (idempotent); => true/false
Vcvars.locate       # => Vcvars::Locator::Installation (vs_path, vcvars, arch, version, name)
Vcvars.env          # => Hash of the env vars vcvars adds/changes (no ENV mutation)

# Target a different toolchain arch:
Vcvars.activate!(arch: "arm64")

How it works

vcvars runs the located vcvars*.bat inside a short-lived cmd.exe, dumps the resulting environment with set (separated from banner noise by a marker line), diffs it against the current environment, and imports the new/changed variables (PATH, INCLUDE, LIB, LIBPATH, the VSCMD_*/VC* markers, …) into ENV. rake-compiler shells out with FileUtils#sh, which inherits that ENV, so a single activation covers the extconf.rb, nmake, and nmake install steps.

Activation is idempotent (it no-ops when VSCMD_VER is set or cl.exe is already on PATH), so it's safe to call from every Rake invocation.

Requirements

  • Windows with a native MSVC Ruby (x64-mswin64 / RUBY_SO_NAME containing vcruntime). On a MinGW/UCRT Ruby, use RubyInstaller's ridk enable instead.
  • Visual Studio 2017+ or the Build Tools with the Desktop development with C++ workload (provides cl.exe, nmake.exe, and vcvars*.bat).

License

MIT.