# 构建与部署
> 所属项目: free-code .NET 10 重写
> 文档类型: 构建设计
> 来源章节: DESIGN-NET10-PART3.md § 23
> 上级文档: [测试与构建总览](测试与构建.md)
---
## 概述
构建目标是跨 5 个平台的 AOT 原生二进制,输出单文件、无运行时依赖的可执行文件。MSBuild 通过 `Directory.Build.props` 统一管理全局属性,`build.sh` 封装多平台批量发布,`install.sh` 提供一键下载安装体验。
原始 TypeScript 项目使用 Bun 打包为单一 JavaScript bundle。.NET 重写的 AOT 路径在启动时间和内存占用上接近原生,同时消除了 Bun 运行时依赖。
---
## 23.1 MSBuild 配置
### Directory.Build.props(全局属性)
所有子项目自动继承这些属性,无需在每个 `.csproj` 中重复声明。
```xml
net10.0
13.0
enable
enable
true
true
true
partial
false
true
true
1.0.0
free-code
FreeCode
```
关键属性说明:
| 属性 | 值 | 作用 |
|------|----|------|
| `AotPublish` | `true` | 启用 AOT 原生编译 |
| `PublishSingleFile` | `true` | 输出单一可执行文件 |
| `PublishTrimmed` | `true` | 裁剪未使用的程序集 |
| `TrimMode` | `partial` | 部分裁剪,保留反射入口点 |
| `JsonSerializerIsReflectionEnabledByDefault` | `false` | 强制使用 Source Generator 序列化 |
| `EnableAotAnalyzer` | `true` | 编译期检测 AOT 不兼容代码 |
| `LangVersion` | `13.0` | C# 13 特性(primary constructors、集合表达式等)|
---
### FreeCode.csproj(主项目)
```xml
Exe
net10.0
```
主项目引用全部 15 个子项目,自身仅包含 `Program.cs` 入口,所有业务逻辑分布在各子项目库中。
---
## 23.2 构建脚本
### build.sh(多平台批量构建)
```bash
#!/bin/bash
# build.sh — 多平台构建
set -euo pipefail
VERSION="${1:-$(git describe --tags --always)}"
OUTPUT_DIR="./dist"
# 构建目标平台
PLATFORMS=(
"osx-arm64"
"osx-x64"
"linux-x64"
"linux-arm64"
"win-x64"
)
for PLATFORM in "${PLATFORMS[@]}"; do
echo "Building for $PLATFORM..."
RID="${PLATFORM}"
dotnet publish src/FreeCode/FreeCode.csproj \
-c Release \
-r "$RID" \
-o "$OUTPUT_DIR/$PLATFORM" \
/p:VersionPrefix="$VERSION" \
/p:AotPublish=true \
/p:PublishSingleFile=true \
/p:PublishTrimmed=true
# 重命名二进制
if [[ "$PLATFORM" == win-* ]]; then
mv "$OUTPUT_DIR/$PLATFORM/free-code.exe" \
"$OUTPUT_DIR/$PLATFORM/free-code-$VERSION-$PLATFORM.exe"
else
chmod +x "$OUTPUT_DIR/$PLATFORM/free-code"
mv "$OUTPUT_DIR/$PLATFORM/free-code" \
"$OUTPUT_DIR/$PLATFORM/free-code-$VERSION-$PLATFORM"
fi
echo "✓ $PLATFORM done"
done
echo "All builds complete in $OUTPUT_DIR/"
```
脚本逻辑说明:
1. 版本号优先读取命令行参数,fallback 到 `git describe --tags --always`
2. 遍历 5 个 RID,每个平台独立调用 `dotnet publish`
3. 输出产物按 `free-code-{VERSION}-{PLATFORM}` 格式命名
4. Windows 平台保留 `.exe` 后缀,其余平台添加可执行权限
---
## 23.3 安装脚本
### install.sh(一键安装)
```bash
#!/bin/bash
# install.sh — 一键安装
set -euo pipefail
# 检测平台
OS="$(uname -s)"
ARCH="$(uname -m)"
case "$OS-$ARCH" in
Darwin-arm64) PLATFORM="osx-arm64" ;;
Darwin-x86_64) PLATFORM="osx-x64" ;;
Linux-x86_64) PLATFORM="linux-x64" ;;
Linux-aarch64) PLATFORM="linux-arm64" ;;
*) echo "Unsupported platform: $OS-$ARCH"; exit 1 ;;
esac
INSTALL_DIR="$HOME/.free-code/bin"
mkdir -p "$INSTALL_DIR"
# 下载
BINARY_URL="https://github.com/paoloanzn/free-code/releases/latest/download/free-code-latest-$PLATFORM"
echo "Downloading free-code for $PLATFORM..."
curl -fsSL "$BINARY_URL" -o "$INSTALL_DIR/free-code"
chmod +x "$INSTALL_DIR/free-code"
# 添加到 PATH
if ! echo "$PATH" | grep -q "$INSTALL_DIR"; then
SHELL_RC="$HOME/.zshrc"
[ -f "$HOME/.bashrc" ] && SHELL_RC="$HOME/.bashrc"
echo "export PATH=\"$INSTALL_DIR:\$PATH\"" >> "$SHELL_RC"
echo "Added $INSTALL_DIR to PATH in $SHELL_RC"
fi
echo "✓ free-code installed to $INSTALL_DIR/free-code"
echo " Run 'free-code' to start"
```
安装流程:
1. 通过 `uname -s` 和 `uname -m` 检测当前平台
2. 从 GitHub Releases 下载对应 RID 的预编译二进制
3. 安装到 `~/.free-code/bin/free-code`
4. 自动检测 shell 配置文件(优先 `.zshrc`,fallback `.bashrc`)并追加 PATH
---
## 23.4 目标平台矩阵
| RID | 操作系统 | 架构 | 说明 |
|-----|---------|------|------|
| `osx-arm64` | macOS | Apple Silicon | M1/M2/M3 Mac |
| `osx-x64` | macOS | Intel x64 | Intel Mac |
| `linux-x64` | Linux | x86-64 | 主流 Linux 服务器 |
| `linux-arm64` | Linux | AArch64 | Raspberry Pi、AWS Graviton 等 |
| `win-x64` | Windows | x64 | Windows 10/11 |
---
## 23.5 发布参数说明
| dotnet publish 参数 | 含义 |
|---------------------|------|
| `-c Release` | Release 配置,开启优化 |
| `-r {RID}` | 目标运行时,指定后产物为自包含 |
| `/p:AotPublish=true` | AOT 原生编译,消除 JIT 开销 |
| `/p:PublishSingleFile=true` | 将所有资源打包为单一可执行文件 |
| `/p:PublishTrimmed=true` | 裁剪未引用的程序集,减小体积 |
| `/p:VersionPrefix={VERSION}` | 注入版本号到程序集元数据 |
AOT 编译将 IL 代码提前编译为目标平台原生机器码,启动时间从 JIT 模式的数百毫秒降至个位数毫秒,与原始 Bun 构建产物的冷启动时间相当。
---
## 参考资料
- [测试与构建总览](测试与构建.md)
- [原始代码映射 — 测试与构建](reference/原始代码映射-测试与构建.md)
- [总体概述与技术选型](../总体概述与技术选型/总体概述与技术选型.md)
- [迁移路线图](测试与构建-迁移路线图.md)