前言
将 Netgear R7000 Router Collector 构建为 Windows / Linux 单文件可执行程序,以及配置内嵌、静态链接等打包相关内容
1.构建环境
必选:
- Rust 工具链:rustup 安装 stable rustup default stable rustup update
可选(交叉编译):
| 目标平台 | 编译说明 | 所需工具 | 安装方式 |
|---|---|---|---|
| Linux | 从 Windows 交叉编译 | cross + Docker Desktop | cargo install cross |
| Windows | 从 Linux 交叉编译 | mingw-w64 工具链 | apt install mingw-w64 |
| Linux musl | 静态链接 | musl-gcc + musl target | rustup target add x86_64-unknown-linux-musl |
2.Windows 构建
2.1. 一键打包
scripts\build.ps1脚本执行流程:
- cargo build --release 编译 Windows release 二进制
- 创建 dist/ 输出目录(若已存在则清空重建)
- 复制 target/release/NetgearR7000-RouterCollector.exe → dist/NetgearR7000-Collector-Windows-x64.exe
- 为 dist/NetgearR7000-Collector-Windows-x64.exe 生成 dist/build-info.txt(MD5/SHA1/SHA256)
- 窗口保持开启,提示用户按 Enter 关闭
2.2. 文件生成
dist/
├── NetgearR7000-Collector-Windows-x64.exe # 约 5.7 MB
└── build-info.txt # 校验信息2.3. 手动构建
推荐使用 build.ps1 构建,如需跳过脚本,可直接编译
# 编译命令
cargo build --release
# 复制文件到 dist 目录
# 不复制在 target\release 目录
copy target\release\NetgearR7000-RouterCollector.exe dist\NetgearR7000-Collector-Windows-x64.exe3. Linux 构建
3.1. 一键打包
执行不了,需要给 build.sh 755 权限
# 一键命令
# 默认使用第一个
# 无权限用第二个
cd Netgear-R7000/scripts && ./build.sh
cd Netgear-R7000/scripts && chmod 755 build.sh && ./build.sh
# 进入scripts目录
cd Netgear-R7000/scripts
# Linux 打包脚本
./build.sh脚本执行流程:
- cargo build --release 编译 Linux release 二进制
- 创建 dist/ 输出目录(若已存在则清空重建)
- 复制 target/release/NetgearR7000-RouterCollector → dist/NetgearR7000-Collector-Linux-x64
- 遍历 dist/ 下所有 NetgearR7000-Collector-* 产物,单次读取文件字节并同时计算 MD5/SHA1/SHA256,写入 dist/build-info.txt
3.2. 文件生成
dist/
├── NetgearR7000-Collector-Linux-x64 # 单文件可执行
└── build-info.txt # 二进制校验信息3.3. WSL 构建
在 Windows 上也可通过 WSL 构建 Linux 版本:
wsl
cd /path/to/Netgear-R7000
bash scripts/build.sh4. 单文件原理
4.1. 配置内嵌
编译内嵌的是 config/config.toml(模板文件),运行时首次启动会生成同目录的 config.toml 文件
配置模板通过 include_str! 宏在编译期内嵌到二进制中。程序启动时若未找到外部配置文件,会把内嵌模板写出为运行目录下的 config.toml:
// src/config/settings.rs
const EMBEDDED_DEFAULT_CONFIG: &str = include_str!("../../config/config.toml");4.2. 首次启动自动生成配置
程序启动时调用 ConfigLoader::new_or_embedded():
- 查找外部 config.toml → 存在则直接加载(支持热加载)
- 不存在 → 将内嵌模板写出为 ./config.toml → 加载(支持热加载)
- 写出失败(只读目录)→ 直接用内嵌配置启动(不支持热加载)
首次启动:
./NetgearR7000-Collector-Windows-x64.exe
→ [INFO] 首次启动:已生成默认配置文件 ./config.toml
→ [INFO] 请修改其中的实际参数(host/password/token 等),保存后自动热加载或重启生效5. 配置路径查找顺序
1. 环境变量 ROUTER_COLLECTOR_CONFIG 指定的路径
- 空/空白字符串视为未设置,继续走默认查找链
- 指向目录时自动拼接 config.toml 文件名
- 指向文件时原样使用
2. ./config.toml ← 生产环境(默认)
3. ./config/config.toml ← 开发环境(仅开发使用)6. 静态链接
.cargo/config.toml 配置了静态链接,减少运行时依赖:
# Windows MSVC:静态链接 C 运行时(避免依赖 vcruntime140.dll)
[target.x86_64-pc-windows-msvc]
rustflags = ["-C", "target-feature=+crt-static"]
# Linux musl:完全静态链接(需安装 musl target + musl-gcc)
[target.x86_64-unknown-linux-musl]
rustflags = ["-C", "target-feature=+crt-static", "-C", "link-arg=-static"]7. TLS 依赖
项目使用 rustls-tls(纯 Rust TLS 实现)替代 native-tls(系统 OpenSSL):
- Windows:不依赖 Schannel / OpenSSL
- Linux:不依赖 libssl / libcrypto,二进制可移植性更好
# Cargo.toml
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "charset", "http2", "gzip", "stream", "json"] }8. Linux musl 完全静态链接
如需生成完全不依赖 glibc 的 Linux 二进制:
# 安装 musl target 和工具链
rustup target add x86_64-unknown-linux-musl
sudo apt install musl-tools
# 构建
cargo build --release --target x86_64-unknown-linux-musl
# 复制产物
cp target/x86_64-unknown-linux-musl/release/NetgearR7000-Collector dist/NetgearR7000-Collector-Linux-musl-x64
9. Release 构建优化
opt-level 选项可参考 Rust Cargo opt-level 有哪些选项?
Cargo.toml 中的 release profile:
[profile.release]
opt-level = 3 # 最高优化
lto = true # 链接时优化(跨 crate)
codegen-units = 1 # 单代码生成单元(最大化优化)
strip = true # 剥离调试符号
panic = "abort" # panic 直接终止(减小二进制)
10. 常见问题
Q: Windows 构建报 LNK1104(无法打开 exe)
原因:已有 NetgearR7000-Collector-Windows-x64.exe 进程正在运行,文件被锁定
解决:
taskkill /f /im NetgearR7000-Collector-Windows-x64.exe
cargo build --releaseQ: PowerShell 脚本报 && 不是有效分隔符
原因:Windows PowerShell 5.x 不支持 &&。build.ps1 已使用 UTF-8 BOM 编码避免中文乱码,并使用 ; 或分行替代 &&。如仍出错,使用 PowerShell 7+ 或 pwsh
Q: Linux 交叉编译失败
当前打包脚本不支持交叉编译,如需 Linux 产物,请直接在 Linux / WSL 上运行 bash scripts/build.sh。
若手动使用 cross 交叉编译失败,通常原因:未安装 cross 或 Docker 未运行
解决:
cargo install cross
# 确保 Docker Desktop 运行
cross build --release --target x86_64-unknown-linux-gnu
