老有人问这个问题:我只是想用 MSVC 编译 C/C++ 代码,为什么要逼着我装一个好几个 GB 的 Visual Studio?如果只是跑一下命令行编译、配个 CI、或者让 CMake 有一套干净的 Windows 原生工具链,确实是没必要装完整 IDE 的。微软也一直提供独立的 Build Tools 分发包,可以只装编译器、链接器、Windows SDK 和标准库头文件,整个过程比很多人想象中简单,但坑也是有的。
这篇文章就专门写清楚:Windows 上如何只安装 MSVC 而不安装 Visual Studio,从原理、版本选型、图形界面安装、命令行自动化安装,到装完之后如何配置环境变量和使用 CMake,最后再整理几个我实际踩过的坑。内容很长,建议先收藏再慢慢看。
1. 为什么能“只装 MSVC”:先说清楚 Build Tools 是什么
1.1 MSVC 不是一个“软件”,而是一套工具链
先说点背景。MSVC(Microsoft Visual C++)严格来说不是某个单独的 exe,而是一整套编译工具链的统称,主要包括这些组件:
cl.exe:C/C++ 编译器本体,负责把源码编译成目标文件(.obj)。link.exe:链接器,负责把目标文件、静态库、动态库链接成 exe 或 dll。nmake.exe:Make 工具,对应 Makefile 里的 nmake 语法。ml64.exe/ml.exe:汇编器,编译汇编代码文件。lib.exe:静态库管理工具。- Windows SDK 头文件、库文件:例如
windows.h、kernel32.lib、user32.lib等。 - C/C++ 标准库:
MSVC STL(对应vcruntime、msvcp系列运行时库)。
平时我们安装 Visual Studio,其实就是在安装 IDE 外壳的同时,附带安装了这么一整套工具链。而微软把这一整套工具链单独打包成了“Build Tools for Visual Studio”,你安装它,就是在不装 IDE 的情况下获得 MSVC 编译环境。所以“仅安装 MSVC”的本质,就是安装Build Tools for Visual Studio。
1.2 Build Tools 与 Visual Studio 在底层上是同源的
有个很容易搞混的点:Build Tools 并不是一个功能阉割的替代品,它里面装的cl.exe、link.exe和你完整安装 Visual Studio 之后调用的那一套是完全相同的。唯一的区别就是没有那个图形界面的 IDE,没有解决方案资源管理器、没有调试器 UI、没有代码编辑器的各种智能化功能。
所以在很多自动化场景里,Build Tools 是比完整安装 Visual Studio 更合适的选择:
- CI/CD 流水线:在 GitHub Actions、Jenkins、Azure Pipelines 等环境里构建 C/C++ 项目,只需要能编译、能链接、能跑测试,不需要 IDE。
- 本机手动编译少量代码:比如你只是要编译某个开源库的源码,
cl一把梭就够了。 - 搭配其他编辑器:你习惯用 VS Code、CLion、Vim,或者公司有统一风格要求,就不需要厚重的 IDE。
- 服务器环境:Windows Server 上部署编译服务,装 Visual Studio 不合适,Build Tools 更干净。
那什么情况下不建议这么做?如果你需要开发、调试、断点查看、性能剖析等完整 IDE 能力,或者需要 C# / VB.NET / F# 等非 C++ 场景,Build Tools 就不适合。Build Tools 并不包含 .NET 编译器,.NET 开发还是得走完整 Visual Studio 或者单独的 .NET SDK。
提示:Build Tools 官方支持 C++ 开发,但如果你只是为了编译 C# 程序,直接装 .NET SDK 更轻量。
2. 安装方式与版本选型:动手前先确定方向
2.1 支持哪些版本,选哪个?
MSVC 工具链的版本号很绕。先说结论:2024 年以后的正常新项目,建议直接用Visual Studio 2022 Build Tools,全称Build Tools for Visual Studio 2022。它支持 Windows 10/11,编译出来的程序兼容性也最好,社区生态和 CMake 支持都非常成熟。
这里有个非常容易误解的点:VS 2022 Build Tools 里的 MSVC 编译器版本并不叫 2022,它的编译器内部版本号是 C/C++ 编译器19.3x系列,对应的_MSC_VER宏是 1930 到 1940 左右的范围。你可能会看到cl.exe输出的版本是 “Microsoft (R) C/C++ Optimizing Compiler Version 19.40”,这没问题,它对应的就是 VS 2022 的工具集。
如果你在用的是老项目,需要匹配旧版的 Platform Toolset,那就要注意了:
| 需求场景 | 推荐安装包 |
|---|---|
| 新项目、新学习、CMake 构建 | Build Tools for Visual Studio 2022 |
| 维护老代码,需要 VS 2019 工具集 | Visual Studio 2019 Build Tools |
| 需要 VS 2017 工具集兼容 | Visual Studio 2017 Build Tools(老版本,不建议新装) |
| 只需要 Windows SDK 和库,不编译 C++ | 单独安装 Windows SDK |
Build Tools 也允许你通过 VS Installer 勾选多个版本的 MSVC 工具集。比如你在安装 VS 2022 Build Tools 时,可以在单个组件里勾选 “MSVC v143 - VS 2022 C++ x64/x86 生成工具”,也可以额外勾选 “MSVC v142 - VS 2019 C++ x64/x86 生成工具”。这样同一个 Build Tools 里就能同时存在两套编译器,老项目新项目都能编。
2.2 安装包怎么下载
下载地址务必认准微软官方的 Visual Studio 下载页面,而不是第三方站点。你只需要找到 “所有下载” 或 “工具” 区域,里面有一项叫“Visual Studio 2022 生成工具”(或者英文版叫 “Build Tools for Visual Studio 2022”)。它的文件名形如:
vs_BuildTools.exe这个 exe 本身很小,只有几 MB,它只是一个引导安装器。真正的大头(几百 MB 到几 GB 的组件)会在安装过程中按需下载。所以下载vs_BuildTools.exe很快,安装过程耗时才比较长。
2.3 架构选择:x64 还是 x86
这里说的不是安装包架构,而是你要编译出的目标程序架构。Build Tools 本身支持一个安装包包含 x86、x64、ARM、ARM64 的编译器和链接器。在安装组件时你会看到:
- MSVC v143 - VS 2022 C++ x64/x86 生成工具
- MSVC v143 - VS 2022 C++ ARM64 生成工具
如果你是编译本机 Windows x64 程序,勾选第一个就够了。如果你还需要交叉编译 32 位程序,那个 x64/x86 的包通常同时包含 x86 和 x64 的本地工具,覆盖大多数场景。
我自己实际安装时选的是 “使用 C++ 的桌面开发” 工作负载,然后在右侧单个组件里关掉了很多用不到的东西,比如测试工具、C++ MFC、C++ ATL 等。如果你对组件不太熟,直接勾选 “使用 C++ 的桌面开发” 也行,它会带上大部分 C++ 开发需要的默认组件。
注意:不要图省事把 “使用 C++ 的桌面开发” 整个删减到只剩编译器。测试工具、CMake 工具等组件很多项目构建时会隐式依赖。
3. 实操:从零开始装好一套干净 MSVC 环境
3.1 图形界面安装流程
第一步:双击下载好的vs_BuildTools.exe。如果弹 UAC 授权窗口,点 “是”。
第二步:进入 Visual Studio Installer 的组件选择界面。这时候你会看到一个类似完整 VS 的安装界面,但它不会安装 IDE。在 “工作负载” 标签页里选择 “使用 C++ 的桌面开发”。
第三步:右侧 “安装详细信息” 面板里,建议确保这几项是被勾选的:
- MSVC v143 - VS 2022 C++ x64/x86 生成工具
- Windows 11 SDK(或 Windows 10 SDK,视系统而定)
- C++ CMake tools for Windows(如果你要用 CMake)
- 适用于最新 v143 生成工具的 C++ ATL(可选,一般不需要)
- C++ AddressSanitizer(可选,调试某些问题时有帮助)
如果只是最精简的编译环境,也可以只勾 “MSVC v143” 和 “Windows 11 SDK”,其余全部不选。但如果你想省事一点,建议至少加上 CMake tools,因为现在大量开源项目都用 CMake 构建,后面省得再手动装。
第四步:点击右下角 “安装”,等待下载和安装。整个过程耗时取决于网速,通常在 5 到 30 分钟之间。安装完成后,不需要打开任何 IDE,也不需要登录账号。直接进入下一步验证。
3.2 命令行静默安装
如果你的机器要批量安装,或者只是维护一个干净环境,命令行方式更高效。vs_BuildTools.exe支持各种参数:
vs_BuildTools.exe --installPath C:\BuildTools --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --quiet --wait解释一下参数:
--installPath:指定安装目录。注意这个目录不能和任何已安装的 Visual Studio 实例重复,建议用独立的目录如C:\BuildTools。--add Microsoft.VisualStudio.Workload.VCTools:添加 C++ 工具负载。--includeRecommended:包含该负载的推荐组件,相当于图形界面里默认打勾的那些。--quiet:静默模式,不显示 UI。--wait:让命令行进程等待安装完成,这样脚本能正确拿到退出码。
你还可以用--add多次添加单个组件,例如:
--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64 --add Microsoft.VisualStudio.Component.Windows11SDK.22621这样能用更精确的粒度来控制要装什么,体积也更小。装完之后脚本退出码为 0 说明安装成功,非 0 则失败。这个在 CI 自动化里非常常用。
我用这个方式在好几台云服务器和 TeamCity 构建代理上装过 MSVC 环境,比每次都开图形界面点要稳定得多。缺点是一次性安装参数写错后,排查会稍微麻烦一些,所以我建议先用图形界面手动装一次熟悉组件 ID,再写自动化脚本。
3.3 安装完成之后:目录结构长什么样
安装完成后,你的工具链默认分布在两个地方:
- 编译器和标准库:
C:\BuildTools\VC\Tools\MSVC\<版本号>\ - Windows SDK:通常装在
C:\Program Files (x86)\Windows Kits\10\
<版本号>是一个类似14.40.33807的目录名,里面还能看到bin\Hostx64\x64\cl.exe、include、lib等子目录。这个目录结构很有规律,以后排查找不到编译器时,先来这里找。
4. 装好之后怎么用:环境变量、CLion、VS Code 与 CMake
4.1 vcvars64.bat:MSVC 环境的关键入口
MSVC 不像 GCC 那样装完直接往 PATH 里扔一个gcc。如果你直接打开 cmd 敲cl,大概率会提示 “不是内部或外部命令”。这是 MSVC 的既定设计:不同架构、不同安装目录下,环境变量都不同,所以它提供了一个批处理脚本来统一设置环境。
这个脚本就藏在安装目录下:
C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat想开一个能直接用cl的终端,先运行:
call "C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat"运行完之后再敲cl,就能正常输出版本信息了。这个脚本会临时设置 PATH、INCLUDE、LIB 等环境变量,所以你不必手动去配置系统全局 PATH,也最好不要去配。因为 MSVC 的环境变量是按架构区分的,全局固定 PATH 容易搞乱。
提示:
vcvars64.bat适合 x64 原生编译;如果你需要编译 32 位程序,用vcvars32.bat;要搞 x64 交叉编译 x86 或 ARM,还有vcvarsx86_amd64.bat等变体。
4.2 第一个程序的完整编译实测
新建一个hello.c:
#include <stdio.h> int main(void) { printf("Hello MSVC without Visual Studio!\n"); return 0; }在已经加载过vcvars64.bat的 cmd 里执行:
cl hello.c正常情况下,你会看到cl.exe输出一行版本信息,然后生成hello.exe。直接运行它,就能看到打印结果。
如果想编译 C++ 和链接动态库,建议用cl /EHsc开启 C++ 异常处理,例如:
cl /EHsc /std:c++20 hello.cpp/std:c++20是 MSVC 指定 C++ 标准的参数;如果你要 C++17 就写/std:c++17。
4.3 让 CMake 找到 MSVC
单独敲cl只是开胃菜,真正高频的场景还是 CMake。CMake 找编译器的方式和平台关系很大,分两种情况。
情形一:你从 Visual Studio Command Prompt 或加载过 vcvars64.bat 的终端里运行 cmake
这时候 CMake 会直接继承现有的环境变量,自动找到 MSVC。比如:
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release cmake --build build情形二:你在普通命令提示符或 PowerShell 里运行 cmake
这种情况下 CMake 默认会尝试找 Visual Studio 实例,如果系统里装了 Build Tools,CMake 有能力自动发现它。但 CMake 的自动发现依赖 Visual Studio Installer 在注册表里写入的 instance 信息。Build Tools 装完后同样会写这个信息,所以多数情况下能被找到。
为了保险,你也可以显式指定 CMake 的生成器,或者直接指定编译器和工具链:
cmake -S . -B build -G "Visual Studio 17 2022" -A x64用-G "Visual Studio 17 2022"会让 CMake 生成一个 Visual Studio 解决方案(.sln)。虽然你没有装 Visual Studio IDE,但 CMake 生成的 sln 可以用MSBuild.exe来构建。Build Tools 里带了MSBuild.exe,它完全可以构建 sln 工程,只是没有图形界面而已。这种用法在 CI 上很常见。
如果你更习惯 Ninja,也可以指定:
cmake -S . -B build -G Ninja -DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl前提是你已经在一个加载过 MSVC 环境的终端里。
4.4 在 VS Code 里配置 C/C++ 开发
VS Code 配合 C/C++ 扩展是一个非常轻量又舒服的选择。装好 Build Tools 之后,不需要再装任何插件来模拟编译器,只需要在 VS Code 里正确指向编译器路径即可。
C/C++ 扩展的c_cpp_properties.json里,compilerPath可以设置成:
{ "compilerPath": "C:/BuildTools/VC/Tools/MSVC/14.40.33807/bin/Hostx64/x64/cl.exe" }不过这个路径里的具体版本号每次升级都会变,比较麻烦。更省事的办法是直接用“Developer Command Prompt”或“Developer PowerShell”启动 VS Code:
call "C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat" && code .这样 VS Code 继承的环境里已经有完整的 INCLUDE 和 LIB,C/C++ 扩展会自动检测到 cl.exe,根本不用手动配置路径。我在几台机器上都是这么干的,升级 MSVC 组件后也不受影响。
CLion 用户同理:Toolchain 里选择 Visual Studio,会自动检测到 Build Tools 安装实例。如果检测不到,再手动指定vcvars64.bat所在路径。
5. 可能踩的坑:高频报错与排查思路
5.1 “Cannot open include file: 'stdio.h': No such file or directory”
这个报错几乎每个刚装完 Build Tools 就手动敲cl的人都会遇到。原因很简单:你直接运行了cl.exe,但它不知道系统的 INCLUDE 路径在哪里,找不到 C 标准库头文件stdio.h和windows.h等。
解决办法就是在使用前先加载vcvars64.bat。如果加载了依然报错,先确认你的 Build Tools 安装目录是不是包含 Windows SDK 组件。有时候你只勾了 MSVC 工具集,没有勾 Windows SDK,就会导致标准库头文件不完整。图形界面里重新运行安装器,添加 “Windows 11 SDK” 或 “Windows 10 SDK” 组件后再试。
5.2 “LNK1104: cannot open file 'kernel32.lib'”
链接阶段的报错,本质和上一个类似:LIB 环境变量缺失。kernel32.lib位于 Windows SDK 的 lib 目录下。加载 vcvars64.bat 之后会自动设置,如果还是报这个错,多半是 SDK 组件没装,或者安装的是 SDK 但 vcvars64.bat 没有正确识别。重新检查 SDK 组件是否选中。
5.3 Build Tools 安装到一半,提示“无法安装”
常见原因有两个。一个是磁盘空间不足,Build Tools 完整安装占用可能超过 6 GB,C 盘如果剩不到 10 GB 容易中途失败。另一个是旧版本 Visual Studio Installer 的残留问题,比如之前装过 VS 2019 又卸载不干净。
排查步骤:
- 打开
C:\Program Files (x86)\Microsoft Visual Studio\Installer,运行setup.exe,强制更新 Visual Studio Installer 到最新版。 - 清理
%TEMP%目录。 - 尝试用管理员身份重新运行
vs_BuildTools.exe。 - 如果依旧失败,可以在安装命令行里加
--force参数(部分版本支持,不一定保证成功)。
5.4 编译出的程序在其他电脑上运行报缺少 DLL
MSVC 编译出的 exe 默认可能依赖动态运行库VCRUNTIME140.dll、MSVCP140.dll。目标机器没装 VC++ Redistributable 就会报错。解决办法有两种:
- 编译时使用静态链接运行库:MSVC 中对应
/MT参数(Release)或/MTd(Debug)。这样 exe 会包含运行时库,不需要目标机器额外装依赖。 - 也可以发布安装包时带上 “Microsoft Visual C++ Redistributable” 安装包,在目标机器上装一次。
在 CMake 里对应参数是:
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")不过要小心:静态链接运行库会让代码里如果同时混用了不同版本的 CRT,可能出现内存分配释放不匹配的问题。常规小工具用/MT省心,大型库项目要看上游是否支持静态 CRT。
5.5 想卸载 Build Tools 却找不到入口
由于 Build Tools 没有 GUI,很多人卸载时不知道去哪里。正确方式仍然是使用 Visual Studio Installer。
如果你当初安装时保留了 Visual Studio Installer,打开它,找到 “已安装” 列表里的 “Visual Studio Build Tools 2022”,点 “卸载” 或 “修改”。如果你不小心把 Visual Studio Installer 也删了,可以去微软官网重新下载vs_BuildTools.exe或vs_installer.exe,它会自动进入修改/卸载界面。
5.6 一个隐藏坑:PATH 里同时有 MinGW 的 gcc 和 MSVC
这是很多混合环境用户会遇到的问题。如果你之前装过 MinGW-w64,它的gcc.exe在 PATH 里,而 MSVC 的cl.exe不在 PATH(需要 vcvars64.bat 临时加入),那么 CMake 在普通终端里跑的时候大概率会优先用 MinGW,生成 Makefile 或用 Ninja 进行 GCC 编译,而你本意是想用 MSVC。
解决办法:在需要 MSVC 的终端里先加载 vcvars64.bat 再执行 cmake,并且用-G参数明确指定生成器;或者直接给 CMake 传-DCMAKE_C_COMPILER=cl -DCMAKE_CXX_COMPILER=cl。
5.7 MSVC 与 MinGW 的区别速查
既然热词里也总在对比 MSVC 和 MinGW,我顺带整理一下,帮助边用边判断:
| 对比项 | MSVC (Build Tools) | MinGW-w64 / GCC |
|---|---|---|
| 编译器 | cl.exe | gcc.exe / g++.exe |
| 默认 ABI | MSVC ABI,和 Windows 原生库兼容好 | GNU ABI,大量开源库直接源码编译也能跑 |
| 标准库 | MSVC STL | libstdc++(GCC) |
| 依赖运行时 | VCRUNTIME/MSVCP DLL,可静态链接 | libgcc/libstdc++ DLL,也可静态链接 |
| 调试器生态 | Windows 下常配合 VS 调试器或 WinDbg | GDB 生态更通用 |
| CMake 支持 | 可用 Visual Studio Generator 或 Ninja | 可用 MinGW Makefiles 或 Ninja |
| 对 Windows SDK 的兼容 | 官方支持,最优先 | 兼容性尚可,有时会有宏定义差异 |
| 适合场景 | Windows 桌面专属、调用 Win32 API、微软生态 | 跨平台可移植、开源项目、Linux 习惯 |
如果你主要是做跨平台项目,源码里用了很多 GCC 特性(比如__attribute__、特定内联汇编语法),那么 MSVC 会遇到编译错误,这时要么加兼容宏,要么直接用 MinGW。反过来说,如果你要调用 DirectX、Windows 原生 SDK 等 API,MSVC 更稳。
6. 一次完整的自动配置脚本:从零到 CMake 构建
最后分享一份我常用的 PowerShell 脚本,它可以在干净的 Windows 机器上静默安装 Build Tools 并构建一个 CMake 项目,非常适合拿到新机器后一键初始化环境。脚本里用到了最精简的组件 ID,适合 CI/CD:
# 1. 下载引导安装器 Invoke-WebRequest -Uri "https://aka.ms/vs/17/release/vs_BuildTools.exe" -OutFile "$env:TEMP\vs_BuildTools.exe" # 2. 静默安装 C++ 工具链和 Windows SDK $args = @( "--installPath", "C:\BuildTools", "--add", "Microsoft.VisualStudio.Workload.VCTools", "--includeRecommended", "--quiet", "--wait", "--norestart" ) $process = Start-Process -FilePath "$env:TEMP\vs_BuildTools.exe" -ArgumentList $args -Wait -PassThru if ($process.ExitCode -ne 0) { Write-Error "Build Tools 安装失败,退出码: $($process.ExitCode)" exit 1 } # 3. 在子进程中加载 vcvars64.bat 然后执行 cmake 构建 $cmd = 'call "C:\BuildTools\VC\Auxiliary\Build\vcvars64.bat" && cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release && cmake --build build' cmd /c $cmd注意--wait参数必须和-Wait配合,否则 PowerShell 脚本会在安装完成前继续执行,导致后续找不到编译器。这是我实际踩过的一个坑。
提醒:上面脚本里的
vcvars64.bat路径是默认安装目录。如果你自定义了--installPath,脚本路径也要改。
在 CI 里还有更规范的做法:直接用ilabs.vswhere这类工具去查找安装实例,自动解析对应的vcvars64.bat路径,而不是硬编码C:\BuildTools。但硬编码在小范围自用场景里最直观,没毛病。
7. 最后的几个小建议
根据我多次在纯净 Windows 环境、云服务器上安装 MSVC 的经验,再说几个细节操作习惯:
优先使用 vcvars64.bat,不要手动改系统环境变量。我见过一些人为了让cl全局可用,把 MSVC 的 bin 目录直接加到系统 PATH 里,结果要么是找不到头文件,要么就是升级工具链后路径失效。vsvars 脚本就是微软设计的正统用法,每次开一个编译终端执行一下成本很低。
安装时磁盘空间给足。我建议至少预留 10 GB 以上,别只看下载体积。实际安装后包含工具链、SDK、缓存,占用比你想象的大。
养成看 clang-cl 的习惯。Build Tools 里还自带clang-cl.exe,它本质上是 LLVM 的 clang 编译器,但接受了 MSVC 风格的命令行参数,并能复用 MSVC 的头文件和库。如果你想在保留 MSVC 生态的同时用上 clang 的诊断信息,可以试试。用法上也是先加载 vcvars64.bat,然后:
clang-cl /std:c++20 hello.cpp编译完的产物和cl生成的没本质区别。
升级时使用 Visual Studio Installer 定期检查。Build Tools 的更新逻辑和 Visual Studio 一样,都是在安装器里点 “更新”,千万别跑到官网手动下载新版本装到另一个目录,否则机器上会有两套 MSVC,CMake 偶尔会选到旧版,后期很头疼。
现在你可以在不碰 Visual Studio IDE 的情况下,用上完整、干净的 MSVC 工具链了。装完之后建议先跑一个最简单的 hello world,再跑一次 CMake 构建,确认整条链路没问题再开始正式项目。如果还有安装或使用上的具体报错,欢迎对照上面第 5 节逐条排查。