我修复了 Windows Native Development

发布: (2026年2月15日 GMT+8 19:25)
13 分钟阅读

请提供您希望翻译的完整文本(除源链接外的内容),我会按照要求将其翻译成简体中文并保留原有的格式。

构建要求:安装 Visual Studio

如果你足够幸运还不知道这件事,我真羡慕你。可惜到现在连波罗米尔都知道了…

说得好,波罗米尔。

“安装 Visual Studio”的隐藏成本

Visual Studio 列为依赖项会让你变成微软 Visual Studio Installer 的免费技术支持人员。
与其专注于代码,你最终会:

  • 向贡献者解释他们需要 “使用 C++ 的桌面开发” 工作负载、v143 构建工具,以及 10.0.22621.0 SDK(而不是其他 SDK)。
  • 花费数小时排查因缺少或不匹配组件导致的构建失败。
  • 多次重新映像你的操作系统,因为一个错误的复选框就能毁掉整个环境。

说“安装 Visual Studio”本质上就是把贡献者交给一本充满死胡同的 自选冒险 书——其中一些死胡同会迫使你从头再来。

为什么这种悲剧只在 Windows 上出现?

平台典型体验
Linux一条 aptyumpacman 命令通常就能拉取完整的工具链。
WindowsVisual Studio 是一个 成千上万组件 的巨型体,通过 GUI 安装程序交付。你必须在一堆复选框中穿梭,选择正确的 工作负载单独组件。选错会导致数 GB 的不必要文件,而漏选单个组件(例如 Windows 10 SDK (10.0.17763.0)Spectre‑mitigated libs)则会在数小时后出现诸如 MSB8101 的晦涩错误。

生态系统把 编辑器编译器SDK 混为一体。当我们把“Visual Studio”列为依赖时,实际上并未区分:

  • 你用来编写代码的 IDE
  • 用来构建代码的 编译器/工具集
  • 用于链接和打包的 运行时 SDK

快速叠加的痛点

  • 数小时的等待——15 GB 的下载却只得到 50 MB 的编译器。
  • 零透明度——无法清晰看到安装了哪些文件以及它们的所在位置;注册表被大量垃圾信息占满,后台更新服务永久占用任务管理器。
  • 没有版本控制——编译器无法加入 Git。团队成员之间的细微版本差异会导致静默的构建分歧。
  • “幽灵”环境——卸载从未真正清理干净。换到新机器时必须再次完整地走一遍 GUI 步骤,盼望自己勾选了相同的选项。
  • 脆弱的命令行使用——编译单个 C 文件需要启动 Developer Command Prompt,该提示符会运行 vcvarsall.bat。这个批处理脚本每次都会修改全局环境变量,使得设置变得不稳固。

产生的构建说明

“在我的机器上使用 VS 17.4.2(Build 33027.167)和 SDK 10.0.22621.0 可以工作。
如果你使用 17.5,请参见 Issue #412。
如果你在 ARM64 上,祝你好运。”

在 Windows 上,这已经成为 业务成本——为一个 5 MB 的可执行文件安装 20 GB,实际上在阻止原生开发。

结论: 把“Visual Studio”列为单一依赖会隐藏一个庞大、晦涩且脆弱的工具链。采用更细粒度的组件逐一指定(或使用轻量、可复现的构建环境)可以让贡献者免去无尽的排错时间。

Source:

使用 MSVC 工具链的新方式

我已经厌倦了为别人的安装程序充当“人工调试器”。我希望 MSVC 工具链像现代依赖一样:可版本化、隔离、声明式

经过几周的工作,我创建了一个开源 CLI 工具,正好实现了这一点:msvcup

  • 在几分钟内安装 MSVC 工具链和 Windows SDK(前提是网络/硬件条件良好)。
  • 每个版本都位于独立的隔离目录中。
  • 幂等——可以在每次构建时运行它而不会产生额外开销。

下面是一个最小示例,展示如何在 无需手动安装 Visual Studio 的情况下编译一个简单程序。

1. 创建源文件 hello.c

#include <stdio.h>

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

2. 创建构建脚本 build.bat

@setlocal

rem -------------------------------------------------
rem 如果尚未存在则下载 msvcup
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 选择你想要的版本
rem -------------------------------------------------
set MSVC=msvc-14.44.17.14
set SDK=sdk-10.0.22621.7

rem 安装所选的工具链/SDK(幂等)
msvcup install --lock-file msvcup.lock --manifest-update-off %MSVC% %SDK%
@if %errorlevel% neq 0 (exit /b %errorlevel%)

rem 生成指向正确 cl.exe 的 “auto‑environment”
msvcup autoenv --target-cpu x64 --out-dir autoenv %MSVC% %SDK%
@if %errorlevel% neq 0 (exit /b %errorlevel%)

rem 使用生成的环境编译程序
.\autoenv\cl hello.c

3. 运行脚本

> build.bat
  • 第一次运行时会下载 msvcup,安装所请求的 MSVC 版本和 Windows SDK,并构建 hello.c
  • 随后的运行是 瞬间完成——msvcup installautoenv 步骤只需几毫秒,因为所有内容已经被缓存。

为什么这很重要

  • 无需 Visual Studio 安装程序 – 脚本可在任何装有 curl/tar(自 2018 年起随系统提供)的 Windows 10+ 机器上运行。
  • 可复现的构建 – 脚本中声明了确切的工具链版本(MSVCSDK 变量)。
  • 隔离 – 每个版本都位于独立目录;不会污染注册表或全局环境。
  • 速度 – 首次运行后开销可以忽略不计,因此可以安全地将这些命令保留在 CI 流水线或开发者脚本中。

抽出一点时间,试一试,并享受从庞大的 Visual Studio 安装程序中获得的 独立宣言。你的构建现在完全自包含,且可在任何现代 Windows 机器上便携运行。

Source:

如何?

msvcup 的灵感来源于 Mārtiņš Možeiko 编写的一个小型 Python 脚本。关键的洞见在于,Microsoft 会发布描述 Visual Studio 中每个组件的 JSON 清单——这些正是官方安装程序使用的清单。

msvcup 解析这些清单,只挑选编译所需的包(编译器、链接器、头文件和库),并直接从 Microsoft 的 CDN 下载。所有文件都会放在 C:\msvcup\ 下的版本化目录中。

有关锁文件、交叉编译以及其他功能的详细信息,请参阅 msvcup README.md

自动环境

我们的 build.bat 脚本从不调用常规的 Developer Environment 批处理文件。它只包含两个 msvcup 命令:

  1. 安装工具链/SDK —— 这同时会安装标准的 vcvars 脚本。
  2. 创建 “自动环境” —— msvcup autoenv 会生成一个目录,里面的包装可执行文件会在调用底层工具之前设置所需的环境变量。

生成的目录还会包含一个 toolchain.cmake 文件,指向已安装的工具,使 CMake 项目能够 在普通环境之外 构建。

实际使用

Tuple(一款结对编程应用)中,我将 msvcup 集成到了我们的构建系统和 CI 流水线。这样就不再需要用户或 CI 代理预先安装 Visual Studio。Tuple 能在 x86_64 和 ARM 目标上编译数百个 C/C++ 项目——包括 WebRTC——并让 CI 与所有开发者使用相同的工具链/SDK。

好处

  • 版本化安装 —— 每个版本都有独立的目录,旁路安装、删除或重新安装都非常简单。
  • 开箱即用的交叉编译 —— msvcup 总是下载所有受支持的交叉目标工具,省去寻找额外组件的麻烦。
  • 锁文件支持 —— 一个自包含的所有负载 URL 列表确保每个人使用相同的包;上游的更改会立刻显现。
  • 极速 —— installautoenv 是幂等的,在没有工作要做时可以在毫秒级完成。

再也不会出现 “在我的机器上能跑是因为我装了 2019 Build Tools”。
再也不需要在注册表里翻找 cl.exe 的位置。
有了 msvcup,你的环境由代码定义,可跨机器迁移,并能在毫秒内准备好编译。

限制

msvcup 只关注核心编译工具链。如果你需要:

  • 完整的 Visual Studio IDE,
  • 基于 MSBuild 的项目系统,
  • 或者诸如 C++/CLI 编译器之类的组件,

仍然需要使用官方安装程序。不过,对于大多数本地开发工作流来说,msvcup 已经提供了你真正需要的全部内容。

实际案例:构建 raylib

下面是一个自包含的批处理脚本,可在全新的 Windows 系统上从源码构建 raylib
它使用 msvcup 安装所需的 MSVC 和 Windows SDK 工具链,然后在没有任何 Visual Studio 安装、GUI 或手动步骤的情况下编译该库。

@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

脚本的工作原理

  1. 安装 msvcup(一个用于下载 MSVC/SDK 的小工具),如果机器上尚未存在。
  2. 安装 MSVCSDK 变量指定的确切版本。
  3. 克隆 raylib 仓库(分支 5.5),仅在目录不存在时执行。
  4. 通过调用新安装的工具链中的 vcvars‑*.bat 脚本,设置编译器环境。
  5. 运行官方的 build-windows 脚本,该脚本位于 raylib\projects\scripts 中。
  6. 在成功后打印生成的 game.exe 的路径。

无需 Visual Studio、无需 GUI、无需手动配置——只需一个可复现、脚本驱动的构建过程。


进一步阅读:
关于在 Windows 上使用 msvcup 从零构建 LLVM 和 Zig 的详细步骤,请参见此处

0 浏览
Back to Blog

相关文章

阅读更多 »

Windows Signal 的补充阅读

Signal 设置中断信号处理。语法 c void __cdecl signal(int sig, int func(int), int); 参数 - sig – 信号值。 - func – 指向函数的指针。

已解决:Notion 无法工作!!!

执行摘要:Notion 显示离线通常是由于您电脑上的本地 DNS 缓存过期,而不是服务中断。清除 DNS 缓存可以强制…