- 语言运行时
- 标准库
- JIT编译
- 编译器
【免费下载链接】runtime
.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
本篇指南以 dotnet/runtime(即当前GitHub_Trending/runtime6/runtime仓库)的 Libraries 构建文档 为核心,完整讲解在 .NET runtime 仓库中编译src/libraries下托管库的完整流程。你将掌握:构建脚本与子集(subset)体系的用法、Debug/Release 与跨平台参数组合、单个库的内循环构建与测试、System.Private.CoreLib迭代、Mono 目标、Native 组件与 sanitizer 构建、静态分析与 ILLink 验证,以及打包和 APICompat 校验——并顺带通过 eng/Subsets.props 等构建定义理解这些命令背后的机制。
快速开始:面向 Libraries 开发者的日常内循环
src/libraries下的库(如System.Collections.Concurrent)依赖运行时才能运行,因此工作流的第一步通常是从仓库根目录构建一次「Release 运行时 + Debug 库」的组合,之后大部分时间只需在单个库的目录里做内循环编译与测试。
以下是一个典型的 Windows 开发者日常流程(摘自 docs/workflow/building/libraries/README.md):
:: 在仓库根目录执行 git clean -xdf git pull upstream main & git push origin main :: 在 Release 运行时之上构建 Debug 库 build.cmd clr+libs -rc Release :: 上述操作通常每天只需一次,或在拉取重大变更后再执行 :: 若使用 Visual Studio,可在这里打开 System.Collections.Concurrent.slnx build.cmd -vs System.Collections.Concurrent :: 切换到要开发的库目录 cd src\libraries\System.Collections.Concurrent :: 切换到测试目录 cd tests :: 内循环构建 / 测试 :: (若使用 Visual Studio,也可以在 IDE 内直接运行测试) pushd ..\src & dotnet build & popd & dotnet build /t:testUnix 系操作系统的步骤基本相同(build.sh 是仓库根的构建入口):
#!/usr/bin/env bash # 在仓库根目录执行 git clean -xdf git pull upstream main; git push origin main # 在 Release 运行时之上构建 Debug 库 ./build.sh clr+libs -rc Release # 上述操作通常每天只需一次,或在拉取重大变更后再执行 # 切换到要开发的库目录 cd src/libraries/System.Collections.Concurrent # 切换到测试目录 cd tests # 内循环构建 / 测试 pushd ../src; dotnet build; popd; dotnet build /t:test核心思想很明确:运行时(CoreCLR/Mono)用 Release,库用 Debug。Release 运行时保证了迭代时测试执行的速度,Debug 库则提供最好的源码级调试体验。上述步骤已经覆盖了绝大多数「改一行代码 → 编译 → 跑测试」的场景。
构建之前:先理解配置(Configuration)概念
在动手构建 Libraries 之前,需要先弄清 runtime 仓库支持的三种构建配置。根据 docs/workflow/README.md:
| 配置 | 说明 |
|---|---|
| Debug | 非优化代码,断言(asserts)启用,运行最慢,但调试体验最佳。 |
| Checked(仅 CoreCLR 运行时) | 优化代码,断言启用。 |
| Release | 优化代码,断言禁用,运行速度最快,适合性能分析;但由于编译器优化,调试器中的信息还原度较差。 |
Libraries 与运行时(CoreCLR/Mono)是独立组件,可以各自采用不同配置。顶层构建脚本用三个特定标志分别控制各组件配置:
-runtimeConfiguration/-rc:CoreCLR 构建配置;-librariesConfiguration/-lc:Libraries 构建配置;-hostConfiguration/-hc:Host 构建配置。
通用配置标志-c会作用于所有「未被更具体标志限定」的子集。例如./build.sh -subset clr+libs -configuration Release -runtimeConfiguration Debug表示库用 Release、运行时用 Debug;而./build.sh -subset clr+libs -configuration Release则两者都是 Release。
构建全部 Libraries:一条命令与它的四个关键参数
构建整个 Libraries 组件(连同运行时)最直接的方式,是从仓库根目录执行:
# Linux / macOS ./build.sh -rc Release:: Windows build.cmd -rc Release这会构建Release 的 CoreCLR(含 System.Private.CoreLib)、Debug 的库、以及 Debug 的安装器。
构建脚本的默认参数值以及可通过-前缀传入的快捷属性如下(msbuild 属性名见括号内):
| 参数 | 作用 | 可选值 | 默认值 |
|---|---|---|---|
-framework/-f | 目标框架(BuildTargetFramework) | net11.0(当前最新 .NET 版本)、net481(最新 .NET Framework 版本)等 | 依据环境推断 |
-os | 目标操作系统(TargetOS) | windows、unix、linux、osx等 | 当前运行的操作系统 |
-configuration/-c | 编译器的优化级别(Configuration) | Debug、Release | Debug |
-arch | 目标架构(TargetArchitecture) | x64、x86、arm、arm64 | x64 |
更多构建枢轴(build pivots)细节见 project-guidelines。
Libraries 构建在逻辑上分为两个部分:
- Native 构建:产出「shims」(在操作系统与托管代码之间提供稳定接口的本地适配层,覆盖 libc、openssl、gssapi、zlib 等);
- Managed 构建:产出构成 Libraries 的 MSIL 代码与 NuGet 包。
上述命令会同时构建这两部分。若不传任何 action,构建脚本默认执行-restore -build动作链。
子集(Subset)体系:libs、libs.tests、libs.pretest从哪来
libs不是单一任务,而是多个子集的聚合。在 eng/Subsets.props 中可以找到其展开定义:
<DefaultLibrariesSubsets Condition="...">libs.native+</DefaultLibrariesSubsets> <DefaultLibrariesSubsets>$(DefaultLibrariesSubsets)libs.sfx+libs.oob+libs.pretest</DefaultLibrariesSubsets> <DefaultLibrariesSubsets Condition="'$(DotNetBuildTests)' == 'true'">$(DefaultLibrariesSubsets)+libs.tests</DefaultLibrariesSubsets>即libs默认展开为libs.native + libs.sfx + libs.oob + libs.pretest(libs.tests仅在DotNetBuildTests=true时追加)。这些子集在 eng/Subsets.props 中分别映射到具体项目:
libs.native→src/native/libs/build-native.proj;libs.sfx→src/libraries/sfx.proj(共享框架,仅在构建当前 .NET 版本时启用);libs.oob→src/libraries/oob.proj(Out-of-Band 库);libs.pretest→src/libraries/pretest.proj(测试宿主准备,包括复制System.Private.CoreLib到 testhost);libs.tests→src/libraries/tests.proj(测试项目,带Test="true"标记)。
需要强调的是:默认情况下
libs只构建产品库,不构建任何测试。要包含测试需追加libs.tests;要运行测试则用-testaction 代替-build,例如build.cmd/sh libs.tests -test。若只想构建库本身,用libs即可。
常用示例
# Release 模式、x64 平台构建(未传 action,restore 与 build 隐式执行) ./build.sh libs -c Release -arch x64 # 构建 src 程序集,并构建与运行测试(运行全部测试耗时相当可观!) ./build.sh libs -test # 清理整个 artifacts 文件夹 ./build.sh -cleanWindows 下只需把./build.sh换成build.cmd即可,其余参数完全一致。
使用 Native Sanitizer 构建 Libraries
Libraries 的原生组件可以接入 AddressSanitizer 等内存安全检测工具,帮助提前发现内存问题。构建时在脚本后追加-fsanitize参数:
build.sh -s libs -fsanitize address需要特别留意:一旦启用任一种 sanitizer,仓库内所有 native 组件都必须用同一组 sanitizer 构建,否则检测结果会失真。
只构建 Native 组件
Libraries 构建包含一部分 Native 代码(libc、openssl、gssapi、zlib 之上的 shims)。构建系统使用 CMake 生成 Makefile(编译器为 clang),并使用 git 生成部分版本信息。独立构建脚本位于 src/native/libs/build-native.sh(Windows 对应build-native.cmd),其默认参数为x64架构、linux目标 OS、Debug配置、clang 编译器。
示例:
# Debug 模式、x64 平台 ./src/native/libs/build-native.sh debug x64 # 构建并更新 binplace(例如 testhost),迭代 native 组件时必需 dotnet.sh build src/native/libs/build-native.proj # ARM 交叉编译 ./src/native/libs/build-native.sh debug arm cross verbosesrc/native/libs/build-native.proj与 eng/Subsets.props 中libs.native子集的映射指向一致,说明通过./build.sh libs构建时,native 部分最终走的也是这条 CMake + clang 的管线。
构建单个库:按目录结构定点构建
与根目录的build.cmd/build.sh类似,你可以直接传入目录路径让构建系统递归构建该目录下的所有项目;对于 Libraries 还支持省略根src文件夹的快捷路径。
示例:
# 构建某个库(如 System.Collections)的全部项目,并运行其测试 ./build.sh -projects src/libraries/*/System.Collections.slnx # 只构建某个库项目的测试 ./build.sh -projects src/libraries/System.Collections/tests/*.csproj # 上述所有参数(framework、configuration 等)同样可用(注意需放在目录之后) ./build.sh -projects src/libraries/*/System.Collections.slnx -f net472 -c Release由于dotnet build在 Unix 与 Windows 上行为一致且会隐式调用 restore,本指南后续统一使用dotnet build展开讲解。
src下每个目录对应 Libraries 中的一个具体程序集(assembly)。例如src/libraries/System.Diagnostics.DiagnosticSource目录存放System.Diagnostics.DiagnosticSource.dll的源码。进入其src子目录执行dotnet build即可产出该 DLL,产物会同时出现在:
artifacts/bin/System.Diagnostics.DiagnosticSourceartifacts/bin/runtime/[$(BuildTargetFramework)-$(TargetOS)-$(Configuration)-$(TargetArchitecture)]
测试则进入对应tests子目录执行dotnet build。部分库还带有ref(参考程序集)与pkg(打包)目录,同样用dotnet build构建。关于目录结构的详细约定,参见 project-guidelines 的 Library Project Guidelines 章节。
对于多目标框架(multi-target)的库,目标框架列表定义在<TargetFrameworks>属性组中;构建时系统会从列表里挑选与BuildTargetFramework最兼容的框架并设为当前构建框架。
带属性的构建示例:
# 为 Linux 构建 dotnet build System.Net.NetworkInformation.csproj /p:TargetOS=linux # 构建 Release 版本 dotnet build -c Release System.Net.NetworkInformation.csproj迭代 System.Private.CoreLib:用 libs.pretest 同步 testhost
System.Private.CoreLib是直接与运行时绑定的最底层托管库,其运行时无关部分源码位于 src/libraries/System.Private.CoreLib/src。修改它之后,普通libs构建不会自动把它复制进 testhost——测试运行时会从 testhost 目录加载二进制,因此必须显式构建libs.pretest子集来完成 testhost 准备(这正是 eng/Subsets.props 中libs.pretest→pretest.proj映射的作用,可参见 docs/workflow/testing/libraries/testing.md 的说明)。
先完成一次运行时构建:
build.cmd clr -rc Release然后按如下方式迭代System.Private.CoreLib:
build.cmd clr.corelib+clr.nativecorelib+libs.pretest -rc Release这条命令的含义在 eng/Subsets.props 中有明确定义:clr.corelib构建 CoreCLR 版本的托管System.Private.CoreLib,clr.nativecorelib对其运行 crossgen。当该System.Private.CoreLib以 Release 模式构建时,会被 crossgen 预编译,同时 testhost 会被更新到最新版 corelib。Mono 运行时使用同一工作流,只需把子集换成mono.corelib+libs.pretest。
面向 Mono 构建
默认情况下 Libraries 针对 CoreCLR 版本的System.Private.CoreLib.dll构建。如需改为 Mono 版本,追加/p:RuntimeFlavor=Mono参数:
build.cmd libs /p:RuntimeFlavor=Mono注意:按 docs/workflow/README.md 的说明,CoreLib 必须与运行时使用匹配的配置(如 Debug 运行时对应 Debug CoreLib);clr子集已同时包含运行时与 CoreLib,因此常规场景无需单独操心这一点。
跨操作系统、跨配置、跨架构构建
- 跨 OS:根目录构建默认只针对当前运行的操作系统。可通过
./build.sh libs -os [value]为其他 OS 构建。需要留意:一般无法为其他 OS 构建 native 组件,但 managed 组件可以;如需在单个项目级或全量构建中跳过 native,可传/p:BuildNative=false。 - Release / Debug:根目录或项目内构建默认均为 Debug。根目录切换为
./build.sh libs -c Release即可。 - 其他架构:根目录用
./build.sh libs -arch [value],项目级在dotnet build后追加/p:TargetArchitecture=[value],即可构建 32/64 位或任意受支持架构的二进制。
本地开启静态分析与 ILLink 验证
为提升本地与 PR 产品构建速度,代码分析器(analyzers)与 ILLink 裁剪默认关闭;但它们在 CI 中仍是合并门禁(merge gates),且官方产品构建始终运行 ILLink 裁剪验证。要在本地启用,需传入以下属性:
Analyzers(构建时运行代码分析器):
./build.sh libs -c Release /p:RunAnalyzersInBuild=trueILLink Trimming(构建时运行 ILLink 裁剪):
./build.sh libs -c Release /p:RunILLinkInBuild=true两者同时开启:
./build.sh libs -c Release /p:RunAnalyzersInBuild=true /p:RunILLinkInBuild=true
这些功能在 global-build CI 管线的专用 job 中运行,作为合并门禁把关,而不必在每个产品构建上都启用。
在 Visual Studio 中工作与调试
在 Windows 上使用 Visual Studio 时,可以直接打开单个库项目,在 IDE 内完成构建、调试与运行测试。进入内循环构建的方式是build.cmd -vs System.Collections.Concurrent,它会生成并打开对应的.slnx解决方案。
调试方面,从 Visual Studio 2022 17.5 开始,VS 会在加载随 .NET Runtime 分发的调试库之前校验其签名是否正确——如果 Debug 库未正确签名会得到提示,请据此确认本机构建的调试库处于可用状态。
关于在 Visual Studio 中运行测试的更多细节,参见 visualstudio 指南。
运行 Libraries 测试
完整测试工作流的官方文档是 docs/workflow/testing/libraries/testing.md,其中强调测试前置条件(先构建运行时与全部库)以及libs.pretest对System.Private.CoreLib复制的重要性,与本指南前述内容一致。从零开始运行全部测试的一站式命令为:
build.cmd/sh -subset clr+libs+libs.tests -test -rc Release即:Release 构建 CLR,Debug 构建 libs+tests,随后运行全部测试。在 Visual Studio 中运行测试的方式见 visualstudio 指南。
构建 NuGet 包
在成功完成 .NETCoreApp 垂直构建(root 级build libs)之后,对 src 项目执行dotnet pack即可产出该库的包:
build libs dotnet.cmd pack src\libraries\System.Text.Json\src\与dotnet build/dotnet publish相同,可用-c指定配置:
dotnet.cmd pack src\libraries\System.Text.Json\src\ -c ReleaseAPICompat:保证 API 兼容性
如果库的变更引入任何 API 不兼容,dotnet build或dotnet pack可能直接报出 API 兼容性错误。这些错误通常必须修复;仅在极少数预期变更场景下(例如更新此前仅以 preview 或 experimental 形式发布的 API)才允许抑制,方法是按错误提示,对不可打包项目执行带/p:ApiCompatGenerateSuppressionFile=true的dotnet build,对可打包项目执行带同样参数的dotnet pack。
特别提醒:如果只是新增 API,不应抑制兼容性错误,而应更新该库的 reference source,保持参考程序集与实现同步。APICompat 的整体机制详见微软官方「API 兼容性」主题文档。
至此,你已经掌握了 .NET runtime 仓库中 Libraries 组件的完整构建知识:从「Release 运行时 + Debug 库」的日常组合、子集(libs/libs.tests/libs.pretest)在 eng/Subsets.props 中的展开与项目映射,到单个库的dotnet build内循环、CoreLib 迭代、Mono 目标、Native 组件与 sanitizer、静态分析/ILLink、打包与 APICompat 校验。把本文的命令与 构建索引文档、测试文档 配合使用,即可在真实仓库中高效地完成从改代码到跑测试的完整开发闭环。
- 语言运行时
- 标准库
- JIT编译
- 编译器
【免费下载链接】runtime
.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
相关推荐
.NET 日构建尝鲜指南:在 runtime 仓库中通过 Dogfooding 消费每日构建的运行时与 SDK
.NET 日构建尝鲜指南:在 runtime 仓库中通过 Dogfooding 消费每日构建的运行时与 SDK 本篇指南以 docs/project/dogfo
语言运行时标准库JIT编译编译器从源码构建 Docker Registry:distribution 仓库的完整开发环境搭建与构建指南
从源码构建 Docker Registry:distribution 仓库的完整开发环境搭建与构建指南 导读 本文以 KubeSphere 仓库中 vendor
云原生容器编排后端微服务多集群DevOps可观测性AI 技能ASP.NET Core 仓库源码构建完全指南:从 clone、restore 到本地构建与测试
ASP.NET Core 仓库源码构建完全指南:从 clone、restore 到本地构建与测试 本文基于 ASP.NET Core 官方仓库文档 BuildF
后端Web框架
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考