BenchmarkDotNet 从源码构建完全指南:Visual Studio 与命令行双方案详解
2026/9/23 12:08:26 网站建设 项目流程

BenchmarkDotNet 从源码构建完全指南:Visual Studio 与命令行双方案详解

【免费下载链接】BenchmarkDotNetPowerful .NET library for benchmarking项目地址: https://gitcode.com/gh_mirrors/be/BenchmarkDotNet

导读

本文讲解如何从源码构建 BenchmarkDotNet 这一 .NET 基准测试库。核心内容基于仓库 docs/articles/contributing/building.md 展开,并结合仓库根目录的 build.cmd、build/build.sh 以及build/BenchmarkDotNet.Build下的 Cake 构建工程源码,深入剖析构建系统的任务体系、依赖项与常用参数。读完本文,你将掌握两种官方推荐的构建方式:Visual Studio 图形界面构建与跨平台命令行构建,并能熟练使用build.cmd执行编译、测试、打包、文档生成、发布等各类构建任务。

构建方式总览

BenchmarkDotNet 仓库提供两条官方推荐的从源码构建路径:

  1. Visual Studio 方式:适合 Windows 上的交互式开发与调试,直接打开解决方案文件执行 Build。
  2. 命令行方式:基于 Cake(C# Make)的跨平台自动化构建,在 Windows、Linux、macOS 上使用同一套脚本与任务。

两种方式最终都依赖 .NET SDK 完成编译,命令行方式额外封装了依赖安装、任务编排与结果输出等自动化能力。

方式一:使用 Visual Studio 构建

环境准备

在开始前需要安装以下工具:

  • Visual Studio 与 tests/BenchmarkDotNet.IntegrationTests.FSharp/BenchmarkDotNet.IntegrationTests.FSharp.fsproj。
  • .NET 10 SDK 中确认,其指定了 SDK 版本10.0.400rollForwarddisable,即要求精确匹配该版本。

构建步骤

工具就绪后,构建非常简单:

  1. 打开位于仓库根目录的解决方案文件BenchmarkDotNet.slnx(注意是.slnx新型解决方案格式,不是传统的.sln)。
  2. 在 Visual Studio 中执行Build操作(Ctrl+Shift+B或菜单 Build → Build Solution)即可完成编译。

解决方案同时被 build/BenchmarkDotNet.Build/Runners/BuildRunner.cs 中的DotNetBuild调用引用,命令行方式与 IDE 方式构建的是同一套工程。

方式二:命令行构建(Cake 自动化)

构建系统的定位

命令行构建基于 Cake(C# Make),这是一个跨平台的构建自动化系统,使用 C# DSL 描述构建流程,可完成代码编译、文件/目录复制、单元测试运行、压缩打包以及 NuGet 包生成等任务。

值得注意的是,当前仓库的构建工程采用的是Cake Frosting模式——构建逻辑本身就是一段 C# 程序。入口在 build/BenchmarkDotNet.Build/Program.cs:

  • Program.Main先通过 CommandLineParser 解析用户输入的任务名与参数;
  • 然后使用CakeHost配合BuildContext运行对应的FrostingTask

每个构建任务都是一个继承FrostingTask<BuildContext>的类,通过[TaskName][TaskDescription]特性声明任务名与描述,通过[IsDependentOn]声明任务间的依赖关系,通过实现IHelpProvider提供该任务的帮助信息。

启动脚本:build.cmd

在仓库根目录执行 build.cmd 即可启动构建。该脚本本身是一个跨平台分发器:

  • 在 Windows 上,它调用 build/build.bat;
  • 在 Linux/macOS 上,它调用 build/build.sh。

当不带任何参数执行时,脚本会打印帮助信息,列出所有可用构建任务。这是探索构建能力的第一步,也是排查参数错误时的好帮手。

跨平台前置依赖

构建脚本根据操作系统有不同的前置依赖要求:

Windows

  • PowerShell 5 或更高版本
  • MSBuild 15.1 或更高版本
  • .NET Framework 4.6 或更高版本

Linux

  • Mono 5 或更高版本
  • fsharp 包
  • 运行 .NET Core SDK 所需的系统包:
    • gettext
    • libcurl4-openssl-dev
    • libicu-dev
    • libssl-dev
    • libunwind8

macOS

  • Mono 5 或更高版本
  • fsharp 包
  • 最新版本的 OpenSSL

需要说明的是,文档中列出的 Mono、OpenSSL 等传统依赖主要是为了支持旧版 .NET Framework / F# 场景;现代 .NET 编译链路由脚本自动安装的 .NET SDK 承担。

build.sh 的自动化引导逻辑

在 Linux/macOS 上,build/build.sh 会完成 SDK 的自动化引导:

  1. 设置环境变量(跳过首次体验、关闭遥测、指定 HTTP 处理器);
  2. 若仓库根目录下不存在.dotnet目录,则自动下载 dotnet-install.sh 指定的版本安装 SDK,同时额外安装 .NET 8 SDK(用于支持多目标框架测试);
  3. 将本地安装的 SDK 加入PATHDOTNET_ROOT
  4. 最后以 Release 配置运行dotnet run启动构建工程build/BenchmarkDotNet.Build/BenchmarkDotNet.Build.csproj,并把命令行参数透传进去。

这套引导逻辑保证了在全新机器上,即使尚未安装匹配版本的 .NET SDK,也能自动完成准备并进入构建流程。

构建任务清单与依赖关系

通过阅读 build/BenchmarkDotNet.Build/Program.cs 中的各个FrostingTask,可以整理出完整的任务清单。所有任务名与描述也会在build.cmd无参数执行时打印出来。

任务名描述关键依赖
build构建 BenchmarkDotNet.slnx 解决方案restore
restore还原 NuGet 包pack-weaver
pack-weaver打包 BenchmarkDotNet.Weaver(IL 织入器)
unit-tests运行单元测试(快速)build
analyzer-tests运行分析器测试build
in-tests-full使用 .NET Framework 4.7.2 运行集成测试(慢,仅 Windows)build
in-tests-core使用 .NET 10 运行集成测试(慢)build
all-tests运行全部单元、分析器与集成测试(慢)unit-testsanalyzer-testsin-tests-fullin-tests-core
build-analyzers构建 BenchmarkDotNet.Analyzers
move-analyzer-rules将已更新的分析器规则从未发布文件移至已发布文件
pack打包 NuGet 包buildbuild-analyzers
install-wasm-tools安装 wasm-tools workload
docs-fetch拉取更新变更日志文件
docs-generate生成辅助文档文件
docs-build构建最终文档docs-generate
version-increment递增当前版本号
release发布新版本buildpackdocs-fetchdocs-generatedocs-build

任务依赖关系在源码中以[IsDependentOn]特性声明,例如:

  • restore依赖pack-weaver——因为 Weaver 包的本地包必须先打出来,才能被解决方案还原引用;
  • unit-tests/analyzer-tests依赖build——先编译再测试;
  • pack同时依赖buildbuild-analyzers——打包主库与 Roslyn 分析器;
  • release是链路上的最终任务,聚合了构建、打包与文档生成。

典型用法示例

# 查看帮助与全部任务列表(无参数执行) build.cmd # 查看某个任务的帮助 build.cmd build --help # 还原 + 构建解决方案(默认 Release 配置) build.cmd build # 以 Debug 配置构建 build.cmd build /p:Configuration=Debug # 运行快速单元测试 build.cmd unit-tests # 只执行目标任务本身,跳过其依赖任务 build.cmd unit-tests --exclusive # 打包 NuGet 包,并指定版本前缀与后缀 build.cmd pack /p:VersionPrefix=0.1.1729 /p:VersionSuffix=preview # 打包稳定版本(去掉 VersionSuffix) build.cmd pack --stable # 安装 wasm-tools workload(用于构建 WebAssembly 相关工程) build.cmd install-wasm-tools

这些示例大多直接取自Program.cs中各个任务IHelpProvider.GetHelp()声明的Examples,是可以直接复制的真实用法。

常用命令行参数解析

构建脚本的参数解析逻辑位于 build/BenchmarkDotNet.Build/CommandLineParser.cs,支持的参数定义在 build/BenchmarkDotNet.Build/Options/KnownOptions.cs。解析器对任务名做了容错处理:忽略连字符且不区分大小写(例如unit-testsunittests等价);-t/--target可显式指定任务;以/p:开头的参数会被转换为 MSBuild 属性传入 Cake。

全局参数

参数别名说明
--verbosity <VALUE>-v控制输出信息量:Quiet / Minimal / Normal / Verbose / Diagnostic
--exclusive-e只执行目标任务本身,不执行其依赖任务
--help-h打印帮助信息(全局帮助或某个任务的帮助)
--stable-s移除 MSBuild 设置中的 VersionSuffix,用于打包正式版

任务专属参数

参数别名适用任务说明
--preview-pdocs-fetchdocs-generatedocs-build文档变更日志中包含即将发布的版本
--depth <VALUE>-ddocs-fetch需要重新生成变更日志的最近稳定版本数量,all表示全部,默认 0
--force-clone-fdocs-fetch强制重新克隆变更日志仓库,删除已有目录
--next-version <VALUE>-nversion-incrementrelease指定下一个版本号
--pushrelease指定后真正执行 GitHub 与 nuget.org 的推送

MSBuild 属性透传

所有任务都支持/p:<KEY>=<VALUE>语法将自定义属性透传给 MSBuild,例如:

build.cmd build /p:Configuration=Debug build.cmd pack /p:VersionPrefix=0.1.1729 /p:VersionSuffix=preview

从源码看,pack任务还会自动附加--include-symbols-p:SymbolPackageFormat=snupkg-p:IsFullPack=true等参数,用于同时产出源码符号包(snupkg),并保证与版本相关属性的一致性。

环境变量

部分任务需要环境变量配合,尤其是发布相关任务:

  • GitHubTokendocs-fetchrelease任务拉取/推送 GitHub 时使用;
  • NuGetTokenrelease任务向 nuget.org 推送时使用。

测试任务背后的工程映射

测试任务的工程映射可以在 build/BenchmarkDotNet.Build/Runners/UnitTestRunner.cs 中看到:

任务测试工程
unit-teststests/BenchmarkDotNet.Tests/BenchmarkDotNet.Tests.csproj 与 tests/BenchmarkDotNet.Exporters.Plotting.Tests/BenchmarkDotNet.Exporters.Plotting.Tests.csproj
analyzer-teststests/BenchmarkDotNet.Analyzers.Tests/BenchmarkDotNet.Analyzers.Tests.csproj
in-tests-full/in-tests-coretests/BenchmarkDotNet.IntegrationTests/BenchmarkDotNet.IntegrationTests.csproj

测试运行细节:

  • unit-tests按 Utils.GetTargetFrameworks 返回的目标框架列表逐框架执行;
  • in-tests-full使用net472目标框架,且仅当构建运行在 Windows 上(ShouldRun中判断IsRunningOnWindows)才执行;
  • in-tests-core使用net10.0目标框架;
  • 测试结果以 TRX 格式输出到仓库根目录的TestResults目录,文件名形如linux(x64)-unit-net10.0.trx,同时控制台会输出 detailed 级别的日志,便于 CI 归档与排查。

如果你只想快速验证某个改动,优先运行unit-tests;完整回归请运行all-tests(耗时较长,且集成测试需要实际启动子进程运行基准,务必在性能稳定的机器上执行)。

打包与发布流程

pack:产出 NuGet 包

pack任务会先清空输出目录,然后对 src 下所有可打包工程逐一执行dotnet pack,最终产物输出到artifacts目录。打包范围包括:

  • 主库 src/BenchmarkDotNet/BenchmarkDotNet.csproj
  • 注解库 src/BenchmarkDotNet.Annotations/BenchmarkDotNet.Annotations.csproj
  • Roslyn 分析器 src/BenchmarkDotNet.Analyzers/BenchmarkDotNet.Analyzers.csproj
  • 代码修复器 src/BenchmarkDotNet.CodeFixers/BenchmarkDotNet.CodeFixers.csproj
  • Windows 专属诊断器 src/BenchmarkDotNet.Diagnostics.Windows/BenchmarkDotNet.Diagnostics.Windows.csproj
  • dotMemory / dotTrace 集成、TestAdapter、Weaver 等其余可打包工程
  • 项目模板 templates/BenchmarkDotNet.Templates.csproj

主库打包时会附加-p:IsFullPack=true,并启用 snupkg 符号包输出。

release:一键发布

release任务串联了buildpackdocs-fetchdocs-generatedocs-build等前置任务,最终由 ReleaseRunner 执行发布。典型用法:

build.cmd release --stable --next-version 0.1.1729 --push

其中--push表示真正执行 GitHub 与 nuget.org 推送(省略时仅演练流程),同时需要配置GitHubTokenNuGetToken环境变量。

常见问题与排障建议

1. 无参数运行 build.cmd 报错或没反应?无参数运行会直接打印帮助信息而不是执行构建,这是预期行为。真正构建需要显式指定任务名,例如build.cmd build

2. 提示 SDK 版本不匹配?build/sdk/global.json 固定了 SDK 版本为10.0.400且禁止 rollForward。请安装对应版本的 .NET SDK,或使用build.sh让脚本自动下载安装到仓库内的.dotnet目录。

3. 任务名拼写不敏感但连字符很关键?解析器会忽略连字符与大小写差异,但为了可读性和帮助文档的一致性,建议按官方任务名书写。

4. 只想单独跑一个任务?使用--exclusive-e)跳过依赖任务。例如只想编译而不想重新还原时,可尝试build.cmd build --exclusive,但请确保此前已执行过restore

5. Linux 构建报缺少系统库?对照上文 Linux 前置依赖清单安装gettextlibcurl4-openssl-devlibicu-devlibssl-devlibunwind8等包(具体包名随发行版略有差异)。

6. 查看某个任务支持哪些参数?执行build.cmd <任务名> --help,例如build.cmd pack --help,会打印该任务的描述、示例、专属参数与环境变量要求。

延伸阅读

  • docs/articles/contributing/building.md:本文的原始依据文档;
  • docs/articles/contributing/running-tests.md:测试运行详解;
  • docs/articles/contributing/debugging.md:调试指南;
  • docs/articles/contributing/documentation.md:文档贡献说明;
  • tests/runCoreTests.sh 与 tests/runClassicTests.cmd:测试脚本的另一种快速入口。

【免费下载链接】BenchmarkDotNetPowerful .NET library for benchmarking项目地址: https://gitcode.com/gh_mirrors/be/BenchmarkDotNet

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询