ASP.NET Core 仓库源码构建完全指南:从 clone、restore 到本地构建与测试
本文基于 ASP.NET Core 官方仓库文档 BuildFromSource 与仓库内实际构建脚本,完整讲解贡献者如何在本地把 aspnetcore 仓库搭建成可构建、可调试、可测试的工作区:涵盖 fork/clone 与子模块拉取、Windows 环境一次性配置、Visual Studio / VS Code / Codespaces 三条开发路径,以及顶层构建脚本 eng/build.sh(eng/build.cmd)的全部关键参数与推荐用法。读完本文,你将能够独立完成从克隆仓库到运行单元测试的完整闭环,并理解 restore、activate、局部 build.sh 等脚本在底层实际执行了什么。
一、准备工作:Fork、Clone 与子模块
如果你正在阅读本文档,大概率是希望作为贡献者在本地构建、调试和测试这个仓库的改动。整个流程假设开发机上已安装 Git。
-
在 GitHub 上登录并点击仓库的 Fork 按钮,创建属于自己的 fork。
-
使用
git clone克隆仓库到本地。由于该仓库包含子模块,必须携带--recursive参数以同时拉取子模块源码:git clone --recursive https://github.com/YOUR_USERNAME/aspnetcore如果克隆时没有传
--recursive,也可以随时用下面命令补拉子模块:git submodule update --init --recursive注意:后续所有步骤都针对你自己的 fork(如
YOUR_USERNAME/aspnetcore),而不是官方dotnet/aspnetcore仓库。
从仓库根目录的 .gitmodules 可以看到,aspnetcore 目前声明了两个子模块:
src/submodules/googletest(GoogleTest,用于 C++ 单元测试)src/submodules/MessagePack-CSharp(MessagePack-CSharp)
这正是克隆时必须 --recursive 的原因:如果这两个目录是空的,涉及它们的本地构建会缺少源码。更多子模块相关背景可参考 docs/Submodules.md。
二、Windows 一次性配置:PowerShell 执行策略与 Visual Studio C++ 组件
如果你的开发机是 Windows,还需要完成两项与操作系统相关的一次性配置:
2.1 更新 PowerShell 执行策略
打开 PowerShell 提示符,执行:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
后文所有 Windows 命令均默认在 PowerShell 提示符下执行。
2.2 安装包含 C++ 组件的 Visual Studio
即使你不打算用 Visual Studio 构建,也建议安装它,以获取必需的 C++ 组件和本机工具链。请使用仓库自带的官方安装脚本来安装:
即使机器上已装有 Visual Studio,也推荐运行这个安装脚本,确保安装了正确的 VS 组件。如果只是想修改现有安装,可以按官方“从配置文件安装”的说明,使用仓库根目录下的
.vsconfig文件导入配置。
./eng/scripts/InstallVisualStudio.ps1 -Edition Enterprise -Channel Preview
把 Enterprise 换成 Professional 或 Community 可切换你偏好的版本。当前要求使用 Preview 通道,因为它支持仓库正在使用的预览版 SDK(见 global.json 中固定的 11.0.100-rc.1.26420.103)。
如果你看到类似 the imported project "....\aspnetcore.tools\msbuild\17.1.0\tools\MSBuild\Microsoft\VC\v170\Microsoft.Cpp.Default.props" was not found 的错误,通常是 VS 组件缺失或过旧,按上面的方式重新安装/更新 Visual Studio 即可。
三、开发路径一:Visual Studio(仅 Windows)
完成上面的通用配置后,具体操作取决于你选择的开发环境,这里以 Visual Studio 为例:
-
该仓库包含 JavaScript 依赖,因此你需要安装 Node.js。
-
在 Visual Studio 打开项目之前,先运行仓库根目录的
restore.cmd脚本安装依赖并初始化仓库:./restore.cmd从 restore.cmd 的源码看,它实际只是调用
eng/build.ps1 -all -nobuild -restore,即“恢复全部项目类型但跳过编译”,因此它安装的是构建所需的 .NET SDK 与工具链(安装位置由 global.json 的paths: [".dotnet"]指定为仓库内的.dotnet目录)。 -
你通常只关注仓库中的某一块项目。可以用
startvs.cmd在特定项目区域启动 Visual Studio。例如启动src/Http区域,先在该目录构建,再启动 VS:cd src/Http ./build.cmd ./startvs.cmdbuild.cmd/build.sh脚本位于你所打开的项目目录内(如src/Http目录下的那个)。若想构建整棵树,请使用eng目录下的build.cmd/build.sh。从源码看,这两个脚本的分工非常清晰:
- 局部脚本 src/Http/build.sh 只有一行核心逻辑:
"$repo_root/eng/build.sh" --projects "$DIR/**/*.*proj" "$@",即把当前目录下所有*.csproj/*.fsproj等工程传给顶层构建脚本,因此“局部构建”本质上是顶层脚本加一个--projects过滤; - startvs.cmd 则把
DOTNET_ROOT指向仓库内.dotnet、把本地dotnet.exe放到PATH最前,然后用devenv.com打开src/Http下指定的.slnf文件(src/Http/startvs.cmd),保证 IDE 内构建使用与命令行脚本同一套本地 SDK。
- 局部脚本 src/Http/build.sh 只有一行核心逻辑:
关于 Solution Filter(.slnf)文件
仓库有一个覆盖全部 ASP.NET Core 的解决方案文件,但大多数人不会直接用它,因为 Visual Studio 对这种规模的项目处理能力有限。取而代之的是大量 Solution Filter(.slnf)文件,每个只包含一组相关项目的子集。以 src/Http/HttpAbstractions.slnf 为例,它通过 JSON 格式声明指向根级 AspNetCore.slnx 并筛选出 Hosting、DataProtection、Http 系列、TestHost 等一组项目。仓库维护 .slnf 的原则:
- 解决方案文件不被 CI 或命令行构建脚本使用,仅供开发者使用;
- 它们把“经常被一起编辑”的工程聚合在一起;
- 找不到包含你关注项目的解决方案?欢迎提 PR 增加新的
.slnf文件。
完成以上步骤后,即可在 Visual Studio 中构建、调试、测试你的改动。
四、开发路径二:VS Code 或其他编辑器(Windows / Linux / macOS)
这些步骤同样适用于其他编辑器:如果使用别的编辑器,把下文中的 code 替换为对应启动命令即可(例如 vim)。
-
需要安装 VS Code,并且能从命令行启动
code。 -
仓库有 JavaScript 依赖,需要安装 Node.js。
-
在 VS Code 打开任何东西之前,先运行根目录的
restore脚本安装 .NET 依赖:# Linux 或 Mac ./restore.sh# Windows ./restore.cmd -
restore完成后,运行激活脚本启用本地安装的 .NET:# Linux 或 Mac source activate.sh# Windows - 注意开头的“点 + 空格” . ./activate.ps1activate.sh 做的事情是:把
DOTNET_ROOT设置为$DIR/.dotnet,并将其放到PATH最前面,还会给 shell 提示符加上仓库名作为视觉标识;运行deactivate可还原环境。如果.dotnet/dotnet不存在,脚本会提示先运行restore.sh。 -
激活后,进入要修改的项目目录并用编辑器打开,例如
src/Http:cd src/Http code . -
在终端中运行项目目录内的
./build.sh构建并测试:# Linux 或 Mac ./build.sh ./build.sh -test# Windows ./build.cmd ./build.cmd -test同样地,脚本位于你打开的项目目录内;构建整棵树请用
eng目录下的build.sh/build.cmd。 -
另一种方式:在激活本地 SDK 之后,直接使用
dotnet build和dotnet test,但必须带上具体的项目文件。例如:# Linux 或 Mac source activate.sh dotnet build dotnet test --filter "MySpecificUnitTest"# Windows . ./activate.ps1 dotnet build dotnet test --filter "MySpecificUnitTest"之所以要求“带具体项目文件”,是因为顶层仓库没有可一键全量构建的单一工程,
dotnet build只应在某个*.csproj/*.fsproj所在目录执行。
五、开发路径三:GitHub Codespaces
如果你的 GitHub 账户启用了 Codespaces,可以直接使用云端的 VS Code 环境来修改代码:
-
进入你的 fork,选择要修改的分支。如果还没有工作分支,先通过 Web 界面或本地 checkout 后 push 创建。
-
点击 Code 按钮 → Codespaces 选项卡 → Create codespace 打开该分支的 Codespace。初始化会花费几分钟,完成后即可在基于 Web 的 VS Code 环境中工作。
-
在 Codespace 中直接使用
dotnet build和dotnet test构建和测试仓库内的具体项目。你不需要手动激活本地 .NET SDK,也不需要运行
restore脚本——这些步骤会在 Codespace 初始化过程中自动完成。
六、构建脚本指南:eng/build.sh(eng/build.cmd)的深入解析
仓库包含位于 eng/build.cmd 和 eng/build.sh 的顶层构建脚本,以及各子目录内的局部构建脚本。这些脚本支持一系列标志位,可用于 restore、build、test 等操作。本节文档化常见参数与推荐调用方式。
官方不推荐运行仓库顶层构建脚本来构建整个仓库——你很少需要构建全部工程,构建子项目通常就足以支撑你的工作流。
6.1 常见参数
可传给 build.cmd / build.sh 的常见参数:
| 参数 | 说明 |
|---|---|
| Configuration | Debug 或 Release。默认 = Debug(CI 场景下默认 Release)。 |
| TargetArchitecture | 目标 CPU 架构(x64、x86、arm、arm64)。 |
| TargetOsName | 目标基础 RID(win、linux、osx、linux-musl)。 |
从 eng/build.sh 的完整用法输出看,脚本实际支持的参数远比上表丰富,常用的还包括:
| 参数 | 说明 |
|---|---|
--[no-]restore / --[no-]build |
控制是否恢复依赖、是否编译(--no-build 隐含 --no-restore)。 |
--[no-]pack / --[no-]publish |
控制是否产出 NuGet 包、是否执行 publish。 |
--[no-]test |
是否运行测试。 |
--projects |
指定要构建的项目列表(绝对路径,支持 glob,如 $(pwd)/**/*.csproj),这正是各子目录局部 build.sh 的内部实现方式。 |
--no-build-deps |
不构建项目间引用,只构建指定项目。 |
--all |
构建所有项目类型(managed、native、nodejs、java、installers)。 |
--[no-]build-native |
是否构建 C/C++ 原生项目。 |
--[no-]build-managed |
是否构建 C#/F#/VB 托管项目。 |
--[no-]build-nodejs |
是否构建 NodeJS/TypeScript 项目。 |
--[no-]build-java |
是否构建 Java 项目(SignalR Java 客户端)。 |
--[no-]build-installers |
是否构建 Windows 安装器。 |
--verbosity / --binarylog |
MSBuild 日志级别与二进制日志开关。 |
--warnAsError / --warnNotAsError |
控制警告即错误的行为。 |
几个值得注意的默认行为(可直接在脚本源码中验证):
- 不带任何项目选择参数时,脚本默认构建
managed(C#)组及其依赖,并打印提示; - 当
managed构建开启且 PATH 中检测到node时,会自动连带开启 NodeJS 项目构建;反之会警告“managed 项目将回退使用上一次构建的 NodeJS 产物,可能不是最新”; --no-build-native --no-build-managed组合可快速只做工具链初始化与恢复,是restore的轻量替代。
6.2 常见调用方式
| 命令 | 作用 |
|---|---|
.\build.cmd -Configuration Release |
以 Release 配置构建子目录中的项目。可在任意项目子目录运行。 |
.\build.cmd -test |
运行当前项目的全部单元测试。可在任意项目子目录运行。 |
6.3 仓库级调用
虽然更推荐项目级构建脚本,但 eng 目录下的仓库级脚本也支持项目级调用:
| 命令 | 作用 |
|---|---|
.\eng\build.cmd -all -pack -arch x64 |
构建仓库中所有 shipping 项目的开发包。必须从仓库根目录运行。 |
.\eng\build.cmd -test -projects .\src\Framework\test\Microsoft.AspNetCore.App.UnitTests.csproj |
运行 Microsoft.AspNetCore.App.UnitTests 项目的全部单元测试。 |
.\eng\build.cmd -noBuildNative -noBuildManaged |
构建仓库但跳过原生与托管项目,是 ./restore.cmd 的更快速替代方案。必须从仓库根目录运行。 |
七、仓库依赖完整清单
为了支撑仓库内各项目的构建与测试,需要安装若干依赖。一部分与你要开发的项目区域无关、始终必需;另一部分则按项目可选。大部分必需依赖由 restore 脚本自动安装,或已随现代操作系统默认提供,或由 Visual Studio 安装器自动装好。
7.1 必需依赖
| 依赖 | 用途 |
|---|---|
| Git | 用于仓库的克隆、分支等源码控制操作。 |
| .NET | 仓库内构建使用的是 .NET SDK 的预览版,由 restore 脚本自动安装(安装到仓库内 .dotnet 目录,版本固定在 global.json 中)。 |
| curl / wget | 用于从 Web 下载安装文件与资源。 |
| tar | 用于解压安装资源。macOS、Linux 与 Windows 10 及以上系统默认自带。 |
7.2 可选依赖
| 依赖 | 用途 | 备注 |
|---|---|---|
| Selenium | 运行 Components(即 Blazor)项目的集成测试。 |
|
| Playwright | 运行 ProjectTemplates 中的模板测试。 |
|
| Chrome | 在上述项目中使用 Selenium 或 Playwright 运行测试时必需;使用 Playwright 时该依赖会自动安装。 | |
| Java Development Kit(v11 或更新) | 构建 SignalR Java 客户端时需要。Windows 上可用 ./eng/scripts/InstallJdk.ps1 脚本安装。 |
确保 JAVA_HOME 指向安装目录,且 PATH 包含 $(jdkInstallDir)/bin 文件夹。 |
| Wix | 处理 Windows 安装器项目 时需要。 | |
| Node.js | 构建仓库中的 JavaScript 资源(如 Blazor、SignalR 相关)。 | 至少需要当前 NodeJS LTS 版本。 |
八、故障排查
如果构建过程中遇到常见错误,请查阅仓库文档 BuildErrors,其中列出了构建仓库时可能遇到的常见问题及对应处理方法。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00