首页
/ zstd 无 IDE 命令行构建指南:基于 Visual Studio 脚本体系的完整解析

zstd 无 IDE 命令行构建指南:基于 Visual Studio 脚本体系的完整解析

2026-09-14 22:05:56作者:裴锟轩Denise

本指南以 zstd 在 Visual Studio 环境下"无需打开 IDE、直接使用命令行脚本编译"的完整方案为主题,详细解析 build.generic.cmd 通用构建脚本、各 VS 版本专用包装脚本、平台工具集(Platform Toolset)选择与输出产物定位。该脚本体系位于本仓库 third-party/zstd/build/VS_scripts 目录,用于在 Windows 上以纯命令行方式编译 zstd 的静态库、动态库、zstd CLI、fuzzerfullbenchdatagen 工具。读完本文,你将能够在 VS2010 ~ VS2022(含 Preview)任一环境中,通过一条命令或精确传参完成指定架构、指定配置、指定 CRT 运行库的 zstd 构建,并理解脚本背后的 MSBuild 探测与参数传递机制。

一、脚本体系概览:为什么需要"无 IDE"构建

zstd 官方在 Windows 上的构建通常有 CMake、Meson 与 Visual Studio 工程三种途径,而 VS_scripts 目录提供的是一套轻量的纯批处理(.cmd)方案:不需要打开 Visual Studio 图形界面、不需要人工配置项目属性,直接调用 MSBuild 命令行编译既有的 .sln 解决方案。该方案对本仓库(mold 链接器)尤其具有参考价值——mold 自身通过 CMake 集成 zstd 作为压缩后端(见 CMakeLists.txt:在检测到 zstd.h 且未开启 MOLD_MOSTLY_STATIC 时链接系统 zstd,否则以 add_subdirectory(third-party/zstd/build/cmake) 方式静态编译 libzstd_static),因此理解 zstd 的多种构建形态,有助于在 Windows 交叉环境中正确产出可复用的 zstd 二进制。

脚本目录结构如下:

脚本文件 用途
build.generic.cmd 通用构建脚本,接受 4 个参数,是全部包装脚本的底层实现
build.VS2010.cmd VS2010 专用包装(Toolset v100)
build.VS2012.cmd VS2012 专用包装(Toolset v110)
build.VS2013.cmd VS2013 专用包装(Toolset v120)
build.VS2015.cmd VS2015 专用包装(Toolset v140)
build.VS2017.cmd VS2017 自动探测包装(Toolset v141,优先级 Enterprise > Professional > Community)
build.VS2017Enterprise.cmd / build.VS2017Professional.cmd / build.VS2017Community.cmd VS2017 指定版本包装
build.VSPreview.cmd VS 预览版(Preview)包装(Toolset v143)

所有脚本均位于 third-party/zstd/build/VS_scripts,共 10 个批处理文件,共同组成"通用引擎 + 版本外壳"的构建体系。

二、build.generic.cmd:通用构建引擎的四个参数

build.generic.cmd 是整套方案的核心引擎,其余脚本全部通过 call "%~p0%build.generic.cmd" ... 间接调用它。其完整语法为:

build.generic.cmd msbuild_version msbuild_platform msbuild_configuration msbuild_toolset

各参数含义(与脚本内置帮助文本一致,见 build.generic.cmd):

参数 含义 取值示例 默认值
msbuild_version Visual Studio 版本标识 latestVS2012VS2013VS2015VS2017VS2019VS2022preview 必填,缺失时打印帮助并退出
msbuild_platform 目标平台架构 x64Win32 x64
msbuild_configuration 构建配置 ReleaseDebug Release
msbuild_toolset 平台工具集(决定 CRT 运行库) v100v110v120v140v141v142v143 空(不传则沿用工程默认)

脚本入口处的默认值逻辑(build.generic.cmd):

IF "%1%" == "" GOTO display_help
SET msbuild_version=%1
SET msbuild_platform=%2
IF "%msbuild_platform%" == "" SET msbuild_platform=x64
SET msbuild_configuration=%3
IF "%msbuild_configuration%" == "" SET msbuild_configuration=Release
SET msbuild_toolset=%4

即:只要第一个参数为空,脚本就打印语法帮助并以退出码 1 结束;架构缺省为 x64,配置缺省为 Release

三、MSBuild 定位:固定路径与 vswhere 双轨机制

脚本选择 MSBuild 可执行文件时采用两条路径(build.generic.cmd):

  1. 固定路径兜底:默认回退到 .NET Framework 自带的 %windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe;对 VS2013 与 VS2015 分别硬编码了 %programfiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe%programfiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe
  2. vswhere 探测:对 VS2017 及更新版本,脚本借助 Visual Studio Installer 附带的 vswhere.exe,按版本区间与产品类型定位实际安装的 MSBuild:
IF %msbuild_version% == VS2017 SET vswhere_params=-version [15,16) -products *
IF %msbuild_version% == VS2017Community SET vswhere_params=-version [15,16) -products Community
IF %msbuild_version% == VS2017Enterprise SET vswhere_params=-version [15,16) -products Enterprise
IF %msbuild_version% == VS2017Professional SET vswhere_params=-version [15,16) -products Professional
IF %msbuild_version% == VS2019 SET vswhere_params=-version [16,17) -products *
IF %msbuild_version% == VS2022 SET vswhere_params=-version [17,18) -products *
REM Add the next Visual Studio version here.
IF %msbuild_version% == latest SET vswhere_params=-latest -products *
IF %msbuild_version% == preview SET vswhere_params=-prerelease -products *

这里 -version [15,16) 表示取 VS2017 主版本区间(15.x),-products * 表示任意产品(Community/Professional/Enterprise 均可),而 latest 取最新安装版本、preview 取预发布版本。随后通过 FOR 循环将 vswhere 输出的首个匹配 MSBuild 路径写入 msbuild 变量:

SET vswhere="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe"
FOR /F "USEBACKQ TOKENS=*" %%F IN (`%vswhere% !vswhere_params! -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe`) DO (
	SET msbuild="%%F"
)

-requires Microsoft.Component.MSBuild 确保只匹配安装了 MSBuild 组件的实例,-find 则在实例内定位真实的 MSBuild 可执行文件。这种设计使脚本无需用户手工配置环境变量即可自适应不同 VS 安装位置。

四、构建参数组装与产物输出位置

脚本将 msbuild、工程文件与参数组装后执行(build.generic.cmd):

SET project="%~p0\..\VS2010\zstd.sln"
SET msbuild_params=/verbosity:minimal /nologo /t:Clean,Build /p:Platform=%msbuild_platform% /p:Configuration=%msbuild_configuration%
IF NOT "%msbuild_toolset%" == "" SET msbuild_params=%msbuild_params% /p:PlatformToolset=%msbuild_toolset%
SET output=%~p0%bin
SET output="%output%/%msbuild_configuration%/%msbuild_platform%/"
SET msbuild_params=%msbuild_params% /p:OutDir=%output%

关键点:

  • 工程文件:所有版本统一使用 %~p0\..\VS2010\zstd.sln,即 third-party/zstd/build/VS2010/zstd.sln。这是一个跨版本兼容的解决方案文件,其中包含 6 个工程(依据 zstd.sln):zstd(CLI)、fuzzerfullbenchdatagenlibzstd(静态库)与 libzstd-dll(动态库)。这意味着运行一次构建即可同时产出 CLI、测试工具与两种形态的库。
  • /t:Clean,Build:先清理再构建,保证产物干净。
  • /p:PlatformToolset:仅当显式传入第 4 个参数时才追加,用于覆盖工程默认的工具集。
  • /p:OutDir:输出目录统一重定向到 build/VS_scripts/bin\{Configuration}\{Platform}\,即本仓库中 third-party/zstd/build/VS_scripts/bin/Release/Win32/bin/Release/x64/ 这类路径,便于在固定位置收集产物。

执行后脚本检查 ERRORLEVEL,失败则退出码为 1,成功则打印 # Success 与输出目录。

五、按 VS 版本构建:官方 README 实战命令全解

官方文档 VS_scripts/README.md 给出了三组典型用法,以下逐一展开并结合脚本源码解释其行为。

5.1 使用 Visual Studio 2013 构建(msvcr120.dll)

直接运行:

build.VS2013.cmd

将依次构建 Release Win32Release x64 两个版本,产物分别位于 bin\Release\Win32\bin\Release\x64\ 目录。其内部实现(build.VS2013.cmd)就是两次调用通用引擎:

call "%~p0%build.generic.cmd" VS2013 Win32 Release v120
call "%~p0%build.generic.cmd" VS2013 x64 Release v120

若只需单一架构,可绕过包装脚本直接传参:

  • Win32:build.generic.cmd VS2013 Win32 Release v120
  • x64:build.generic.cmd VS2013 x64 Release v120

需要 Debug 构建时,将 Release 替换为 Debug

  • Win32:build.generic.cmd VS2013 Win32 Debug v120
  • x64:build.generic.cmd VS2013 x64 Debug v120

注意这里 v120 工具集对应 VS2013,产物链接 msvcr120.dll 运行库。

5.2 使用 Visual Studio 2015 构建(msvcr140.dll)

直接运行:

build.VS2015.cmd

内部同样执行 Win32 与 x64 两轮构建(build.VS2015.cmd),工具集为 v140

call "%~p0%build.generic.cmd" VS2015 Win32 Release v140
call "%~p0%build.generic.cmd" VS2015 x64 Release v140

单架构与 Debug 变体:

  • Win32:build.generic.cmd VS2015 Win32 Release v140
  • x64:build.generic.cmd VS2015 x64 Release v140
  • Debug(以 Win32 为例):build.generic.cmd VS2015 Win32 Debug v140

5.3 用 VS2015 编译器构建 msvcr120.dll 兼容产物

当需要"新编译器、旧运行库"的组合(即用 VS2015 的 MSBuild 编译出链接 msvcr120.dll 的二进制,以兼容未安装 VC++ 2015 运行库的旧系统)时,直接给通用脚本传入 v120 工具集即可:

  • Win32:build.generic.cmd VS2015 Win32 Release v120,产物位于 bin\Release\Win32\
  • x64:build.generic.cmd VS2015 x64 Release v120,产物位于 bin\Release\x64\
  • Debug 同理,将 Release 替换为 Debug

这正是 msbuild_toolset 参数独立于 msbuild_version 的意义所在——编译器版本与平台工具集(CRT 目标)可以解耦。需要说明的是,这种"VS2015 + v120"组合要求系统已安装相应的旧工具集组件,脚本本身不负责安装。

5.4 使用 Visual Studio 2017 自动探测构建

build.VS2017.cmd

脚本会按 Enterprise > Professional > Community 的优先级自动选择本机安装的第一个 VS2017 变体并构建 Win32/x64 双架构(见 build.VS2017.cmd)。其版本标识 VS2017build.generic.cmd 中映射为 vswhere 参数 -version [15,16) -products *,即不限定产品类型、由 vswhere 按安装顺序返回。

若需锁定特定版本,则使用对应包装脚本:

build.VS2017Enterprise.cmd    rem 仅匹配 Enterprise
build.VS2017Professional.cmd  rem 仅匹配 Professional
build.VS2017Community.cmd     rem 仅匹配 Community

这三个脚本分别在 build.VS2017Enterprise.cmdbuild.VS2017Professional.cmdbuild.VS2017Community.cmd 中,将版本标识分别传入 VS2017Enterprise/VS2017Professional/VS2017Community,对应 vswhere 的 -products 过滤条件,全部使用 v141 工具集。

5.5 其他版本与 Preview

仓库还内置了更早与更新的包装脚本:

  • build.VS2010.cmdVS2010 Win32 Release v100 + VS2010 x64 Release v100
  • build.VS2012.cmdVS2012 Win32 Release v110 + VS2012 x64 Release v110
  • build.VSPreview.cmdpreview Win32 Release v143 + preview x64 Release v143,对应 vswhere 的 -prerelease 参数,适用于 VS 预览版(工具集 v143,与 VS2022 同代)

从脚本源码看,新增更高版本(如 VS2022 的独立包装)只需参照既有模式新增一个 .cmd 文件并仿照 build.generic.cmd 补充 vswhere_params 映射即可,脚本注释中明确保留了 REM Add the next Visual Studio version here. 的扩展位。

六、版本、平台与工具集对照速查

综合 README 与脚本源码,可整理出如下对照表,便于快速选参:

VS 版本 版本标识参数 平台工具集 对应 CRT 运行库
VS2010 VS2010 v100 msvcr100.dll
VS2012 VS2012 v110 msvcr110.dll
VS2013 VS2013 v120 msvcr120.dll
VS2015 VS2015 v140 msvcr140.dll
VS2017 VS2017 / VS2017Enterprise / VS2017Professional / VS2017Community v141 msvcp140.dll 系列
VS2019 VS2019 v142 通用 CRT(UCRT)
VS2022 / Preview VS2022 / preview v143 通用 CRT(UCRT)
最新版 latest 由 vswhere 决定

其中 VS2019VS2022latestpreview 虽未提供独立包装脚本,但均可直接通过 build.generic.cmd 使用(vswhere 映射已在 build.generic.cmd 中实现)。

七、使用前提与限制

  • 操作系统:本方案面向 Windows,脚本为批处理格式,需在 cmd 中执行;Linux/macOS 构建请使用仓库内 third-party/zstd/build/cmakethird-party/zstd/build/meson 方案。
  • 依赖组件:对应版本的 Visual Studio 必须已安装(含 MSBuild 与所选工具集);VS2017+ 需要 Visual Studio Installer 提供的 vswhere.exe(默认位于 %ProgramFiles(x86)%\Microsoft Visual Studio\Installer\);使用旧工具集(如 v120)需要对应组件已安装。
  • 跨工具集编译VS2015 + v120 这类组合依赖系统存在 v120 工具集,脚本只负责传参,不负责安装组件。
  • 产物验证:构建成功后,可在 third-party/zstd/build/VS_scripts/bin/{Configuration}/{Platform}/ 目录中按需取用 libzstd(静态库)、libzstd-dll(动态库与导入库)、zstd.exe(CLI)、fuzzer.exefullbench.exedatagen.exe,其中 CLI 与测试工具可借助仓库 third-party/zstd/tests 中的用例进行功能验证。

结语

zstd 的 VS 命令行构建脚本以"一个通用引擎 + 若干版本外壳"的极简架构,覆盖了 VS2010 到 VS2022/Preview 的完整工具链演进,并将架构(Win32/x64)、配置(Release/Debug)与 CRT 目标(工具集)三个维度解耦为独立参数。无论是要在本仓库中为 mold 的 zstd 压缩后端准备 Windows 静态库,还是在 CI 流水线中实现无界面构建,这套脚本体系都提供了可直接复用的范本。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
34
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.21 K
2.81 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
945
1.86 K
docsdocs
暂无描述
Markdown
906
5.84 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
537
607
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
864
1.36 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
4.28 K
1.03 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.39 K
1.48 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
550
401
flutter_flutterflutter_flutter
本仓库是 Flutter SDK 与 Flutter Engine 的 OpenHarmony 适配版本,由 CPF-Flutter 团队维护。开发者可使用熟悉的 Flutter 技术栈开发 OpenHarmony 应用,3.35.7 及以后的适配版本可基于本仓库源码构建支持 OpenHarmony 的 Flutter Engine。
Dart
1.19 K
347