你的 Mac 是 ARM 架构,服务器是 x86/AMD 架构。
普通编译出来的程序,服务器看不懂。我们需要一个"翻译官"把代码翻译成服务器能懂的格式。
- Zig:就是那个强大的底层翻译官(链接器)。
- cargo-zigbuild:是 Rust 的指挥官,它指挥 Zig 去干活。
第一步:安装必要的工具
打开终端(Terminal),依次执行以下命令:
-
安装 Zig (翻译官)
brew install zig
Bash
-
安装 cargo-zigbuild (指挥官)
cargo install cargo-zigbuild
Bash
- 添加目标架构支持告诉 Rust 我们通过能够生成 x86_64 的代码:
sql
rustup target add x86_64-unknown-linux-gnu
Bash
第二步:修改 Cargo.toml (最关键的一步!)
问题所在:Linux 上的 OpenSSL 库和 Mac 上的不一样。如果直接编译,编译器会在 Mac 上找 Linux 版的 OpenSSL 库,找不到就会报错。
解决方案 :有两种方法,推荐方法 A。
方法 A:使用 vendored 模式(推荐,最稳妥)
让 Rust 编译器自动下载一份 OpenSSL 的源码,并把它静态编译进你的程序里。这样你的程序到了服务器上,不需要依赖服务器的 OpenSSL 版本,直接就能跑。
打开项目根目录下的 Cargo.toml ,找到 [dependencies] 区域:
如果你直接依赖了 openssl :
ini
# 修改前可能是:openssl = "0.10"
# 修改后:
openssl = { version = "0.10", features = ["vendored"] }
toml
如果你使用的是 axum 配合 reqwest 或 sqlx (通常是这种情况): 你需要检查 reqwest 或 sqlx 的配置,确保它们启用 native-tls-vendored 或者干脆切换到 rustls 。
- 场景 1 (Axum + Reqwest):
ini
# 强制让 reqwest 自带 openssl 源码
reqwest = { version = "0.11", features = ["json", "native-tls-vendored"] }
toml
- 场景 2 (Axum + Sqlx):
arduino
sqlx = { version = "0.7", features = ["runtime-tokio-native-tls", "postgres"] }
# 如果编译报错,尝试改用 rustls (无需 OpenSSL,更简单):
# sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "postgres"] }
toml
方法 B:完全抛弃 OpenSSL,使用 Rustls
这是 Rust 社区更推荐的做法。 rustls 是纯 Rust 写的加密库,不需要 C 语言的 OpenSSL,完全没有交叉编译的烦恼。
- 在 Cargo.toml 中,把所有涉及 native-tls 的特性改成 rustls 。
第三步:执行编译
在项目根目录下,执行打包命令:
css
cargo zigbuild --target x86_64-unknown-linux-gnu --release
Bash
- --target x86_64-unknown-linux-gnu :指定目标是 Linux AMD64。
- --release :生成优化后的生产环境版本(文件更小,速度更快)。
第四步:获取结果与验证
- 找到文件:
编译成功后,可执行文件位于:
target/x86_64-unknown-linux-gnu/release/你的项目名
- 验证文件类型(可选):
在终端输入:
bash
file target/x86_64-unknown-linux-gnu/release/你的项目名
Bash
你应该看到类似输出: ELF 64-bit LSB pie executable, x86-64, ... (只要看到 ELF 和 x86-64,就说明编译成功了)
第五步:上传到服务器并运行
- 上传:
bash
scp target/x86_64-unknown-linux-gnu/release/你的项目名 root@你的服务器IP:/root/
Bash
- 运行:
登录服务器:
bash
chmod +x ./你的项目名 # 赋予执行权限
./你的项目名 # 运行
Bash
⚡️ 查漏补缺总结
- OpenSSL 是最大的坑:仅仅添加 openssl 依赖是不够的,必须开启 features = ["vendored"] ,否则编译时会报 linker error。
- glibc 版本问题: cargo-zigbuild 默认会兼容较老的 glibc 版本,这通常没问题。如果你的服务器系统特别老(比如 CentOS 7),可能需要指定 glibc 版本,例如: --target x86_64-unknown-linux-gnu.2.17 (一般情况不需要这步)。
- Docker 替代方案:如果上述步骤依然报错(通常是因为还有其他 C 语言依赖库),最简单的备选方案是使用 Docker 在本地模拟 Linux 环境编译,但对于小白来说, cargo-zigbuild 是配置成本最低的。
按照上述"推荐方法 A"修改 Cargo.toml,然后运行命令,99% 的情况都能成功!