---
url: /getting-started/build.md
description: 从源码构建 mayami、eBPF、TLS 后端和安装包
---

# 编译

本节说明怎样从源码构建 Linux 调试版、路由器静态程序、cronet TLS 对象和安装包。日常开发流程见仓库 [`manual/development.md`](https://git.arc.moe/adam/mayami-rs/src/branch/main/manual/development.md)。

## 环境

仓库的 `flake.nix` 提供三个 Linux shell：

| shell | 进入 | 用途 |
|---|---|---|
| `default` | `nix develop --no-pure-eval` | 日常构建、测试、clippy、fuzz 和 bench |
| `package` | `nix develop .#package --no-pure-eval` | 两个架构的 musl 构建与 deb 打包 |
| `vm` | `nix develop .#vm --no-pure-eval` | qemu、virtme-ng、pppd/pppoe-server 根测试 |

不通过 Nix 构建时，要自行准备：

* Rust stable；
* `nightly-2026-09-07`、`rust-src` 和 `bpf-linker 0.11.1`，用于 `capture-ebpf`；
* BoringSSL 子模块所需的 cmake、perl、libclang 和 C 标准头；
* XDP 的 libbpf 头，例如 Debian 的 `libbpf-dev`。

首次取源码后补齐子模块：

```sh
git submodule update --init --recursive
```

## 调试版

```sh
cargo build -p mayami
cargo build --release -p mayami
```

输出在 `target/debug/mayami` 或 `target/release/mayami`。

只开发用户态、不需要 `capture` 时：

```sh
AYA_BUILD_SKIP=1 cargo build -p mayami
```

这个变量会让内核程序不参与构建；带 `capture` 入站的配置不能使用这样的产物。

## 路由器静态程序

```sh
scripts/musl.sh aarch64-unknown-linux-musl
scripts/musl.sh --no-cronet aarch64-unknown-linux-musl
```

第一条默认静态链接 `libcronet`，供 naive 的 cronet carrier 使用；第二条不链接它，体积更小。

`armv7-unknown-linux-musleabihf`、`riscv64gc-unknown-linux-musl` 也可作为目标，交叉编译器需自备。`MUSL_CROSS` 可指定工具链前缀，`CRONET_LIB_DIR` 可指定已有的 libcronet。

## cronet TLS 引擎

`tls.engine: cronet` 让 TLS 由 Chromium 的 `//net` TLS 实现处理，和 naive 的 cronet carrier 不是同一层。它使用 mayami-c 编出的 `mayami_net.o`：

```sh
MAYAMI_NET_OBJECT=/path/to/mayami_net.o \
  cargo build --release -p mayami --features cronet
```

对象来自 Chromium checkout：

```sh
mayami-c/scripts/cronet-build.sh ~/chromium/src x64
mayami-c/scripts/cronet-build.sh ~/chromium/src arm64
```

`mayami_net.h` 或对象 ABI 改过以后，先跑握手冒烟：

```sh
MAYAMI_NET_OBJECT=/path/to/mayami_net.o \
  cargo test -p mayami-tls --features cronet --test cronet
```

链接需要 lld。不带 `cronet` feature 的产物配置 `tls.engine: cronet` 时会在读配置阶段失败。

## 安装包

### Debian

```sh
nix develop .#package --no-pure-eval -c scripts/deb.sh
nix develop .#package --no-pure-eval -c scripts/deb.sh aarch64-unknown-linux-musl
```

产物在 `target/deb/`，包括 amd64/arm64 的 `mayami` 包，以及不分架构的 `mayami-vyos` 包。

### OpenWrt

OpenWrt 25.12+ 使用 APK。先看路由器自己的架构，不能只按 `uname -m` 猜：

```sh
cat /etc/apk/arch
scripts/openwrt.sh --arch aarch64_generic
```

已经有一个匹配架构的静态 ELF 时，可以只打包：

```sh
scripts/openwrt.sh --arch aarch64_generic \
  --binary target/aarch64-unknown-linux-musl/release/mayami
```

完整容器内构建命令和说明见 [`packaging/openwrt/Dockerfile`](https://git.arc.moe/adam/mayami-rs/src/branch/main/packaging/openwrt/Dockerfile)。

## 确认产物

```sh
mayami --version
```

输出包含版本、目标平台、Chromium 版本、cronet 是链接在内还是运行时加载，以及 BoringSSL 是否内置。

参见 [安装 OpenWrt](/getting-started/install#openwrt) 和 [安装 Debian](/getting-started/install#debian)。
