pip install(cryptography や pydantic、orjson など)の途中で、ビルドに入り、次のエラーで止まることがあります。
error: can't find Rust compiler
続けて、pip はヒントも出します。
If you are using an outdated pip version, it is possible a prebuilt wheel is available for this package but pip is not able to install from it. Installing from the wheel would avoid the need for a Rust compiler.
これは、そのパッケージが Rust で書かれた拡張を含んでいて、pip が事前ビルド済みのパッケージ(wheel)を使えずにソースからビルドしようとし、その環境に Rust ツールチェーン(rustc / cargo)が無いために起きます。Python やパッケージのコードの誤りではなく、gcc が無いときの error: command 'gcc' failed と同じ「ビルド道具が無い」系で、要求されるのが Rust に変わったものです。
ヒントが言うとおり、多くの場合の正解は Rust を入れることではなく、wheel を使えるようにすることです。
なぜ Rust を要求されるのか
cryptography(3.4 で Rust ビルドを導入し、35.0 以降は Rust が必須)、pydantic(v2 の pydantic-core)、orjson などは、速度や安全性のために内部の一部を Rust で書いています。これらを入れるとき、pip はまず環境に合う wheel(コンパイル済みの配布物)を探します。wheel があれば、ダウンロードして展開するだけで、コンパイルは起きません。
ところが、環境に合う wheel が無いと、pip は sdist(ソース配布物)を落としてその場でビルドしようとします。Rust 拡張のビルドには rustc(Rust コンパイラ)が要ります。それが PATH に無いと、ビルドが build_rust の段階で error: can't find Rust compiler で止まります。
なぜ手元では出ないのか
手元(デスクトップや、これまで使っていた環境)では、そのパッケージの wheel がそのまま入っていました。ソースビルドに落ちるのは、環境に合う wheel が無いか、pip がその wheel を使えていないときです。
看板の cryptography は、Linux 向けに manylinux と musllinux(Alpine 用)の両方を配り、しかも abi3 wheel(1つの wheel が新しい Python でもそのまま使える形)を出しています。だから Alpine でも新しい Python でも、たいていは wheel が当たります。それでもソースビルドに落ちるのは、次のようなときです。
--no-binaryを付けている:--no-binaryはソースビルドを強制する指定です。意図せず付いていると、wheel があってもビルドに入り、Rust を要求されます。- pip が古くて wheel のタグを読めない:
musllinuxやabi3のタグに対応していない古い pip は、wheel があってもソースへ落ちることがあります。 - wheel の無いプラットフォーム:
ppc64leやs390xのような、そのパッケージが wheel を配っていない CPU アーキテクチャ。
つまり cryptography では、「Alpine だから wheel が無い」はたいてい当てはまりません(musllinux wheel があります)。パッケージによっては musllinux wheel を出しておらず「Alpine だから」が本当に効くこともありますが、まずは決めつけずに、本当にソースからビルドする必要があるのかを疑ってください。
直し方1:wheel を使えるようにする(基本)
Rust を入れる前に、wheel を取りに行く方向を先に検討します。エラーメッセージが最初に案内するのもこちらです。まず、wheel が存在するのに使えていないのか、そもそも無いのかを切り分けます。
pip install --only-binary=:all: <パッケージ>
これが成功すれば wheel は存在します(=直し方1で解けます)。失敗すれば、その Python・プラットフォーム向けの wheel がそもそも無いので、直し方2(Rust を入れる)かプラットフォーム変更に進みます。切り分け専用の指定で、通常のインストールに付けるものではありません。
wheel が存在するのに使えていない場合の直し方:
- pip を新しくする:
pip install --upgrade pip。古い pip はmusllinux/abi3などの wheel タグを読めず、wheel があってもソースビルドへ落ちることがあります。Alpine でcryptographyが落ちたときも、多くはこれで musllinux wheel が取れます。 --no-binaryを外す:--no-binaryを意図せず付けていないか確認します。付いていれば、wheel があってもソースビルドに入ります。- wheel のあるプラットフォームに替える:使っているアーキやディストリ向けの wheel が無いなら、wheel の揃う環境に寄せると、ビルドが要らなくなります。
これらで wheel が入るなら、Rust は要りません。
直し方2:どうしても Rust が要るとき(source build を続ける)
--only-binary=:all: でも失敗する(対応 wheel がそもそも無い)場合は、ソースからビルドするしかありません。Rust ツールチェーンを入れます。恒久的に管理された環境なら rustup が推奨です。CI やコンテナでは OS のパッケージからも入りますが、OS パッケージの Rust は古いことがあり(たとえば Debian 11 の cargo は 1.48)、パッケージが要求する版(This package requires Rust >=1.63.0 のように出ます)に届かず再び止まることがあります。その場合は rustup で新しい Rust を入れてください。
さらに、Rust だけでは足りないパッケージが多い点に注意してください。cryptography をソースからビルドするには、Rust に加えて C コンパイラ(build-essential)・OpenSSL の開発ヘッダ(libssl-dev)・libffi の開発ヘッダ・Python の開発ヘッダ・pkg-config が要ります(OpenSSL などとリンクするためです)。orjson のような Rust 中心のパッケージでも、ソースからのビルドには C コンパイラなどが併せて要ります。必要な一式は対象パッケージの版で変わるので、その版の公式ビルド手順(cryptography なら インストールドキュメント)で必要な依存を確認するのが確実です。
この道は、コンパイラと多くの依存をイメージに積むことになります。だから、対応 wheel が存在するなら直し方1(wheel を使う)を先に選ぶほうが、イメージも軽く、ビルド時間も要りません。
切り分け(うまくいかないとき)
error: command 'gcc' failedも一緒に、あるいは代わりに出る:同じ「ビルド道具が無い」系で、足りないのが C コンパイラ側です。対処は error: command ‘gcc’ failed(pip がソースビルドに落ちて gcc が無い) を参照してください。cryptographyは Rust と C の両方を使うので、Rust を入れた次に gcc 側で止まることがあります。- Rust を入れたのに、まだ
can't find Rust compilerと出る:rustcがPATHに通っているかを確認してください。rustupで入れた場合、source "$HOME/.cargo/env"を実行するか、シェルを開き直さないとPATHに載らないことがあります。rustc --versionが通るかを先に見ます。 This package requires Rust >=Xで止まる:Rust は入っているが版が古いケースです。rustup updateか、新しい Rust を入れ直します。OS パッケージのcargo/rustcが古いこともあります。pip installは通ったのに、実行時に別のエラーが出る:それはビルドと別の問題です。まずは今回のimportが通るかを確認してから切り分けます。
検証環境
python:3.12-slim、ネットワーク有り- 再現:
pip install --no-cache-dir --no-binary cryptography "cryptography==42.0.5"が、Rust の無い環境でerror: can't find Rust compilerを出して終了コード 1 - 修正:
pip install --no-cache-dir "cryptography==42.0.5"(wheel を使う)の後、終了コード 0
再現から修正までは errfix の検証ハーネスが機械的に確認しています。ここでは --no-binary cryptography でソースビルドを強制し(実環境では wheel が無いと自動でこの経路に入ります)、--no-cache-dir でキャッシュを使わせずに、can't find Rust compiler が出ること、--no-binary を外して wheel を使うと同じインストールが通ることを、再現→修正→シグネチャ消滅として通しました。エラー文言と「wheel を使えば Rust は要らない」というヒントは実機出力から引用しています。Rust を入れる方向(直し方2)は環境ごとに要求が変わるため、本記事では機械検証の対象は wheel を使う経路に限っています。