news 2026/9/20 1:23:00

在 Windows 上构建与运行 CoreCLR 测试:runtime 仓库 `src\tests` 完整实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
在 Windows 上构建与运行 CoreCLR 测试:runtime 仓库 `src\tests` 完整实战指南

在 Windows 上构建与运行 CoreCLR 测试:runtime 仓库src\tests完整实战指南

【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址: https://gitcode.com/GitHub_Trending/runtime6/runtime

导读

本文聚焦 .NET runtime 仓库(CoreCLR 运行时)在 Windows 平台上的测试工作流:如何通过src\tests\build.cmd构建托管/原生测试组件、按优先级或子集筛选构建范围、生成 Core_Root 测试布局,并通过src\tests\run.cmd执行测试、定位失败原因。读完本文,你将掌握从"改一行测试代码"到"在本地 Windows 机器上完成单测复现"的完整闭环,并能结合仓库源码理解每一步背后的参数解析与产物目录规则。

前置准备:先构建运行时与库

在构建 CoreCLR 测试之前,需要先构建 runtime(clr子集)与 libraries(libs子集)。从源码结构看,测试构建产物与 CoreCLR 产品二进制、库程序集之间是强依赖关系:build.cmd生成 Core_Root 时会同时拷贝 coreclr 产品二进制与库程序集。若库未按预期配置构建,可通过/p:LibrariesConfiguration指定与默认Release不同的配置。

构建测试:入口脚本与默认行为

构建 CoreCLR 测试必须使用专用脚本,而不是dotnet test

src\tests\build.cmd

这一点在 src/tests/README.md 中被反复强调:此测试树驱动方式不同于dotnet test,错误工具会静默报告 "0 test projects" 或找不到 testhost。

脚本默认架构为x64、配置为Debug、目标 OS 为windows,这些默认值直接定义在 src/tests/build.cmd 中。默认情况下库使用Release配置;如需切换,通过 MSBuild 属性指定:

src\tests\build.cmd /p:LibrariesConfiguration=Debug

注意LibrariesConfiguration是直接透传给 MSBuild 的参数(build.cmd会把未识别参数原样传给 MSBuild,见 src/tests/build.cmd),因此必须带/p:前缀。同理,如果宿主(coreclr 产品)使用了不同的构建配置,可额外用/p:HostConfiguration指定。

其他常用顶层参数(均来自 src/tests/build.cmd 的参数解析逻辑):

参数作用默认值
x64/x86/arm64/wasm构建架构x64
debug/checked/release构建配置Debug
os <value>目标 OS(如 linux、osx、browser、wasi)windows
-Rebuild清理测试产物后重建
-SkipRestorePackages跳过包还原
-SkipManaged跳过托管测试构建
-SkipNative跳过原生测试构建
-SkipGenerateLayout跳过 Core_Root 布局生成
-GenerateLayoutOnly仅生成 Core_Root 布局
-MSBuild使用 MSBuild 代替默认的 Ninja
-Crossgen2用 Crossgen2 预编译 coreroot 中的框架程序集
-Composite使用 Crossgen2 复合模式(整个框架编译为单个 R2R 库)
-PDB预编译时生成 PDB
-PerfmapCrossgen2 编译时输出 perfmap 符号
-NativeAOT按 Native AOT 编译方式构建测试
-Mono/-CoreCLR选择运行时口味CoreCLR
-fsanitize <s>用指定原生 sanitizer 构建原生测试组件
--之后所有参数直接透传 MSBuild

仅构建原生测试组件

当你只想构建原生(native)测试组件而不构建托管部分时,传递skipmanagedskipgeneratelayout

src\tests\build.cmd skipmanaged skipgeneratelayout

从源码实现看,skipmanaged会跳过托管测试构建,skipgeneratelayout会跳过 Core_Root 布局生成(见 src/tests/build.cmd),二者组合后脚本只执行原生部分:调用eng\native\gen-buildsys.cmd生成 CMake 工程(默认走 Ninja),再执行cmake --build ... --target install完成原生组件安装(见 src/tests/build.cmd)。因为原生测试组件总体构建代价不大,官方建议在任何托管测试构建之前先完整执行一次原生构建。

C++/CLI 原生测试组件:使用 live ref assemblies

默认情况下,C++/CLI 原生测试组件基于仓库根目录 global.json 指定的 SDK 中的 ref pack 构建。若希望改为针对本次构建产出的 ref assemblies 编译,向测试构建传递 CMake 参数:

src\tests\build.cmd skipmanaged -cmakeargs -DCPP_CLI_LIVE_REF_ASSEMBLIES=1

在 src/tests/build.cmd 中,-cmakeargs被解析为CMakeArgs并拼入__CMakeArgs,随后在原生构建阶段随gen-buildsys.cmd一并传入 CMake,最终以-DCMAKE_BUILD_RUNTIME_FLAVOR=CoreCLR等参数一起生效(见 src/tests/build.cmd)。

构建预编译(Crossgen)测试

src\tests\build.cmd crossgen

该命令使用crossgen.exe在测试可执行文件运行前将其预编译(即 ReadyToRun 化)。注意脚本中实际存在的是crossgen2(见 src/tests/build.cmd),它设置__TestBuildMode=crossgen2,会预编译 coreroot 中的框架托管程序集;可配合-PDB生成 PDB、-Perfmap生成符号映射。构建完成后,coreroot 内即包含预编译产物,运行测试时会直接执行 R2R 镜像。

按优先级构建测试

src\tests\build.cmd -priority=1

优先级语义是累积式的:-priority=1会同时构建CLRTestPriority01的测试。默认优先级为0。该逻辑在 src/tests/Directory.Build.props 中实现:命令行指定的__Priority被映射为 MSBuild 属性CLRTestPriorityToBuild,满足CLRTestPriority <= CLRTestPriorityToBuild的测试才会被构建(666表示构建全部)。测试自身的优先级在各自.csproj中通过<CLRTestPriority>设置,未显式声明时默认为 0,详见 docs/workflow/testing/coreclr/test-configuration.md。

生成 Core_Root

src\tests\build.cmd会生成 Core_Root 目录,其中包含运行测试所需的测试宿主corerun、库程序集以及 coreclr 产品二进制。若只想生成 Core_Root 而不构建测试:

src\tests\build.cmd generatelayoutonly

输出位于:

<repo_root>\artifacts\tests\coreclr\windows.<arch>.<configuration>\Tests\Core_Root

例如 x64 Checked 配置为:<repo_root>\artifacts\tests\coreclr\windows.x64.Checked\Tests\Core_Root

从 src/tests/build.cmd 可见,generatelayoutonly会同时置位SkipManagedSkipNative并跳过原生拷贝,仅执行布局生成阶段。布局生成要求先构建过libs子集;若库不是Release配置,需同步传入/p:LibrariesConfiguration=<config>,否则布局中的库程序集会与预期不符。Core_Root 也是运行单个测试(见下文)所必需的环境,可通过CORE_ROOT环境变量或-coreroot参数引用。

常用组合示例

:: 构建 crossgen 预编译的 priority 0 和 1 测试 src\tests\build.cmd crossgen -priority=1 :: 为 x86 release 仅生成 Core_Root,不构建测试 src\tests\build.cmd x86 Release generatelayoutonly

查看build.cmd支持的全部参数:

src\tests\build.cmd -?

脚本内置的-TestArgParsing开关还可以在不真正构建的情况下打印参数解析结果,便于排查参数拼写问题(见 src/tests/build.cmd)。

构建测试子集:test/dir/tree

不指定任何子集时,src\tests下的整棵测试树都会被构建,这在-priority=1模式下非常耗时。build.cmd提供三种限定范围的选项,且均可重复指定或一次传多个以分号分隔的路径:

1)test <test-project>—— 构建指定测试项目(路径可为绝对路径或相对src\tests的路径):

src\tests\build.cmd test JIT/Methodical/divrem/div/i4div_cs_do.csproj;JIT/Methodical/divrem/div/i8div_cs_do.csproj

(仓库当前该目录下实际以源码文件i4div.csi8div.cs等组织,见 src/tests/JIT/Methodical/divrem/div;项目文件位于上层聚合目录。)

2)dir <test-folder>—— 构建指定目录下的全部测试项目:

src\tests\build.cmd dir JIT/Methodical/Arrays/huge;JIT/Methodical/divrem/div

3)tree <root-folder>—— 构建指定子树根路径下的全部测试项目:

src\tests\build.cmd tree baseservices/exceptions;JIT/Methodical

参数解析实现在 src/tests/build.cmd:test/dir/tree各自累积到__BuildTestProject/__BuildTestDir/__BuildTestTree,最终作为 MSBuild 属性参与构建。

重要提醒:优先级过滤与子集选择是正交的。即使你指定构建某个具体测试,只要它是 Pri1 且命令行未带-priority=1,该测试就会被跳过——从 src/tests/Directory.Build.props 的实现看,优先级过滤发生在子集确定之后。这是当前设计(官方希望长期内最终移除优先级机制),因此务必记得为 Pri1+ 测试显式补充-priority

构建单个测试

前置条件:如果单个测试带原生资源,需要先至少执行一次build.cmd skipmanaged [其他参数]

  • 原生测试:构建与测试 cmake 文件对应的生成的 Visual Studio 解决方案或 makefile。
  • 托管测试:直接使用仓库根目录的dotnet.cmd对测试项目执行构建:
dotnet.cmd build -c <Configuration> src\tests\path\to\test.csproj

除测试程序集外,构建还会在测试输出目录中为测试生成一个.cmd脚本(即测试入口点)。测试输出目录位于<repo_root>\artifacts\tests\coreclr\windows.<arch>.<configuration>之下、按测试在源码中的位置对应的子路径中,例如带原生组件的 src/tests/Exceptions/ForeignThread/ForeignThreadExceptions.csproj 这类项目会在对应目录生成ForeignThreadExceptions.cmd

运行全部测试

run.cmd支持的所有参数可以通过帮助查看:

src\tests\run.cmd /?

使用 Checked 构建运行全部测试:

src\tests\run.cmd checked

运行完成后会生成名为TestRun_<arch>_<flavor>.html的报告(例如TestRun_windows_x64_Checked.html),位于<repo_root>\artifacts\log子目录;所有失败测试会列在TestRunResults_windows_x64_Checked.err中。

从 src/tests/run.cmd 的解析逻辑看,run.cmd支持架构(x64/x86/arm64/wasm)与配置(debug/release/checked)位置参数,此外还提供大量实用开关:

开关作用
jitstress <n>DOTNET_JitStress=n运行
jitstressregs <n>DOTNET_JitStressRegs=n运行
jitminoptsDOTNET_JITMinOpts=1运行
jitforcerelocsDOTNET_ForceRelocs=1运行
gcname <name>DOTNET_GCName=name运行
gcstresslevel <n>DOTNET_GCStress=n运行(n 为位掩码:1=所有分配处 GC,2=进入抢占式 GC 时,4=每个可 JIT 指令,8=每个可 NGEN 指令,16=仅唯一栈路径;须以十六进制表达)
gcsimulator运行 GC Simulator 测试
longgc运行长时间 GC 测试
ilasmroundtrip对测试执行 ilasm 往返
timeout <n>单测试超时毫秒数(默认 600000,即 10 分钟;部分开关会覆盖它)
sequential/parallel <type>顺序执行 / 并行级别(none、collections、assemblies、all,默认 collections)
printlastresultsonly不运行测试,仅打印上次结果
runincontext在可卸载的 AssemblyLoadContext 中运行每个测试
tree <path>仅运行指定子树下的测试(如JIT/Regression
runcrossgen2tests运行 Crossgen2 编译的 ReadyToRun 测试
interpreter/node启用解释器 / 使用 NodeJS(wasm)
<CORE_ROOT>显式指定待测运行时路径

run.cmd最终会把参数转发给src\tests\run.py执行(见 src/tests/run.cmd)。

调查测试失败

测试运行结束后可能有一个或多个测试失败。测试输出位于 Reports 目录,默认形如:

<repo_root>\artifacts\tests\coreclr\windows.x64.Checked\Reports\Exceptions\Finalization

其中有两个关键文件:

  • Finalizer.output.txt—— 测试自身记录的全部日志信息;
  • Finalizer.error.txt—— 测试进程崩溃时由 CoreRun.exe 报告的崩溃信息。

要重跑失败的测试,按"运行单个测试"一节操作即可;失败测试的报告会包含其确切的运行命令,例如:

<repo_root>\artifacts\tests\coreclr\windows.x64.Checked\Exceptions\Finalization\Finalizer.cmd

这给了你"精确复现"的入口:直接执行该.cmd,或在调试器下执行它定位崩溃点。

运行单个测试

先按上文"构建单个测试"构建目标测试,然后:

  1. CORE_ROOT环境变量设置为 Core_Root 目录:
set CORE_ROOT=<repo_root>\artifacts\tests\coreclr\windows.x64.Checked\Tests\Core_Root
  1. 运行测试生成的.cmd脚本:
<test_output_dir>\<TestName>.cmd

如果想在调试器(例如 WinDbg)下运行,向测试命令追加-debug <debuggerFullPath>

<TestName>.cmd -debug C:\path\to\windbg.exe

这些.cmd入口脚本的参数与corerun基本一致(-debug-env-coreroot),其中-coreroot可替代环境变量CORE_ROOT显式指定运行时布局;相关说明可参考 docs/workflow/testing/using-corerun-and-coreroot.md。

修改测试并复现

当测试需要改动时,流程是:修改测试源码 → 重新构建该测试项目 → 二进制会被 binplace 到测试二进制目录(例如<repo_root>\artifacts\tests\coreclr\windows.x64.Checked\Exceptions\Finalization)→ 按上文方式重新运行。

如果要新增测试,可参考 docs/workflow/testing/coreclr/test-configuration.md 中的创建指南:以现有项目为模板、移除<AssemblyName>、设置<CLRTestKind>/<CLRTestPriority>、通过 XunitFact特性或自定义Main(成功返回100,失败返回非100)编写用例。测试树中大量测试通过<RequiresProcessIsolation>true</RequiresProcessIsolation>标记为独立进程运行,或通过<Import Project="$(TestSourceDir)MergedTestRunner.targets" />归入合并运行器,选择哪个入口取决于测试项目的声明方式——具体判定步骤见 docs/workflow/testing/coreclr/testing.md。

常见问题速查

  • 构建测试报 "0 test projects":检查是否遗漏了-priority=1(针对 Pri1 测试)或误用了dotnet test而非build.cmd/build.sh
  • 运行单个测试找不到运行时:确认CORE_ROOT已设置或传了-coreroot,且 Core_Root 是通过generatelayoutonly/完整构建生成的有效布局。
  • 测试失败但想看崩溃现场:查看Reports目录下的*.error.txt,并用-debug <debuggerFullPath>重跑。
  • C++/CLI 组件链接到旧 ref 程序集:用-cmakeargs -DCPP_CLI_LIVE_REF_ASSEMBLIES=1切换到本次构建产出的 ref assemblies。
  • 希望控制构建/运行范围:构建用test/dir/tree子集,运行用tree <path>限定,二者都别忘了优先级参数。

【免费下载链接】runtime.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.项目地址: https://gitcode.com/GitHub_Trending/runtime6/runtime

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 1:21:29

基于Jetson NANO与YOLOv5的智能门店访客计数系统实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/20 1:19:47

Jsoup解析完整的HTML

^^ 《榴芒客服系统》是我们工作室开发的在线客服系统&#xff0c;欢迎下载试用&#xff1a; 《榴芒客服系统》https://blog.csdn.net/look4liming/article/details/164755808 import org.jsoup.Jsoup; import org.jsoup.nodes.Document;public class JsoupParserTest {public s…

作者头像 李华
网站建设 2026/9/20 1:18:44

Python中如何安装pandas库:Windows、macOS、Linux全平台安装指南

1. 为什么每个数据分析新手都绕不开pandas这一关刚接触Python数据分析的人&#xff0c;十有八九遇到的第一个拦路虎不是语法&#xff0c;而是装库。你可能已经跟着教程敲下了import pandas as pd&#xff0c;结果终端毫不留情地甩出一行红字&#xff1a;ModuleNotFoundError: N…

作者头像 李华
网站建设 2026/9/20 1:18:34

DSH接入SpreadJS MCP全流程:Token配置与工具调用避坑指南

把 DeepSeek Harness&#xff08;DSH&#xff09;接到 SpreadJS MCP 这件事&#xff0c;我前前后后折腾了一个下午&#xff0c;最后发现真正的难点根本不在 MCP 配置&#xff0c;而在 Token 那一环。中间踩过dsh web authentication required、plugin tree failed to load这些坑…

作者头像 李华
网站建设 2026/9/20 1:18:22

用Anki把物理复习PDF变成高效自测卡片的完整方案

简介&#xff1a;大连理工大学大学物理期中复习题&#xff08;含答案&#xff09;为一份面向电磁学部分的备考资料&#xff0c;适合正在准备期中考试或需要夯实电学、磁学基础概念与计算能力的学生使用。资料为单个PDF文件&#xff0c;大小仅584KB&#xff0c;便于在电脑、平板…

作者头像 李华