【解決】huggingface/candleを含むライブラリのpythonバインディングをgithub actionsでビルドできなかった
Pyo3、Maturinを使ってPythonバインディングを作ろうとしたわけだが、自動で生成される Github Actions のワークフローだと openssl と ring のビルドに失敗してしまったので、その対処法のメモ。
基本的に huggingface の tokenizers や hf_transfer が成功事例なのでそれをパクっていく
openssl-sys v0.9.102
error: failed to run custom build command for Pyo3 と Maturin で Rust の Python用 binding を Github Actions でビルドしようとしたら、
↓こんな感じのエラーが出てしまった
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
openssl-sys ビルドできない問題の解決策
おそらく hf-hub クレート由来なので candle には限らないとおもう。
次の2つを行って解決できた。
- (少なくとも)maturin-actionsで
openssl
クレートでvendored
feature を使うようにする
[target.'cfg(target_os = "linux")'.dependencies]
openssl = { version = "*", features = ["vendored"] }
dependencies で features を指定すると勝手にそれを使ってビルドするようになってくれるらしい。ただ、そのまま dependencies に追加するとローカルの Windows でビルドできなかったので Linux に限定している。
target_os
を指定するやつの解説はドキュメント参照
-
maturin-actions で openssl をインストールする
maturin-actions が別の docker イメージを引っ張ってくるので、Actionsの ubuntu-latest ではなく、ビルドするOS内でいれる必要がある。
また、maturin-actionsで使われるOSは2種類あるので、それぞれインストールに利用するコマンドが異なる。x86
とx86_64
が CentOS でそれ以外は Ubuntu なので、x86
とx86_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
- huggingface/hf_transfer
- cross-rs/cross
ring v0.17.8
error: failed to run custom build command for openssl-sys
が解決したら、次はring
というクレートのビルドに失敗した。
ワークフロー: https://github.com/p1atdev/dartrs/actions/runs/8955678713/job/24596648212#step:4:547
症状としては下の issue と全く同じだった。
なので、 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
を指定すると互換性のためにめっちゃ古いバージョンを使うようになっているらしい。
古い環境だと ring がビルドできないことがあるらしいので新しいバージョンを指定している感じ。
参考:
- huggingface/tokenizers
Pyo3、Maturinの導入などに関してはこの記事が非常に参考になった