Closed5

【解決】huggingface/candleを含むライブラリのpythonバインディングをgithub actionsでビルドできなかった

ピン留めされたアイテム
PlatPlat

Pyo3、Maturinを使ってPythonバインディングを作ろうとしたわけだが、自動で生成される Github Actions のワークフローだと openssl と ring のビルドに失敗してしまったので、その対処法のメモ。

基本的に huggingface の tokenizers や hf_transfer が成功事例なのでそれをパクっていく

PlatPlat

error: failed to run custom build command for openssl-sys v0.9.102

Pyo3 と Maturin で Rust の Python用 binding を Github Actions でビルドしようとしたら、
↓こんな感じのエラーが出てしまった

https://github.com/p1atdev/dartrs/actions/runs/8952005137/job/24588937519#step:6:463

error: failed to run custom build command for `openssl-sys v0.9.102`

...略

   Could not find directory of OpenSSL installation, and this `-sys` crate cannot
  proceed without this knowledge. If OpenSSL is installed and this crate had
  trouble finding it,  you can set the `OPENSSL_DIR` environment variable for the
  compilation process.

  Make sure you also have the development packages of openssl installed.
  For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.

  If you're in a situation where you think the directory *should* be found
  automatically, please open a bug at https://github.com/sfackler/rust-openssl
  and include information about your system as well as this message.

  $HOST = x86_64-unknown-linux-gnu
  $TARGET = x86_64-unknown-linux-gnu
  openssl-sys = 0.9.102
PlatPlat

openssl-sys ビルドできない問題の解決策

おそらく hf-hub クレート由来なので candle には限らないとおもう。

次の2つを行って解決できた。

  1. (少なくとも)maturin-actionsで openssl クレートで vendored feature を使うようにする
Cargo.toml
[target.'cfg(target_os = "linux")'.dependencies]
openssl = { version = "*", features = ["vendored"] }

dependencies で features を指定すると勝手にそれを使ってビルドするようになってくれるらしい。ただ、そのまま dependencies に追加するとローカルの Windows でビルドできなかったので Linux に限定している。

target_os を指定するやつの解説はドキュメント参照

  1. maturin-actions で openssl をインストールする
    maturin-actions が別の docker イメージを引っ張ってくるので、Actionsの ubuntu-latest ではなく、ビルドするOS内でいれる必要がある。

また、maturin-actionsで使われるOSは2種類あるので、それぞれインストールに利用するコマンドが異なる。x86x86_64 が CentOS でそれ以外は Ubuntu なので、x86x86_64だけ yum を使って他で apt-get を使う。

  linux:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        # target: [x86_64, x86, aarch64, armv7, s390x, ppc64le]
        target: [x86_64, x86]
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - name: Build wheels
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.target }}
          args: --release --out dist --find-interpreter
          sccache: 'true'
          manylinux: auto
          before-script-linux: "yum install openssl-devel devtoolset-10-libatomic-devel perl-IPC-Cmd -y"
      - name: Upload wheels
        uses: actions/upload-artifact@v4
        with:
          name: wheels
          path: dist

  linux2:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        # target: [x86_64, x86, aarch64, armv7, s390x, ppc64le]
        target: [aarch64, armv7, s390x, ppc64le]
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - name: Build wheels
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.target }}
          args: --release --out dist -i python3.7 -i python3.8 -i python3.9 -i python3.10 -i python3.11 -i python3.12 
          sccache: 'true'
          manylinux: auto
          before-script-linux: "apt-get update && apt-get install libssl-dev -y"
      - name: Upload wheels
        uses: actions/upload-artifact@v4
        with:
          name: wheels
          path: dist

参考:

  • PyO3/maturin-action

https://github.com/PyO3/maturin-action?tab=readme-ov-file#manylinux-docker-container

  • huggingface/hf_transfer

https://github.com/huggingface/hf_transfer/blob/aa9d247b4cdb20f49ab517cc6b342273e2c2480e/.github/workflows/CI.yml#L22-L69

  • cross-rs/cross

https://github.com/cross-rs/cross/wiki/Recipes#openssl

PlatPlat

error: failed to run custom build command for ring v0.17.8

openssl-sys が解決したら、次はring というクレートのビルドに失敗した。
ワークフロー: https://github.com/p1atdev/dartrs/actions/runs/8955678713/job/24596648212#step:4:547

症状としては下の issue と全く同じだった。

https://github.com/PyO3/maturin-action/issues/222

なので、 huggingface/tokenizers のワークフローをパクって、失敗している環境の manylinux を指定するようにしてみる。tokenizers では x86_64 でも指定していたが、私の環境では aarch64 だけ失敗していたのでとりあえずそれだけ指定するようにした。

  linux2:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        manylinux: [auto]
        target: [armv7, s390x, ppc64le]
        include:
          - target: aarch64
            manylinux: musllinux_1_1
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.10'
      - name: Build wheels
        uses: PyO3/maturin-action@v1
        with:
          target: ${{ matrix.target }}
          args: --release --out dist -i python3.7 -i python3.8 -i python3.9 -i python3.10 -i python3.11 -i python3.12 
          sccache: 'true'
          manylinux: ${{ matrix.manylinux }}
          before-script-linux: "apt-get update && apt-get install -y libssl-dev musl-tools"
      - name: Upload wheels
        uses: actions/upload-artifact@v4
        with:
          name: wheels-linux-${{ matrix.target }}
          path: dist

matrix 使って aarch64 だけ musllinux_1_1 を使い、他は auto になるようにしている。

ちなみに、auto を指定すると互換性のためにめっちゃ古いバージョンを使うようになっているらしい。

https://github.com/PyO3/maturin-action?tab=readme-ov-file#inputs

古い環境だと ring がビルドできないことがあるらしいので新しいバージョンを指定している感じ。

参考:

  • huggingface/tokenizers

https://github.com/huggingface/tokenizers/blob/f2ec3b239b0a7a9866b01ec5cbd4d44243a40a16/.github/workflows/python-release.yml

このスクラップは14日前にクローズされました