跳转至

跨平台编译指南

本文档介绍如何在 macOS 上编译 Linux wheel 包。

为什么需要交叉编译

  • maturin develop 只能构建当前操作系统的包
  • macOS 上运行只能构建 macOS wheel
  • Linux 上运行只能构建 Linux wheel
  • 本项目依赖 boring-sys2(BoringSSL),需要编译 C/C++ 代码

方法 1: 使用 Zig 交叉编译(推荐)

在 macOS 上无需 Docker 即可构建 Linux wheel。

1.1 安装依赖

# 安装 zig
brew install zig

# 安装 cargo-zigbuild
cargo install cargo-zigbuild

# 添加目标平台
rustup target add x86_64-unknown-linux-gnu
rustup target add aarch64-unknown-linux-gnu

1.2 构建 Linux wheel

# 构建 x86_64 Linux wheel
maturin build --release --features python --target x86_64-unknown-linux-gnu --zig

# 构建 aarch64 Linux wheel (ARM64)
maturin build --release --features python --target aarch64-unknown-linux-gnu --zig

1.3 构建结果

wheel 文件位于 target/wheels/ 目录:

target/wheels/
├── x_api_rs-1.0.0-cp38-abi3-manylinux_2_17_x86_64.whl      # Linux x86_64
├── x_api_rs-1.0.0-cp38-abi3-manylinux_2_17_aarch64.whl     # Linux ARM64
└── x_api_rs-1.0.0-cp38-abi3-macosx_11_0_arm64.whl          # macOS (本地)

方法 2: 使用 Docker 构建(已验证)

本项目依赖 boring-sys2(BoringSSL),需要自定义 Docker 镜像。

2.1 创建 Dockerfile.build

# 使用最新 Rust 版本(支持 edition 2024)
FROM rust:latest

# 安装 Python 和构建依赖
RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip \
    python3-venv \
    clang \
    libclang-dev \
    cmake \
    build-essential \
    patchelf \
    ninja-build \
    golang \
    perl \
    && rm -rf /var/lib/apt/lists/*

# 安装 maturin
RUN pip3 install maturin --break-system-packages

WORKDIR /io

# 设置入口点
ENTRYPOINT ["maturin"]

2.2 构建 Docker 镜像

docker build -f Dockerfile.build -t maturin-clang .

2.3 构建 Linux ARM64 wheel(M1/M2 Mac 原生)

# 创建输出目录
mkdir -p target/wheels

# 在容器内复制代码后构建(避免卷挂载兼容性问题)
docker run --rm \
  --entrypoint /bin/bash \
  -v "$(pwd)":/src:ro \
  -v "$(pwd)/target/wheels":/output \
  maturin-clang \
  -c "cp -r /src /build && cd /build && maturin build --release --features python --skip-auditwheel && cp /build/target/wheels/*.whl /output/"

2.4 构建 Linux x86_64 wheel(需要模拟)

# 先构建 x86_64 镜像
docker build --platform linux/amd64 -f Dockerfile.build -t maturin-clang-amd64 .

# 构建(较慢,使用 QEMU 模拟)
docker run --rm \
  --platform linux/amd64 \
  --entrypoint /bin/bash \
  -v "$(pwd)":/src:ro \
  -v "$(pwd)/target/wheels":/output \
  maturin-clang-amd64 \
  -c "cp -r /src /build && cd /build && maturin build --release --features python --skip-auditwheel && cp /build/target/wheels/*.whl /output/"

2.5 构建结果

ls -la target/wheels/
# x_api_rs-1.0.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl  # Linux ARM64
# x_api_rs-1.0.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl    # Linux x86_64

注意: --skip-auditwheel 跳过严格的 glibc 兼容性检查。生成的 wheel 需要目标系统 glibc >= 2.34(Ubuntu 22.04+, Debian 12+)。

方法 3: 在 Linux 服务器上构建

最可靠的方式是直接在目标 Linux 环境构建。

# SSH 到 Linux 服务器
ssh user@your-server

# 安装依赖 (Ubuntu/Debian)
sudo apt install -y clang libclang-dev cmake python3-pip
pip install maturin

# 安装 Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env

# 克隆并构建
git clone <your-repo>
cd x-api-rs
maturin build --release --features python

# 安装
pip install target/wheels/x_api_rs-*.whl

方法 4: GitHub Actions CI/CD

自动化构建多平台 wheel。创建 .github/workflows/build-wheels.yml

name: Build Wheels

on:
  push:
    tags: ['v*']
  workflow_dispatch:

jobs:
  build:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            target: x86_64-unknown-linux-gnu
          - os: ubuntu-latest
            target: aarch64-unknown-linux-gnu
          - os: macos-latest
            target: x86_64-apple-darwin
          - os: macos-latest
            target: aarch64-apple-darwin

    steps:
      - uses: actions/checkout@v4

      - name: Install clang (Linux)
        if: runner.os == 'Linux'
        run: sudo apt-get install -y clang libclang-dev

      - uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.target }}
          args: --release --features python
          manylinux: auto

      - uses: actions/upload-artifact@v4
        with:
          name: wheels-${{ matrix.target }}
          path: target/wheels/*.whl

部署到服务器

复制 wheel 文件

# 复制到服务器
scp target/wheels/x_api_rs-*manylinux*.whl user@server:/tmp/

# 服务器上安装
ssh user@server "pip install /tmp/x_api_rs-*.whl"

Docker 部署

# 在 Dockerfile 中
COPY target/wheels/x_api_rs-*manylinux*.whl /tmp/
RUN pip install /tmp/x_api_rs-*.whl && rm /tmp/x_api_rs-*.whl

常见问题

Q: zig 构建报错 "unable to find libclang"

确保安装了 zig 和 cargo-zigbuild:

brew install zig
cargo install cargo-zigbuild

Q: Docker 构建报错 "libclang version unsupported"

使用自定义 Dockerfile 安装新版 clang(见方法 2.2)。

Q: wheel 安装后 import 报错

确保安装的 wheel 与目标平台匹配: - Linux x86_64 服务器使用 manylinux_x86_64.whl - Linux ARM64 服务器使用 manylinux_aarch64.whl

快速参考

场景 命令
本地开发 (macOS) maturin develop --features python
构建 macOS wheel maturin build --release --features python
构建 Linux ARM64 (Docker) 见方法 2.3
构建 Linux x86_64 (Docker) 见方法 2.4
构建 Linux x86_64 (zig) maturin build --release --features python --target x86_64-unknown-linux-gnu --zig
构建 Linux ARM64 (zig) maturin build --release --features python --target aarch64-unknown-linux-gnu --zig