I Fixed Windows Native Development

Published: (February 15, 2026 at 06:25 AM EST)
8 min read

Source: Hacker News

Build Requirements: Install Visual Studio

If you’re lucky enough not to know this yet, I envy you. Unfortunately, at this point even Boromir knows…

Well put, Boromir.

The hidden cost of “Install Visual Studio”

Listing Visual Studio as a dependency turns you into an unpaid tech‑support agent for Microsoft’s Visual Studio Installer.
Instead of focusing on code, you end up:

  • Explaining to contributors that they need the “Desktop development with C++” workload, v143 build tools, and the 10.0.22621.0 SDK (not the other SDK).
  • Spending hours troubleshooting broken builds that stem from missing or mismatched components.
  • Re‑imaging your OS multiple times because a single wrong checkbox can ruin the whole setup.

Saying “Install Visual Studio” is essentially handing contributors a choose‑your‑own‑adventure book riddled with dead ends—some of which force you to start over from scratch.

Why is this tragedy unique to Windows?

PlatformTypical experience
LinuxA single apt, yum, or pacman command usually pulls in the entire toolchain.
WindowsVisual Studio is a thousands‑of‑components monolith delivered via a GUI installer. You must navigate a maze of checkboxes to select the right Workloads or Individual Components. Selecting the wrong ones can add gigabytes of unnecessary files, while missing a single component (e.g., Windows 10 SDK (10.0.17763.0) or Spectre‑mitigated libs) leads to cryptic errors like MSB8101 hours later.

The ecosystem conflates editor, compiler, and SDK into a single tangled web. When we list “Visual Studio” as a dependency we fail to distinguish between:

  • The IDE you use to write code.
  • The compiler/toolset required to build it.
  • The runtime SDKs needed for linking and packaging.

Pain points that compound quickly

  • Hours‑long waits – A 15 GB download for a 50 MB compiler.
  • Zero transparency – No clear view of which files were installed or where they reside; the registry becomes littered with cruft, and background update services permanently occupy the Task Manager.
  • No version control – You can’t check the compiler into Git. Slight version differences between teammates cause silent build divergence.
  • “Ghost” environments – Uninstalling never truly cleans up. Moving to a new machine forces you to repeat the entire GUI dance, hoping you tick the same boxes.
  • Fragile command‑line usage – Compiling a single C file requires launching the Developer Command Prompt, which runs vcvarsall.bat. This batch script mutates global environment variables each time, making the setup brittle.

The resulting build instructions

“Works on my machine with VS 17.4.2 (Build 33027.167) and SDK 10.0.22621.0.
If you have 17.5, see Issue #412.
If you are on ARM64, godspeed.”

On Windows this has become the cost of doing business—a 20 GB install for a 5 MB executable, effectively deterring native development.

Bottom line: Listing “Visual Studio” as a single dependency hides a massive, opaque, and fragile toolchain. A cleaner, component‑by‑component specification (or a lightweight, reproducible build environment) would spare contributors endless hours of troubleshooting.

A New Way to Use the MSVC Toolchain

I’m tired of being a “human debugger” for someone else’s installer. I want the MSVC toolchain to behave like a modern dependency: versioned, isolated, declarative.

After a few weeks of work I created an open‑source CLI tool that does exactly that: msvcup.

  • Installs the MSVC toolchain and Windows SDK in a few minutes (on a decent network/hardware).
  • Each version lives in its own isolated directory.
  • Idempotent – you can run it on every build without penalty.

Below is a minimal example that shows how to compile a simple program with zero manual installation of Visual Studio.

1. Create the source file hello.c

#include 

int main() {
    printf("Hello, World\n");
}

2. Create the build script build.bat

@setlocal

rem -------------------------------------------------
rem Download msvcup if it isn’t already present
rem -------------------------------------------------
@if not exist msvcup.exe (
    echo msvcup.exe: installing...
    curl -L -o msvcup.zip ^
        https://github.com/marler8997/msvcup/releases/download/v2026_02_07/msvcup-x86_64-windows.zip
    tar xf msvcup.zip
    del msvcup.zip
) else (
    echo msvcup.exe: already installed
)
@if not exist msvcup.exe exit /b 1

rem -------------------------------------------------
rem Choose the versions you want
rem -------------------------------------------------
set MSVC=msvc-14.44.17.14
set SDK=sdk-10.0.22621.7

rem Install the selected toolchain/SDK (idempotent)
msvcup install --lock-file msvcup.lock --manifest-update-off %MSVC% %SDK%
@if %errorlevel% neq 0 (exit /b %errorlevel%)

rem Generate an “auto‑environment” that points cl.exe to the right tools
msvcup autoenv --target-cpu x64 --out-dir autoenv %MSVC% %SDK%
@if %errorlevel% neq 0 (exit /b %errorlevel%)

rem Compile the program using the generated environment
.\autoenv\cl hello.c

3. Run the script

> build.bat
  • The first run downloads msvcup, installs the requested MSVC version and Windows SDK, and builds hello.c.
  • Subsequent runs are instant – the msvcup install and autoenv steps take only a few milliseconds because everything is already cached.

Why This Matters

  • No Visual Studio Installer – the script works on any Windows 10+ machine that has curl/tar (shipped since 2018).
  • Reproducible builds – the exact toolchain versions are declared in the script (MSVC and SDK variables).
  • Isolation – each version lives in its own directory; nothing pollutes the registry or the global environment.
  • Speed – after the first run the overhead is negligible, so you can safely keep the commands in CI pipelines or per‑developer scripts.

Take a moment, give it a try, and enjoy a declaration of independence from the monolithic Visual Studio Installer. Your builds are now fully self‑contained and portable across any modern Windows machine.

How?

msvcup is inspired by a small Python script written by Mārtiņš Možeiko.
The key insight is that Microsoft publishes JSON manifests describing every component in Visual Studio—the same manifests the official installer uses.

msvcup parses these manifests, selects only the packages required for compilation (compiler, linker, headers, and libraries), and downloads them directly from Microsoft’s CDN. Everything is placed in version‑ed directories under C:\msvcup\.

For details on lock files, cross‑compilation, and other features, see the msvcup README.md.

Automatic environment

Our build.bat script never sources the usual Developer Environment batch files.
It contains two msvcup commands:

  1. Install the toolchain/SDK – this also installs the standard vcvars scripts.
  2. Create an “Automatic Environment”msvcup autoenv generates a directory with wrapper executables that set the required environment variables before invoking the underlying tools.

The generated directory also includes a toolchain.cmake file, which points CMake projects to the installed tools. This lets you build CMake projects outside a special environment.

Real‑world usage

At Tuple (a pair‑programming app) I integrated msvcup into our build system and CI pipelines. This removed the need for users or CI agents to pre‑install Visual Studio. Tuple compiles hundreds of C/C++ projects—including WebRTC—on both x86_64 and ARM targets, keeping the CI and all developers on the same toolchain/SDK.

Benefits

  • Versioned installations – each version lives in its own directory, making side‑by‑side installs, removal, or re‑installation trivial.
  • Cross‑compilation out of the boxmsvcup always downloads tools for all supported cross‑targets, so you never have to hunt down extra components.
  • Lock‑file support – a self‑contained list of all payload URLs guarantees that everyone uses the same packages; changes upstream are immediately visible.
  • Blazing fastinstall and autoenv are idempotent and complete in milliseconds when there is nothing to do.

No more “it works on my machine because I have the 2019 Build Tools installed.”
No more digging through the registry to locate cl.exe.
With msvcup, your environment is defined by code, portable across machines, and ready to compile in milliseconds.

Limitations

msvcup focuses on the core compilation toolchain. If you need:

  • the full Visual Studio IDE,
  • MSBuild‑based project systems,
  • or components such as the C++/CLI compiler,

you’ll still have to use the official installer. For most native development workflows, however, msvcup provides everything you actually need.

A Real‑World Example: Building raylib

Below is a self‑contained batch script that builds raylib from source on a clean Windows system.
It uses msvcup to install the required MSVC and Windows SDK toolchains, then compiles the library without any Visual Studio installation, GUI, or manual steps.

@setlocal

rem -------------------------------------------------
rem  Configuration
rem -------------------------------------------------
set TARGET_CPU=x64
set MSVC=msvc-14.44.17.14
set SDK=sdk-10.0.22621.7

rem -------------------------------------------------
rem  Install msvcup (if not already present)
rem -------------------------------------------------
if not exist msvcup.exe (
    echo msvcup.exe: installing...
    curl -L -o msvcup.zip ^
        https://github.com/marler8997/msvcup/releases/download/v2026_02_07/msvcup-x86_64-windows.zip
    tar xf msvcup.zip
    del msvcup.zip
)

rem -------------------------------------------------
rem  Install the selected toolchains
rem -------------------------------------------------
msvcup.exe install --lock-file msvcup.lock --manifest-update-off %MSVC% %SDK%
if %errorlevel% neq 0 exit /b %errorlevel%

rem -------------------------------------------------
rem  Clone raylib (if not already present)
rem -------------------------------------------------
if not exist raylib (
    git clone https://github.com/raysan5/raylib -b 5.5
)

rem -------------------------------------------------
rem  Load the toolchain environment
rem -------------------------------------------------
call C:\msvcup\%MSVC%\vcvars-%TARGET_CPU%.bat
call C:\msvcup\%SDK%\vcvars-%TARGET_CPU%.bat

rem -------------------------------------------------
rem  Build raylib for Windows
rem -------------------------------------------------
cmd /c "cd raylib\projects\scripts && build-windows"
if %errorlevel% neq 0 exit /b %errorlevel%

rem -------------------------------------------------
rem  Success message
rem -------------------------------------------------
echo Build succeeded! Executable located at:
echo .\raylib\projects\scripts\builds\windows-msvc\game.exe

What this script does

  1. Installs msvcup (a tiny downloader for MSVC/SDK) if it isn’t already on the machine.
  2. Installs the exact MSVC and Windows SDK versions specified by MSVC and SDK.
  3. Clones the raylib repository (branch 5.5) only when the folder is missing.
  4. Sets up the compiler environment by calling the vcvars‑*.bat scripts from the freshly installed toolchains.
  5. Runs the official build-windows script located in raylib\projects\scripts.
  6. Prints the path to the resulting game.exe on success.

No Visual Studio, no GUI, no manual configuration—just a reproducible, script‑driven build.


Further reading:
A detailed walkthrough of using msvcup to build LLVM and Zig from scratch on Windows can be found here.

0 views
Back to Blog

Related posts

Read more »

Supplemental Reading for Windows Signal

Signal Sets interrupt signal handling. Syntax c void __cdecl signalint sig, int funcint, int; Parameters - sig – Signal value. - func – Pointer to the function...