orjson 3.10.15 だけが ARM64 Windows でビルド失敗した
この記事の見出し
orjson 3.10.15 のインストールは 113.28 秒かけて失敗してしまった(体感では、かなり長く待ってから落ちる)。
新しい venv を作って、httpx、rich、pydantic、orjson を順に入れるだけ、という小さな確認だった。実際に試した結果、最初の 3 本は通り、最後の 1 本だけがエラーになる(まとめて入れていたら、どこで待たされたのか少し見えにくかったはず)。この落ち方が想定外だった。
この点は、先に切り分けておきたい話だった。失敗そのものより待ち時間の長さが印象に残る気がする話。
Python のパッケージを ARM64 Windows で入れるとき、失敗するならネイティブ拡張を持つものがまとめて詰まる、くらいに雑に思っていたためである。
計測日は 2026-07-11。2026年7月11日のログとして残す。この環境では Python 3.12.10 の ARM64 版で venv を作り、pip 25.0.1 のまま --no-cache-dir を付けて入れた。venv 作成そのものは 19.33 秒で終わっている。
面食らったのは、pydantic が普通に成功したことだった。pydantic_core は Rust 製のネイティブ拡張を含むが、wheel tag は cp312-cp312-win_arm64 だった。同じ Rust 製の拡張でも、ARM64 Windows 向け wheel を配っているかどうかで結果が分かれる(Rust かどうかだけを見ても、実際の導入可否は読めない)。
ひとつずつ入れて切り分けた
やったことは単純で、新しい venv を作ってから 4 つのパッケージを 1 本ずつ入れた。まとめて pip install しなかったのは、どのパッケージで時間を使い、どの時点で失敗したのかを分けて見たかったためだった(ここを一括にすると、待ち時間の正体がぼやける)。
C:\Users\akirasakai\AppData\Local\Programs\Python\Python312-arm64\python.exe -m venv C:\Users\AKIRAS~1\AppData\Local\Temp\arm64lab_c\venv
C:\Users\AKIRAS~1\AppData\Local\Temp\arm64lab_c\venv\Scripts\python.exe -m pip install --no-cache-dir -q httpx==0.28.1
C:\Users\AKIRAS~1\AppData\Local\Temp\arm64lab_c\venv\Scripts\python.exe -m pip install --no-cache-dir -q rich==13.9.4
C:\Users\AKIRAS~1\AppData\Local\Temp\arm64lab_c\venv\Scripts\python.exe -m pip install --no-cache-dir -q pydantic==2.10.6
C:\Users\AKIRAS~1\AppData\Local\Temp\arm64lab_c\venv\Scripts\python.exe -m pip install --no-cache-dir -q orjson==3.10.15
--no-cache-dir を付けているので、ローカルに残っていた wheel で楽をする余地は減っている。pure Python の wheel ならこの条件でも素直に入るので、問題になるのはプラットフォーム別のバイナリが必要なパッケージのほう(つまり今回なら orjson 側)だった。
途中で venv 作成時に junction 由来の注意も出た。これはエラーではなく、戻り値は 0 で終わっている。今回の本題ではないが、短いパスの AKIRAS~1 と通常の akirasakai が混ざるので、ログを読むときに少し戸惑う(失敗原因を探している最中だと、こういう余計な表示にも引っ張られやすい話)。
待った時間と戻り値
この計測は反復測定ではなく、1 回ずつの現場ログとして残っている。だから中央値は出さず、各コマンドの戻り値と経過時間をそのまま置くことにした(再現性より、失敗した順番を残すための表である)。軽い JSON 書き出しのために入れた依存が、Rust ツールチェーン、maturin、cargo、ローカルのビルド環境という別の層を一気に連れてくるので、失敗した瞬間に見なければならない範囲が広がりすぎる。
| 対象 | 経過時間 | rc | 結果 |
|---|---|---|---|
| venv 作成 | 19.33 秒 | 0 | 成功 |
| httpx==0.28.1 | 16.14 秒 | 0 | 成功 |
| rich==13.9.4 | 28.74 秒 | 0 | 成功 |
| pydantic==2.10.6 | 17.05 秒 | 0 | 成功 |
| orjson==3.10.15 | 113.28 秒 | 1 | 失敗 |
113.28 秒待ってから失敗するのは、体感ではかなり長い。すぐに「対応 wheel がありません」と返ってくるのではなく、ビルドに進んでから落ちる。ここで待たされるのが、今回いちばん嫌なところ(その間、画面上はちゃんと作業しているように見えるのがまた紛らわしい)。短いログ処理の依存を増やしただけのつもりが、環境準備の途中で別のビルド問題を抱え込む形になったのも嫌だった。しかもエラーの見た目は Rust 側の深いところまで進んだあとに出るので、単にパッケージを選び直せばよいだけなのか、環境を直すべきなのか、あるいは最初から標準ライブラリへ戻すべきなのかの判断まで遅れる。軽い JSON 書き出しのために入れた依存が、Rust ツールチェーン、maturin、cargo、ローカルのビルド環境という別の層を一気に連れてくるので、失敗した瞬間に見なければならない範囲が広がりすぎる。
インストール後の pip list --format=json には httpx 0.28.1、rich 13.9.4、pydantic 2.10.6、pydantic_core 2.27.2 が残った。orjson の行は見当たらず、失敗したパッケージが環境に半端に入らなかった点は助かる。
wheel tag で見る差
今回の芯は、成功したものが全部同じ理由で成功したのではない、という点にある。httpx と rich、その依存は py3-none-any の pure Python wheel なので、ARM64 か x64 かをほぼ気にしない。一方、pydantic は本体が py3-none-any でも、実体として使う pydantic_core が cp312-cp312-win_arm64 を持っていた。
| パッケージ | wheel tag | 見方 |
|---|---|---|
| httpx | py3-none-any | pure Python |
| httpcore | py3-none-any | pure Python |
| anyio | py3-none-any | pure Python |
| certifi | py3-none-any | pure Python |
| h11 | py3-none-any | pure Python |
| idna | py3-none-any | pure Python |
| rich | py3-none-any | pure Python |
| markdown_it_py | py3-none-any | pure Python |
| mdurl | py3-none-any | pure Python |
| pygments | py3-none-any | pure Python |
| pydantic | py3-none-any | pure Python 側の本体 |
| pydantic_core | cp312-cp312-win_arm64 | ARM64 Windows 向けネイティブ拡張 |
| annotated_types | py3-none-any | pure Python |
| typing_extensions | py3-none-any | pure Python |
| pip | py3-none-any | pure Python |
この表だけ見ると、pydantic が入った理由はかなりはっきりする。Rust 製だから失敗する、という話ではない。ARM64 Windows 向け wheel がある Rust 製拡張は入る。無いものはソースビルドへ進み、そこでローカル環境のツールチェーンに依存する形になってしまう。
既存の pip-arm64-wheels では、20 パッケージ分の wheel 有無を横に並べて見ている。今回はその一覧調査ではなく、1 パッケージが実際に 113.28 秒待たせたあとで動かなかった、という現場の記録として切り分けた(一覧表だけだと、この待ち時間の嫌さは出てこない)。
どこで落ちたか
orjson は win_arm64 向けのビルド済み wheel が見つからず、pip がソースからビルドしようとした。orjson は Rust 製なので、ビルドには maturin と cargo が絡む。私の環境では Rust ツールチェーンを入れていなかった。そこで、Rust 側のビルドに入ったあとでエラーになってしまった。
ログ末尾は次の内容になっている。
ror
warning: build failed, waiting for other jobs to finish...
error: could not compile `proc-macro2` (build script) due to 1 previous error
error: could not compile `serde` (build script) due to 1 previous error
error: could not compile `rustversion` (build script) due to 1 previous error
error: could not compile `libc` (build script) due to 1 previous error
error: could not compile `target-lexicon` (build script) due to 1 previous error
徴 maturin failed
Caused by: Failed to build a native library through cargo
Caused by: Cargo build finished with "exit code: 101": `"cargo" "rustc" "--profile" "release" "--message-format" "json-render-diagnostics" "--manifest-path" "C:\\Users\\akirasakai\\AppData\\Local\\Temp\\pip-install-8n8qgl88\\orjson_e12791a1a3a54fafbaca1e8d479de68a\\Cargo.toml" "--lib"`
Error: command ['maturin', 'pep517', 'build-wheel', '-i', 'C:\\Users\\AKIRAS~1\\AppData\\Local\\Temp\\arm64lab_c\\venv\\Scripts\\python.exe', '--compatibility', 'off'] returned non-zero exit status 1
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for orjson
[notice] A new release of pip is available: 25.0.1 -> 26.2
[notice] To update, run: C:\Users\AKIRAS~1\AppData\Local\Temp\arm64lab_c\venv\Scripts\python.exe -m pip install --upgrade pip
ERROR: Failed to build installable wheels for some pyproject.toml based projects (orjson)
could not compile libc (build script)、maturin failed、Cargo build finished with "exit code: 101" が同じ末尾に並ぶ。pip 自体の問題というより、wheel が無かったためにビルド経路へ入り、その先で Rust 側が通らなかった、という読み方になる。
どう使い分けるか
今回の結論は、orjson 3.10.15 はこの ARM64 Windows 環境では動かない、で止めたい。Rust を入れればビルドできる可能性はあるが、そこまでして使う理由が今は薄い。実際に必要だったのは、軽いログ処理と設定ファイルの読み書きだった(この用途で113.28秒待って失敗するのは割に合わない)。
まず標準の json で足りるかを考えてみる。速度だけを理由に orjson を入れたい場面はあるが、この手元の用途では 113.28 秒の失敗を受け入れてまで追うほどではなかった。依存を 1 本減らせるなら、そのほうが運用は楽になる。
pydantic は外さない。pydantic_core が cp312-cp312-win_arm64 を持っているので、少なくとも今回の条件では導入できた。ここを見ずに「Rust 製は全部だめ」と片付けると、判断を誤ってしまう。
短い結論にすると、pure Python wheel は安全圏で、ARM64 wheel があるネイティブ拡張も使える側に入る。orjson 3.10.15 のように win_arm64 wheel が無いものは、ソースビルドに入った瞬間から別の作業になる。個人的には、ARM64 Windows で日常用の venv を作るとき、まず標準ライブラリで足りる場所を探すように変えた。まず標準の json で試してみる、という落としどころだ。
次に測るなら、Rust ツールチェーンを入れた状態で同じ 113.28 秒の失敗がどこまで変わるかを見る。ただ、これは別の記事に分ける。今回は「何も足さない新しい venv で orjson だけが落ちた」という失敗記録として残しておくつもりだ。なぜここまで待たされたのか、という疑問は残る。