I fixed Windows native development

612 points298 comments11 hours ago
dgxyz

This is harder than what I do. Just install LTSC Visual Studio build tools from [1], then chuck this in a cmd file:

    cl yourprogram.c /link user32.lib advapi32.lib ... etc etc ...
I've built a load of utilities that do that just fine. I use vim as an editor.

The Visual Studio toolchain does have LTSC and stable releases - no one seems to know about them though. see: https://learn.microsoft.com/en-gb/visualstudio/releases/2022... - you should use these if you are not a single developer and have to collaborate with people. Back like in the old days when we had pinned versions of the toolchain across whole company.

[1] https://download.visualstudio.microsoft.com/download/pr/5d23...

show comments
tgtweak

Toolchains on linux are not clear from dependency hell either - ever install an npm package that needs cmake underneath? glibc dependencies that can't be resolved because you need two different versions simultaneously in the same build somehow... python in another realm here as well. That shiny c++ project that needs a bleeding edge boost version that is about 6 months away from being included in your package manager. Remember patching openSSL when heartbleed came around (libssHELL).

Visual studio is a dog but at least it's one dog - the real hell on windows is .net framework. The sheer incongruency of what version of windows has which version of .net framework installed and which version of .net your app will run in when launched... the actual solution at scale for universal windows compatibility on your .net app is to build a c++ shim that checks for .net beforehand and executes it with the correct version in the event of multiple version conflict - you can literally have 5 fully unique runtimes sharing the same .net target.

show comments
dimgl

> The build.bat above isn’t just a helper script; it’s a declaration of independence from the Visual Studio Installer.

I am so fed up with this! Please if you're writing an article using LLMs stop writing like this!

show comments
jjkaczor

While this is great - Visual Studio installer has a set of "command-line parameters" for unattended installs.

You can then build a script/documentation that isolates your specific requirements and workloads:

https://learn.microsoft.com/en-us/visualstudio/install/use-c...

Had to do this back in 2018, because I worked with a client with no direct internet access on it's DEV/build machines (and even when there was connectivity it was over traditional slow/low-latency satellite connections), so part of the process was also to build an offline install package.

show comments
Aurornis

Looking at the script:

> curl -L -o msvcup.zip https://github.com/marler8997/msvcup/releases/download/v2026...

No thanks. I’m not going to install executables downloaded from an unknown GitHub account named marler8997 without even a simple hash check.

As others have explained the Windows situation is not as bad as this blog post suggests, but even if it was this doesn’t look like a solution. It’s just one other installation script that has sketchy sources.

show comments
its_notjack

Is this post AI-written? The repeated lists with highlighted key points, the "it's not just [x], but [y]" and "no [a] just [b]" scream LLM to me. It would be good to know how much of this post and this project was human-built.

show comments
evanjrowley

Fantastic work! It's a long-needed breath of fresh air for the Visual Studio DX. I wish msvcup was existed when they made us use it back during Uni.

Alternatively, there's this:

Install Visual Studio Build Tools into a container to support a consistent build system | Microsoft Learn

https://learn.microsoft.com/en-us/visualstudio/install/build...

anankaie

Why not use winget to do it?

`winget install --id Microsoft.VisualStudio.2022.BuildTools`.

If you need the Windows(/App) SDK too for the WinRT-features, you can add `winget install --id Microsoft.WindowsSDK.10.0.18362` and/or `winget install --id Microsoft.WindowsAppRuntime.1.8`

show comments
jezek2

I wish open source projects would support MingW or at least not actively blocking it's usage. It's a good compiler that provides an excellent compatibility without the need of any extra runtime DLLs.

I don't understand how open source projects can insist on requiring a proprietary compiler.

show comments
malkia

Or... you can

"winget install Microsoft.VisualStudio.BuildTools"

"winget install Microsoft.WindowsSDK.10.0.26100"

show comments
bob1029

You can do a lot of "native" windows development from modern C#/.NET via win32 interop.

Newer C# features like ref returns, structs, spans, et. al., make the overhead undetectable in many cases.

https://github.com/prasannavl/WinApi

https://github.com/microsoft/CsWin32

show comments
Alifatisk

> It’s so vast that Microsoft distributes it with a sophisticated GUI installer where you navigate a maze of checkboxes, hunting for which “Workloads” or “Individual Components” contain the actual compiler. Select the wrong one and you might lose hours installing something you don’t need.

I have a vague memory of stumbling upon this hell when installing the ldc compiler for dlang [1].

1. https://wiki.dlang.org/Building_and_hacking_LDC_on_Windows_u...

remix2000

I don't really use Windows OS much, but why not just use MinGW? Then you have Clang on all platforms you can think of: Android, all the various Darwin flavors and of course Linux and Windows; as well as on platforms you can't think of like FreeBSD or even Haiku maybe? Like honestly what's the point of supporting MSVC at all?? Maybe I'm just not enough of a Windows nerd to understand? (so I'm basically wondering if mingw has any drawbacks)

show comments
torginus

What we did for out build agents was to just install the required version of build tools via chocolatey. But cool approach!

show comments
jacobgorm

I’ve found that just installing LLVM, CMake and Ninja is enough to get started developing on Windows for most things C/C++.

jordand

For big C++ projects, the .vsconfig import/export way of handling Visual Studio components has worked well for the large teams I'm on. Tell someone to import a .vsconfig and the Visual Studio Installer does everything. Only times we've had issues is from forgetting to update it with components/SDK changes.

show comments
6581

> No Visual Studio installation. No GUI. No prayer. Just a script that does exactly what it says.

show comments
jdthedisciple

Actually not that complicated: You simply check in a global.json [0] where you specify the sdk and workload versions.

Then you also specify target platform sdk versions in the .csproj file and VS will automatically prompt the developer to install the correct toolchain.

[0] https://learn.microsoft.com/en-us/dotnet/core/tools/global-j...

show comments
pjmlp

It starts by not looking into Windows through UNIX developer glasses.

The only issue currently plaguing Windows development is the mess with WinUI and WinAppSDK since Project Reunion, however they are relatively easy to ignore.

show comments
asveikau

Nitpick, "Windows Native Development" also refers to the NT native subsystem, which would be basically coding against private APIs instead of Win32. From the title I thought that's what this was. Then I realized it was about avoiding full use of Visual Studio when building C projects (something that a lot of people already do by the way)

criemen

This is amazing.

At $workplace, we have a script that extracts a toolchain from a GitHub actions windows runner, packages it up, stuffs it into git LFS, which is then pulled by bazel as C++ toolchain.

This is the more scalable way, and I assume it could still somewhat easily be integrated into a bazel build.

show comments
g947o

* Is this allowed per VS' ToS?

* I wonder if Microsoft intentionally doesn't provide this first party to force everyone to install VS, especially the professional/enterprise versions. One could imagine that we'd have a vsproject.toml file similar to pyproject.toml that just does everything when combined with a minimal command line tool. But that doesn't exist for some reason.

show comments
drwu

I hope it would work with wine. Then cross compiling Win64 binaries from Linux would become convenient without requiring spinning up a Windows VM.

show comments
int0x29

Last I checked the license for the headless toolchain requires that a full licensed copy of Visual Studio be installed somewhere. So I think this violates the license terms.

A bug got opened against the rustup installing the headless toolchain by itself at some point. I'll see if I can find it

edit: VSCode bug states this more clearly https://github.com/microsoft/vscode/issues/95745

m132

> On Linux, the toolchain is usually just a package manager command away. On the other hand, “Visual Studio” is thousands of components.

That package manager command, at the very least, pulls in 50+ packages of headers, compilers, and their dependencies from tens of independent projects, nearly each of them following its own release schedule. Linux distributions have it much harder orchestrating all of this, and yet it's Microsoft that cannot get its wholly-owned thing together.

trilogic

WOW such a great work. Myself I have been struggling with Mingw just to compile from source. Of course it works much cleaner then the hated visual studio, but then when it comes to cuda compile, that´s it. Visual studio or the magority our there, It is invasive and full of bloatware like you say. Same struggle with electron.

How to match it with cuda to compile from source the repos?

ddtaylor

As someone who is out of the loop on Windows development, is this related to the Windows Driver Kit (WDK, I think it used to be DDK)? That's a certain type of hell I don't wish upon most.

ivanjermakov

One day I decided to port my text editor to Windows. Since it depends on pcre2 and treesitter, these two libraries had to be provided by the system.

In the span of ~2hrs I didn't manage to find a way to please Zig compiler to notice "system" libraries to link against.

Perhaps I'm too spoiled by installing a system wide dependency in a single command. Or Windows took a wrong turn a couple of decades ago and is very hostile to both developers and regular users.

show comments
yellowapple

I don't get why people go through all these flaming hoops and hurdles to deal with MSVC when MinGW and MinGW-w64/MSYS2 are options. In the latter case you even still get (mostly complete) MSVC ABI-compatibility if you compile with clang.

show comments
anaisbetts

Came in getting ready to hate on this article, but was actually pleasantly surprised, this is great. Good work OP.

reactordev

And here I was messing with MingW64…

This is fantastic and someone at Microslop should take notes.

show comments
ww520

I was just setting up a new machine and was setting up the Rust environment. The very first thing rustup-init asked was to install Visual Studio before proceeding. It was like 20-30gb of stuff installed before moving forward.

This tool would be a great help if I knew beforehand.

whatever1

“Build Requirements: Install Visual Studio”.

You’ve never experienced genuine pain in your life. Have you tried to change the GCC compiler version in Linux?

show comments
dundarious

I'll just keep using Mārtiņš Možeiko's script, portable-msvc.py, that this tool is based upon. It does everything this does, except a lock file and the autoenv. I'm not particularly interested in the former, and definitely not the latter.

https://gist.github.com/mmozeiko/7f3162ec2988e81e56d5c4e22cd...

kI3RO

c3 does this automatically, I implemented the same thing :)

https://github.com/c3lang/c3c/pull/2854

claimred

Perhaps winget is enough?

winget install Microsoft.VisualStudio.2022.BuildTools

show comments
fassssst

You can also install visual studio build tools via the built in winget package manager.

delta_p_delta_x

No one should use any of these weird Frankenstein monstrosities in 2026. And a batch script? :( PowerShell exists.

Install:

  - contrary to the blog post, the entirety of Visual Studio, because the IDE and debugger is *really damn good*.

  - LLVM-MinGW[1]
Load the 'VSDevShell' DLL[2] for PowerShell, and you're good to go, with three different toolchains now:

  cl.exe from VS
  clang-cl.exe—you don't need to install this separately in VS; just use the above-mentioned llvm-mingw clang.exe as `clang.exe --driver=cl /winsysroot <path\to\Windows SDK> /vctoolsdir <path\to\VC>`. Or you can use it in GNU-driver-style mode, and use -Xmicrosoft-windows-sys-root. This causes it to target the Windows ABI and links against the VS SDK/VC tools
  `clang.exe` that targets the Itanium ABI and links against the MinGW libraries and LLVM libc++.
Done and dusted. Load these into a CMake toolchain and never look at them again.

People really like overcomplicating their lives.

At the same time, learn the drawbacks of all toolchains and use what is appropriate for your needs. If you want to write Windows drivers, then forget about anything non-MSVC (unless you really want to do things the hard way for the hell of it). link.exe is slow as molasses, but can do incremental linking natively. cl.exe's code gen is (sometimes) slightly worse than Clang's. The MinGW ABI does not understand things like SAL annotations[3], and this breaks very useful libraries like WIL[4] (or libraries built on top of them, like the Azure C++ SDK[5] The MinGW headers sometimes straight up miss newer features that the Windows SDK comes with, like cfapi.h[6].

[1]: https://github.com/mstorsjo/llvm-mingw

[2]: https://learn.microsoft.com/en-gb/visualstudio/ide/reference...

[3]: https://learn.microsoft.com/en-gb/cpp/c-runtime-library/sal-...

[4]: https://github.com/microsoft/wil

[5]: https://github.com/Azure/azure-sdk-for-cpp

[6]: https://learn.microsoft.com/en-gb/windows/win32/cfapi/build-...

show comments
jevinskie

Were you around before the new installer came out? It was light speed compared to what was before!

OlympicMarmoto

mmozeiko "fixed" windows native development, just use their script. Also PortableBuildTools already exists https://github.com/Data-Oriented-House/PortableBuildTools

a-dub

it's been 14 years since i've used msvc for anything real. iirc the philosophy back then was yearly versioned releases with rolling intermediate updates.

this seems to go down the road towards attempts at determinsticish builds which i think is probably a bad idea since the whole ecosystem is built on rolling updates and a partial move towards pinning dependencies (using bespoke tools) could get complicated.

mschuster91

> On Linux, the toolchain is usually just a package manager command away.

If you are compiling for your native system, yes.

But as soon as you try cross-compiling, you are in for a lot of pain.

throw_win32dev

I will never cease to be amused by these 'Unixhead has to do windev. Reinvents the wheel' blog posts.

mmargerum

If you are looking to rapidly build windows native apps just use Delphi. Superlative tool for this. Been using since ‘95

rzr

next, wrap it with wine and eventually share a bottle/winetrick

NSUserDefaults

So this fixes the problem when msvc is the required compiler. Does the zig C++ compiler bring anything to the table when clang is an option?

show comments
droelf

Thank you, this might be a great way to improve the developer experience in the conda/conda-forge ecosystem.

juujian

> Hours-long waits: You spend an afternoon watching a progress bar download 15GB just to get a 50MB compiler.

What year is it?! Also, haven't heard any complaints regarding VS on MacOS, how ironic...

GeoAtreides

>The key insight

are we doomed to only read AI slop from now on? to get a couple paragraphs in and suddenly be hit with the realization that is AI?

it's all so tiresome

show comments
__alexander

Another option is explore winget and chocolaty. Most build tools and compilers can be installed via the command line on windows. Ask your favorite LLM to create a powershell script to install them all.

wosined

Why not just use Linux?

show comments
beanjuiceII

these seems overly dramatic...i just setup a windows 11 box and installed the needed tools quite quickly via winget and I was up and running

cptskippy

I'm not trying to diminish or take away from this post but Visual Studio is an IDE and is not necessary to build an App.

You just need the required build tools.

If you've ever had to setup a CI/CD pipeline for a Visual Studio project then you've had to do this.

ewuhic

Nix on Windows when...

show comments
zer0zzz

Please people, stop trying to fix windows and just let it die.

shevy-java

To me it seems as if Microsoft wants to make it deliberately harder to have software developers. Now - I installed all the required things and compiled on Windows too, but it is very annoying compared to Linux. Microsoft should simply have ONE default build, e. g. "download this and 80% of developers will be happy". No need for a gazillion checkboxes.

dvfjsdhgfv

I like the tool, I like the article, but I'd prefer it it was half as long but without AI touch.

functionmouse

just use w64devkit, it's nice

forrestthewoods

> msvcup is inspired by a small Python script written by Mārtiņš Možeiko.

This script is great. Just use it. The title saying “I fixed” is moderately offensive glory stealing.

gaigalas

Windows Native is fine. People in that space are comfortable with it.

What needs to be fixed is the valley between unix and windows development for cross-os/many-compiler builds, so one that does both can work seamlessly.

It's not an easy problem and there are lots of faux solutions that seem to fix it all but don't (in builds, the devil is in edge cases).

phendrenad2

I seriously doubt that people who get confused by the MSVC++ Installer will be able to handle a CLI app that installs a mystery MSVC++ toolchain version to a versioned directory. They're still going to click the Visual Studio icon on their desktop and scratch their head why your script didn't magically fix their problems.

mkoubaa

Say what you want about coding agents, when the cost of writing code goes to near-zero, the cost of wrangling tools becomes a much bigger fraction of development effort. This is an amazing opportunity to address long-standing frictions.

PlatoIsADisease

I havent run into this problem yet... but my oldest .net software is only 1 year old... Is this something that happens over the course of a few years?

show comments
forrestthewoods

> I fixed

> msvcup is inspired by a small Python script written by Mārtiņš Možeiko.

No. Martins fixed. OP made a worse layer on top of Martins great script.

jen20

This is a serious quality of life improvement for people forced to deal with Windows! Great job.

kfsone

Gross ignorance and incompetence.

TLDR: I don't understand my native command line, see how lost I got when I tried to do my thing in a different environment.

- Not a unique problem to Windows or even MSVC; He's gonna hate XCode, - Making Python a bootstrap dependency = fail, - Lacks self-awareness to recognize aversion vs avoidance,

My background is distinctly non-Windows, but I survive around Windows so well that people think I'm a Mickeysoft type. And no, I don't use mingw, cygwin, ...

If any of the obstacles this user faced were legitimate, nobody would ever make any money on Windows, including and especially Microsoft - a company whose developers have the same challenges.

I'm being harsh because _mea quondam culpa_ and it's correctable.

Everything this user went thru is the result of aversion instead of avoidance.

To _avoid_ long deep dives into Windows, you need to recognize there is a different vocabulary and a radically different jargon dialect at play.

1. Learn a tiny minimum of Powershell; it's based on the same POSIX spec as bash and zsh, but like Python, Javascript, etc, instead of byte as the fundamental unit, they use objects. So there's less to learn to reach a greater level of convenience than soiling yourself with DOS/CMD/BAT. On Windows, pwsh has a default set of linux-like aliases to minimize the learning required for minimal operability. And never have to type \ instead of / for a directory separator.

2. Microsoft make money from training. To sell their meat-free steak (* ingredient: saw dust), they feed the suits an all-you-can-eat calorie, nutrition, and protein free buffet of documenting everything in great detail and routinely "streamlining" the names and terminology.

Development on Windows is in a different reference frame, but relative to their own reference frames, they're ultimately not all that different.

Approach in your "foreign language" mindset; English alphabet but the words mean different things.

3. What not how. "How do I grep" means you are trying to random access bytes out of a random access character stream. "What's the command to search for text in files?" well, if you're bloody mindedly using cmd, then it's "find".

4. Seriously, learn a little Powershell.

I only approached Powershell hoping to gain material for a #SatansSphincter anti-ms rant while using it as a Rosetta Stone for porting shell scripts in our CI for Windows.

I mean, it is based on the same POSIX spec as sh, bash, and zsh, with a little Perl thrown in. That can't not go horribly, insidiously, 30-rock wrong in the hands of MS, right?

Turned out, it's the same paradigm shift perl/shell users have to make when coming into Python:

from `system("ps | grep hung")` to `"hung" in system("ps")`; from `system("ifconfig -a | sed 's/\<192\.168\.0\./10.0.0./g'")` to `system("ifconfig -a").replace("192.168.0.", "10.0.0.")`

`grep` is a command that applies an assumption to a byte stream, often the output of a command.

In powershell, executing a command is an expression. In the case of a simple command, like "ps", that expression resolves to a String, just like system(...) does in Python.

Learning even a small amount of Powershell is immensely helpful in better understanding your enemy if you're going to have to deal with Windows. The formal names for official things use "verb-singularnoun".

That last part of the convention is the magic: the naming of things on Windows is madness designed to sell certifications, so crazy even MS ultimately had to provide themselves a guide.

eptcyka

Is this even legal?

thrownaway561

I'm just asking, but is there really a need for a native programs anymore? Where I worked a decade ago, we started porting all our native programs over to the browser and this was when MVC beta was just being released. At this point with Electron and Tauri, is there even a need to write a native program

Now with AI, I would think that porting a native program to the browser wouldn't be the chore it once was.

show comments
cissikatt

I just avoid Windows and Windows development. If I get paid to do it I don't mind the shittyness.

Philpax

At the risk of being that guy, I haven't had any issues onboarding people onto native projects written in Rust. rustup does a great job of fetching the required toolchains without issue. I'd imagine the same is also true of Go or Zig.

show comments