🚀 通过在 GitHub 上赞助我,帮助我成为全职开源开发者
🚀 通过在 GitHub 上赞助我,帮助我成为全职开源开发者
使用 zig 作为链接器编译 Cargo 项目,以简化交叉编译过程。
cargo install --locked cargo-zigbuild
你也可以使用 pip 安装,它会自动安装 ziglang:
pip install cargo-zigbuild
我们还提供预安装了 macOS SDK 的 Docker 镜像,此外还包含 cargo-zigbuild 和 Rust,例如构建 x86_64 macOS 目标:
docker run --rm -it -v $(pwd):/io -w /io ghcr.io/rust-cross/cargo-zigbuild \
cargo zigbuild --release --target x86_64-apple-darwin
pip3 install ziglang
rustup target add aarch64-unknown-linux-gnu
cargo zigbuild --target aarch64-unknown-linux-gnu
| 变量 | 描述 |
|---|---|
| CARGO_ZIGBUILD_PYTHON_PATH | 使用 Python ziglang 包时的 Python 可执行文件路径(默认:python3) |
| CARGO_ZIGBUILD_ZIG_PATH | Zig 可执行文件路径(默认:zig) |
| CARGO_ZIGBUILD_CACHE_DIR | zig 工具和包装器的缓存目录 |
| CARGO_ZIGBUILD_RUSTC_VERSION | 覆盖检测到的 rustc 版本 |
| SDKROOT | macOS SDK 路径(在 macOS 上自动检测) |
| CMAKE_TOOLCHAIN_FILE | CMake 工具链文件路径(也支持 CMAKE_TOOLCHAIN_FILE_<target>、TARGET_CMAKE_TOOLCHAIN_FILE) |
| BINDGEN_EXTRA_CLANG_ARGS | bindgen 的额外 clang 参数(也支持 BINDGEN_EXTRA_CLANG_ARGS_<target>) |
| PKG_CONFIG_SYSROOT_DIR | pkg-config 的系统根目录(对 Apple 目标自动设置为 SDKROOT) |
| OHOS_NDK_HOME | OpenHarmony NDK 路径(ohos 目标必需) |
| CFLAGS | 额外的 C 编译器标志 |
| RUSTFLAGS | 额外的 Rust 编译器标志 |
默认情况下,--target 为 *-gnu 时,Zig 会隐式构建基于 Zig 版本的默认 glibc 版本(v12 到 v14 版本默认使用 glibc 2.28)。
要为特定的最低 glibc 版本构建,可在 --target 值后添加版本后缀。例如,要使用 --target aarch64-unknown-linux-gnu 为 glibc 2.17 编译:
cargo zigbuild --target aarch64-unknown-linux-gnu.2.17
glibc 版本目标功能存在以下注意事项:
--target,将不使用 Zig,命令实际上会运行常规的 cargo build。-C linker)会选择不使用 Zig,而 -L path/to/files 会导致 Zig 忽略 -C target-feature=+crt-static。-C target-feature=+crt-static 不支持静态链接到特定 glibc 版本(上游 zig cc 缺乏支持)你可能需要在 cargo zigbuild 命令前添加以下环境变量,指定系统路径或类似路径:
CFLAGS='-isystem /usr/include'RUSTFLAGS='-L /usr/lib64'cargo zigbuild 始终使用 zig cc 的 -nostdinc 选项,该选项会排除标准头文件位置(如 /usr/include)。当 Zig 配置了 --target 时,这也是其默认行为,此外还会选择不使用标准系统搜索路径。
这可能导致一种常见情况:cargo build 成功,而 cargo zigbuild 未经过额外配置则失败:
# 无法找到构建所需的头文件:
fatal error: 'libelf.h' file not found
# 无法找到要链接的共享库:
error: unable to find dynamic system library 'elf' using strategy 'no_fallback'. searched paths
有多种解决方法,但对于 /usr/include 等系统路径,必须注意避免将系统 glibc 头文件与 Zig 自身提供的 glibc 头文件混合,否则会产生类似 CPATH=/usr/include 导致的错误:
In file included from /usr/local/lib64/python3.13/site-packages/ziglang/lib/libunwind/src/gcc_personality_v0.c:21:
In file included from /usr/local/lib64/python3.13/site-packages/ziglang/lib/libunwind/include/unwind.h:18:
In file included from /usr/include/stdint.h:26:
In file included from /usr/include/bits/libc-header-start.h:33:
/usr/include/features.h:516:9: warning: '__GLIBC_MINOR__' macro redefined [-Wmacro-redefined]
516 | #define __GLIBC_MINOR__ 41
| ^
:2:9: note: previous definition is here
2 | #define __GLIBC_MINOR__ 37
|
当你安装的系统包已将项目构建所需的头文件添加到 /usr/include 时,你会希望 Zig 仅对这些头文件回退到 /usr/include,同时使用自身的 glibc 头文件。这可以通过 zig cc -isystem /usr/include 实现,对于 cargo zigbuild,可通过环境变量 CFLAGS='-isystem /usr/include' 进行配置。
对于共享库的类似问题,如果你的包将系统库安装在 /usr/lib64,通常会使用 LDFLAGS='-L /usr/lib64',但 rustc 和 cargo 不读取此环境变量,而是必须通过带有 build.rs 的 crate 配置搜索路径,以查找要动态/静态链接的库。因此,你需要使用 RUSTFLAGS='-L /usr/lib64'。
🚀 请通过 https://github.com/***/messense 帮助我成为全职开源开发者
使用 https://github.com/ziglang/zig 作为 链接器 编译 Cargo 项目,实现 更简单的交叉编译。
cargo install --locked cargo-zigbuild
你也可以使用 pip 安装,它会自动安装 ziglang:
pip install cargo-zigbuild
我们还提供预安装了 macOS SDK 以及 cargo-zigbuild 和 Rust 的 Docker 镜像,例如构建 x86_64 macOS 目标:
docker run --rm -it -v $(pwd):/io -w /io ghcr.io/rust-cross/cargo-zigbuild \
cargo zigbuild --release --target x86_64-apple-darwin
pip3 install ziglang 从 PyPI 安装 zigrustup target add aarch64-unknown-linux-gnucargo zigbuild,例如 cargo zigbuild --target aarch64-unknown-linux-gnu| 变量 | 描述 |
|---|---|
CARGO_ZIGBUILD_PYTHON_PATH | 使用 Python ziglang 包时的 Python 可执行文件路径(默认:python3) |
CARGO_ZIGBUILD_ZIG_PATH | Zig 可执行文件路径(默认:zig) |
CARGO_ZIGBUILD_CACHE_DIR | zig 工具和包装器的缓存目录 |
CARGO_ZIGBUILD_RUSTC_VERSION | 覆盖检测到的 rustc 版本 |
SDKROOT | macOS SDK 路径(在 macOS 上自动检测) |
CMAKE_TOOLCHAIN_FILE | CMake 工具链文件路径(也支持 CMAKE_TOOLCHAIN_FILE_<target>、TARGET_CMAKE_TOOLCHAIN_FILE) |
BINDGEN_EXTRA_CLANG_ARGS | bindgen 的额外 clang 参数(也支持 BINDGEN_EXTRA_CLANG_ARGS_<target>) |
PKG_CONFIG_SYSROOT_DIR | pkg-config 的系统根目录(对于 Apple 目标自动设置为 SDKROOT) |
OHOS_NDK_HOME | OpenHarmony NDK 路径(ohos 目标必需) |
CFLAGS | 额外的 C 编译器标志 |
RUSTFLAGS | 额外的 Rust 编译器标志 |
默认情况下,--target 对于 *-gnu 目标会让 Zig 隐式构建针对特定 glibc 版本,该版本因 Zig 版本而异(https://github.com/ziglang/zig/blob/0.14.1/lib/std/Target.zig#L473%EF%BC%89%E3%80%82
要针对特定的最低 glibc 版本构建,请在 --target 值后添加该版本作为后缀。例如,要使用 --target aarch64-unknown-linux-gnu 为 glibc 2.17 编译:
cargo zigbuild --target aarch64-unknown-linux-gnu.2.17
[!NOTE] glibc 版本目标功能存在https://github.com/rust-cross/cargo-zigbuild/issues/231#issuecomment-***%EF%BC%9A
- 如果未提供
--target,则不会使用 Zig,该命令实际上会运行常规的cargo build。- 如果指定了无效的 glibc 版本,
cargo zigbuild不会转发zig cc发出的关于所选回退版本的警告。- 此功能不一定与在构建主机上动态链接到特定版本 glibc 的行为一致。
- 可以指定版本 2.32,但在仅提供 2.31 的主机上运行时本应中止并报错,却能正常运行。
- 同时,在 glibc 2.31 的主机上指定 2.33 会被正确检测为不兼容。
- 某些
RUSTFLAGS(如-C linker)会退出使用 Zig,而-L path/to/files会导致 Zig 忽略-C target-feature=+crt-static。-C target-feature=+crt-static用于静态链接到特定 glibc 版本不受支持(上游zig cc缺乏支持)
cargo zigbuild 无法找到已存在的头文件(*.h 文件)或库你可能需要在 cargo zigbuild 命令前添加以下环境变量(或类似系统路径):
CFLAGS='-isystem /usr/include'RUSTFLAGS='-L /usr/lib64'cargo zigbuild 始终使用 zig cc 的 -nostdinc 选项,该选项会排除 /usr/include 等标准头文件位置。这也是 Zig 在配置了 --target 时的默认行为,此外还会退出标准系统搜索路径。
这可能导致一种常见情况:cargo build 成功,而 cargo zigbuild 因缺少额外配置而失败:
# 无法找到构建所需的头文件:
fatal error: 'libelf.h' file not found
# 无法找到要链接的共享库:
error: unable to find dynamic system library 'elf' using strategy 'no_fallback'. searched paths
有多种解决方法,但对于 /usr/include 等系统路径,必须注意避免将系统 glibc 头文件与 Zig 自身提供的 glibc 头文件混合,否则会产生类似 CPATH=/usr/include 导致的错误:
In file included from /usr/local/lib64/python3.13/site-packages/ziglang/lib/libunwind/src/gcc_personality_v0.c:21:
In file included from /usr/local/lib64/python3.13/site-packages/ziglang/lib/libunwind/include/unwind.h:18:
In file included from /usr/include/stdint.h:26:
In file included from /usr/include/bits/libc-header-start.h:33:
/usr/include/features.h:516:9: warning: '__GLIBC_MINOR__' macro redefined [-Wmacro-redefined]
516 | #define __GLIBC_MINOR__ 41
| ^
:2:9: note: previous definition is here
2 | #define __GLIBC_MINOR__ 37
|
当你安装的系统包已将项目构建所需的头文件添加到 /usr/include 时,你需要让 Zig 仅对这些头文件回退到 /usr/include,同时使用自身的 glibc 头文件。这可以通过 zig cc -isystem /usr/include 实现,对于 cargo zigbuild,可通过通用环境变量 CFLAGS='-isystem /usr/include' 进行配置。
对于共享库的类似问题,如果你的包将系统库安装在 /usr/lib64,通常会使用 LDFLAGS='-L /usr/lib64',但 rustc 和 cargo 不读取此环境变量,而是必须通过 build.rs 配置 crate 的搜索路径以查找要动态/静态链接的库。因此,你需要使用 RUSTFLAGS='-L /usr/lib64'。
如果你的构建二进制文件未剥离符号,在 Linux 上可运行以下脚本扫描 glibc 版本化符号并找出最高版本(即运行所需的最低版本)
/usr/local/bin/get-min-glibc:#!/bin/bash
FILE_NAME=$1
LANG=C readelf -W --version-info --dyn-syms ${FILE_NAME} \
| grep 'Name: GLIBC' \
| sed -re 's/.*GLIBC_(.+) Flags.*/\1/g' \
| sort -t . -k1,1n -k2,2n \
| tail -n 1
chmod +x /usr/local/bin/get-min-glibc
$ get-min-glibc target/x86_64-unknown-linux-gnu/release/hello-world
2.28
cargo zigbuild 支持特殊的 universal2-apple-darwin 目标,用于在 Rust 1.64.0 及更高版本上构建 macOS universal2 二进制文件/库。
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
cargo zigbuild --target universal2-apple-darwin
[!NOTE] 注意,Cargo 的
--message-format选项目前不适用于 universal2 目标。
已知的上游 zig https://github.com/ziglang/zig/labels/zig%20cc%EF%BC%9A
zig cc 识别(例如 armv7-unknown-linux-gnueabihf),解决方法是在 https://github.com/rust-cross/cargo-zigbuild/pull/58 中使用 -mcpu=generic 并显式传递目标特性。SDKROOT 环境变量为 macOS SDK 路径可解决此问题。本作品以 MIT 许可证发布。许可证副本见 LICENSE 文件。
探索更多轩辕镜像的使用方法,找到最适合您系统的配置方式
通过 Docker 登录认证访问私有仓库
无需登录使用专属域名
Kubernetes 集群配置 Containerd
K3s 轻量级 Kubernetes 镜像加速
VS Code Dev Containers 配置
Podman 容器引擎配置
HPC 科学计算容器配置
ghcr、Quay、nvcr 等镜像仓库
Harbor Proxy Repository 对接专属域名
Portainer Registries 加速拉取
Nexus3 Docker Proxy 内网缓存
需要其他帮助?请查看我们的 常见问题Docker 镜像访问常见问题解答 或 提交工单
docker search 限制
站内搜不到镜像
离线 save/load
插件要用 plugin install
WSL 拉取慢
安全与 digest
新手拉取配置
镜像合规机制
不支持 push
manifest unknown
no matching manifest(架构)
invalid tar header(解压)
TLS 证书失败
DNS 超时
域名连通性排查
410 Gone 排查
402 与流量用尽
401 认证失败
429 限流
D-Bus 凭证提示
413 与超大单层
来自真实用户的反馈,见证轩辕镜像的优质服务