diff --git a/CLAUDE.md b/CLAUDE.md index 94ee6a2..9993151 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -16,7 +16,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co **M3(Desktop 3 platform と配布の再現性)は、6 件の完了条件をすべて満たし、配布まで踏んだ。** 3 platform(Windows / macOS / Linux)で native plugin がビルドされ、L1 / L3 と `test-tools-slow` が CI で green になり、Linux の LeakSanitizer レーンがリークを検出し、成果物の linkage・有効言語・リンク済み依存が実物の archive から検証されている。UPM tarball は使い捨ての Unity プロジェクトに実際に導入して 10/10 pass を確認済み(**M3 時点の件数**。現在の件数はこのレーンの行にある)。 -**配った実績は 4 つある: v0.1.0(2026-08-28)、v0.1.1(2026-08-29)、v0.2.0(2026-08-30)、v0.3.0(2026-09-04、最新の公開版)。** いずれも tag から `release.yml` が**その時点の全 platform 分**を作り、`--draft` で下書きにしてから人が公開している。v0.1.1 は上に書いた Linux の欠陥を直した版で、**中身を差し替えず新しい版として出した** — 一度配ったものを黙って差し替えると、同じ版名で違う物が世の中に 2 つ存在することになる。asset は 16 件(3 platform × 5 + `SHA256SUMS.txt`)。**これは v0.1.1 までの形である。その後 M3.5 / M4 / M6 で増えた**(現在の数は下の `release.yml` の行が持つ)。**公開された物を落として実測した(2026-08-29、このマシン)**: Linux の tarball は `SHA256SUMS.txt` と一致し、中の `libopencv_unity_native.so` は `GLIBC<=2.34, GLIBCXX<=3.4.29`(上限 2.35 / 3.4.30)だった。 +**配った実績は 5 つある: v0.1.0(2026-08-28)、v0.1.1(2026-08-29)、v0.2.0(2026-08-30)、v0.3.0(2026-09-04)、v0.4.0(2026-09-12、最新の公開版)。** いずれも tag から `release.yml` が**その時点の全 platform 分**を作り、`--draft` で下書きにしてから人が公開している。v0.1.1 は上に書いた Linux の欠陥を直した版で、**中身を差し替えず新しい版として出した** — 一度配ったものを黙って差し替えると、同じ版名で違う物が世の中に 2 つ存在することになる。asset は 16 件(3 platform × 5 + `SHA256SUMS.txt`)。**これは v0.1.1 までの形である。その後 M3.5 / M4 / M6 で増えた**(現在の数は下の `release.yml` の行が持つ)。**公開された物を落として実測した(2026-08-29、このマシン)**: Linux の tarball は `SHA256SUMS.txt` と一致し、中の `libopencv_unity_native.so` は `GLIBC<=2.34, GLIBCXX<=3.4.29`(上限 2.35 / 3.4.30)だった。 **PR #8 を CI に通したことで、ローカルでは緑だった欠陥が 3 件出た。** これは記録に値する: M3 を「書いたコードを CI に通すだけ」と見なしていたら、そのまま配っていた。 @@ -26,11 +26,11 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co **留保が 2 つある。** (a) **macOS の `.meta` は M3.5 で実測に変わったが、「macOS 上で動く Unity」は依然として実測が無い。** M2 の条件 7 で Linux 分が実測になり(`ci-unity.yml` が Linux の Unity を動かし、`libopencv_unity_native.so` とその `.meta` が実際に読み込まれて EditMode / IL2CPP Player の両方で通った)、M3.5 の全部入りで macOS 分も実測になった —— 実物の `libopencv_unity_native.dylib` とその `.meta` を含む package を Unity に読ませ、`PluginImporter` に解釈を問う EditMode の検査が通った(2026-08-30、ローカルの Windows)。**残るのは macOS 上で Unity を起動すること**で、CI の macOS job は plugin をビルドするが Unity を起動しない。**M3.5 はこの穴を狭めるどころか深刻にした** —— macOS の binary と `.meta` は、いまや Windows / Linux の利用者が導入する package の中にも入って配られる。(b) **Git URL では導入できない** — native plugin の binary は `.gitignore` で追跡から外してあるので、Git URL で参照した利用者に届くのは `.meta` だけで実体が入らない。完了条件は「Git URL **または** tarball」なので満たすが、利用者向けに明記が要る(`README.md` の "Why not a Git URL" とリリースノートに書いてある)。判定の詳細は `docs/roadmap.md` の M3 節にある。 -**M3.5(配布の形と、実用に必要な最小の穴)は実装が済み、CI も green で main に入った**(PR #34、`41cda19`、2026-08-29。**内訳は `docs/roadmap.md` の M3.5 節**)。**完了条件 6 件をすべて満たし、2026-08-30 に完了した**(判定表は `docs/roadmap.md` の M3.5 節。条件 3 は PR #37 で閉じた —— CI が 3 platform 同居で gating を走らせ、`native plugins present: 3` を出した)。 成立させたのは 3 つ: (1) **3 platform 分の binary を 1 つに束ねた tarball `com.ayutaz.opencv-unity-native.tgz` を配る正にした**(版番号を名前に入れない —— OpenUPM の `githubReleaseAssetName` が安定した接頭辞で asset を選ぶため。**実測 9.6 MB**(正確な値と run は `docs/roadmap.md` の M3.5 節))。platform ごとの tarball も引き続き出すが、そちらは便宜であって正ではない。(2) **`imgcodecs` の encode / decode を C ABI に出した**(下記)。(3) **Unity を 6.3 LTS へ載せ替えた**(`tests/UnityProject` は 6000.3.16f1、`package.json` の `"unity"` も 6000.3)。**実測はこのマシンで 2026-08-30**: 全部入りの tarball が導入できて `==> UPM tarball install: 16 passed`、Unity 6.3 の EditMode が 16 passed、IL2CPP Player が 10 passed(**IL2CPP モジュールが入っておらず Player が "Currently selected scripting backend (IL2CPP) is not installed" で落ちたので、Hub の CLI で入れてから走らせた**)。**OpenUPM への登録も済んだ**(openupm/openupm PR #6843、2026-08-30 に自動マージ)—— `https://package.openupm.com/com.ayutaz.opencv-unity-native` が `0.2.0` を配信している。**提出前に、用意してあった定義の `topics` が 2 つとも存在しない slug だったことが分かった**(そのままでは弾かれていた)。詳細は `docs/roadmap.md` の M3.5 節。** リポジトリの複数箇所が「リンク済み」と書いていたが、`cmake/FindOpenCvUnityDeps.cmake` の `COMPONENTS` は `core imgproc` だけだった。**間違えるのが容易な形をしている** —— `tools/opencv-config.psd1` の `Modules` に `imgcodecs` が入っているので **OpenCV 自身はそれを含めてビルドされており**、`ocvu_get_build_information()` も `To be built: ... imgcodecs` と報告する。**「OpenCV に入っている」と「このプラグインがリンクしている」は別である。** 気づいたのは CMake を読み直してではなく、`cv::imencode` / `cv::imdecode` が未解決の外部シンボル(LNK2019)になったからである。ついでに分かったこと: **`COMPONENTS` に足すだけでは binary は 1 バイトも増えない**(静的リンクは参照された object しか引かない)。Windows の debug plugin が 8,831,488 → 10,177,536 バイト(+1.35 MB)になったのは、関数を書いたからである。 +**M3.5(配布の形と、実用に必要な最小の穴)は実装が済み、CI も green で main に入った**(PR #34、`41cda19`、2026-08-29。**内訳は `docs/roadmap.md` の M3.5 節**)。**完了条件 6 件をすべて満たし、2026-08-30 に完了した**(判定表は `docs/roadmap.md` の M3.5 節。条件 3 は PR #37 で閉じた —— CI が 3 platform 同居で gating を走らせ、`native plugins present: 3` を出した)。 成立させたのは 3 つ: (1) **3 platform 分の binary を 1 つに束ねた tarball `com.ayutaz.opencv-unity-native.tgz` を配る正にした**(版番号を名前に入れない —— OpenUPM の `githubReleaseAssetName` が安定した接頭辞で asset を選ぶため。**実測 9.6 MB**(正確な値と run は `docs/roadmap.md` の M3.5 節))。platform ごとの tarball も引き続き出すが、そちらは便宜であって正ではない。(2) **`imgcodecs` の encode / decode を C ABI に出した**(下記)。(3) **Unity を 6.3 LTS へ載せ替えた**(`tests/UnityProject` は 6000.3.16f1、`package.json` の `"unity"` も 6000.3)。**実測はこのマシンで 2026-08-30**: 全部入りの tarball が導入できて `==> UPM tarball install: 16 passed`、Unity 6.3 の EditMode が 16 passed、IL2CPP Player が 10 passed(**IL2CPP モジュールが入っておらず Player が "Currently selected scripting backend (IL2CPP) is not installed" で落ちたので、Hub の CLI で入れてから走らせた**)。**OpenUPM への登録も済んだ**(openupm/openupm PR #6843、2026-08-30 に自動マージ)—— `https://package.openupm.com/com.ayutaz.opencv-unity-native` が**当時 `0.2.0` を配信していた**(**いま配信している版をここに書かない** —— 版を配るたびにこの行だけが古くなる)。**提出前に、用意してあった定義の `topics` が 2 つとも存在しない slug だったことが分かった**(そのままでは弾かれていた)。詳細は `docs/roadmap.md` の M3.5 節。** リポジトリの複数箇所が「リンク済み」と書いていたが、`cmake/FindOpenCvUnityDeps.cmake` の `COMPONENTS` は `core imgproc` だけだった。**間違えるのが容易な形をしている** —— `tools/opencv-config.psd1` の `Modules` に `imgcodecs` が入っているので **OpenCV 自身はそれを含めてビルドされており**、`ocvu_get_build_information()` も `To be built: ... imgcodecs` と報告する。**「OpenCV に入っている」と「このプラグインがリンクしている」は別である。** 気づいたのは CMake を読み直してではなく、`cv::imencode` / `cv::imdecode` が未解決の外部シンボル(LNK2019)になったからである。ついでに分かったこと: **`COMPONENTS` に足すだけでは binary は 1 バイトも増えない**(静的リンクは参照された object しか引かない)。Windows の debug plugin が 8,831,488 → 10,177,536 バイト(+1.35 MB)になったのは、関数を書いたからである。 **M4(Mobile)は実装が済み、CI も green で main に入った**(PR #41、`5354658`、2026-08-30)。**対象 platform は 3 から 5 になった** —— Android arm64-v8a と iOS arm64 が加わり、**クロスコンパイルがこのリポジトリに初めて入った**(M0〜M3.5 の完了条件はすべて「実行中の OS で確かめる」形だった)。成立させたのは 4 つ: (1) **5 platform の OpenCV を CI がビルドし、plugin をクロスビルドする**。(2) **Android の 16 KB page size を実物の `.so` で両方向検証する** —— 対応時は `p_align = 16384`、linker flag の書き方を変えて効かなくすると `4096` で赤くなる(後者は事故だったが、**「16 KB 整列は NDK の既定ではなくこの flag が作っている」ことと「検査が実物で落ちる」ことを同時に証明した**)。(3) **iOS は静的ライブラリを作り、libtool で OpenCV を束ねる** —— 束ねられていることを「こちらの object が要求する `cv::` シンボルをこの archive が定義しているか」で測り、**同じ step の負の対照が毎回それを裏づける**。(4) `WebCamTexture` から `CvMat` を作れる(**新しい C ABI 関数は 1 本も増えていない**。既存の上に立つ C# である)。 -**M4 は完了していない。完了条件 9 件のうち 6 件を満たし、3 件は閉じていない**(判定表は `docs/roadmap.md` の M4 節が正本)。**2026-09-01 に、残る条件をすべてスキップすると決めた** ——iOS / Android の実機、lifecycle と memory pressure、macOS 上での Unity 起動、Windows IL2CPP の結論。**実機が要る 2 件は CI では原理的に閉じない**ので、人が実行する手順書(`docs/m4-device-verification.md`)に落としてある。**この 4 件はどれも自然には閉じない** —— **「まだ調べていない」ではなく「やらないと決めた」である**(判断と帰結は `docs/roadmap.md` の「配布 その 4」に 1 箇所だけ書いてある)。帰結: **Android / iOS は「CI がビルドするが誰も動かしたことがない」まま残っている。**(**利用者に届く最新版は v0.3.0(6 platform、2026-09-04 公開)である** —— 2026-09-01 の時点では v0.2.0 のままだったが、その後配った。)判定表は `docs/roadmap.md` の M4 節。 +**M4 は完了していない。完了条件 9 件のうち 6 件を満たし、3 件は閉じていない**(判定表は `docs/roadmap.md` の M4 節が正本)。**2026-09-01 に、残る条件をすべてスキップすると決めた** ——iOS / Android の実機、lifecycle と memory pressure、macOS 上での Unity 起動、Windows IL2CPP の結論。**実機が要る 2 件は CI では原理的に閉じない**ので、人が実行する手順書(`docs/m4-device-verification.md`)に落としてある。**この 4 件はどれも自然には閉じない** —— **「まだ調べていない」ではなく「やらないと決めた」である**(判断と帰結は `docs/roadmap.md` の「配布 その 4」に 1 箇所だけ書いてある)。帰結: **Android / iOS は「CI がビルドするが誰も動かしたことがない」まま残っている。**(**利用者に届く最新版は v0.4.0(6 platform、2026-09-12 公開)である** —— 2026-09-01 の時点では v0.2.0 のままだったが、その後 v0.3.0 と v0.4.0 を配った。**実機で動かしていないことは、どちらの版でも変わっていない。**)判定表は `docs/roadmap.md` の M4 節。 **クロスビルドが緑になってから CI で 8 回落ちた。** Android の sample プロジェクト / install 配置 /新しい third-party(`cpufeatures`)/ 自分が起こした回帰 / クロスでの `find_package` の閉じ込め /`.meta` のキーが `iPhone` ではなく `iOS` であること。**最後の 1 件は、`.meta` を自分でパースする検査は通し、Unity に問う検査だけが落とした。** @@ -40,6 +40,8 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co **v0.3.0 は 2026-09-04 に公開した**(asset 33 件)。**M4 / M5 / M6 の成果が、これで初めて利用者に届いた** —— v0.2.0 以来である。**実機で一度も動かしていないことは変わらない**ので、その穴はリリースノートに明記してある(経緯は `docs/roadmap.md` の「配布 その 5」)。 +**v0.4.0 は 2026-09-12 に公開した。** **M7(`dnn` の opt-in profile / `RenderTexture` の低コピー経路 / native と C# の module 分離)と 2026-09 の API 拡張の成果が、これで初めて利用者に届いた** —— v0.3.0 以来である。**退行を 1 つ含む**: PNG の encode / decode が Android / iOS / macOS arm64 で ARM 加速を失った(上流 OpenCV 5.0.0 の vendoring の欠陥を避けるための取引で、JPEG と `core` / `imgproc` の SIMD には触れていない)。**実機で一度も動かしていないことは、この版でも変わらない。** 経緯は `docs/roadmap.md` の「配布 その 6」。 + **M5(binding specification と generator)は実装が済み、CI も green になった**(PR #55、2026-09-01。必須 21 本すべて)**。境界の宣言はもう手で書かない。** `bindings/spec/*.json` が正本で(**module 名を写さない**)、そこに並ぶ entry から **C ABI 宣言(`native/include/ocvu/*.h`)/C# の P/Invoke(`Runtime/Interop/NativeMethods..g.cs`)/全 entry point を 1 回ずつ呼ぶ到達性テスト(`tests/UnityProject/Assets/Tests/Shared/AbiReachabilityChecks.g.cs`)/API 対応表(`docs/api-map.md`)**が同時に出る(`./tools/dev.ps1 generate`)。**本数を数えるのは `docs/api-map.md` の冒頭だけである** —— ここに書くと、ABI が 1 本増えたときにこの行だけが静かに嘘になる。**手書きの `[DllImport]` は 0 個である**(全部が `.g.cs` の中にある)。一致は `./tools/dev.ps1 verify-generated` が見て、これは `dev.ps1 test` に入っているので **3 platform の `ci-native` が走らせる**(**PR #55 で 3 platform とも実際に通った**)。**検査は両向きに効く** —— 生成物を手で触ると落ち(実測)、`native/src/**/*.cpp` に `extern "C"` で `ocvu_` を実装して spec に書かなければ落ちる(後者は `tools/tests/BindingGenerator.Tests.ps1`。**見ているのは `native/src` の `.cpp` だけ**なので、他所に定義を置くと網に入らない)。**ABI は 1 本も増減していない** —— `OCVU_ABI_VERSION` は 1 のままで、M5 は移設であって追加ではない。**完了条件 5 件のうち 4 件を満たし、条件 2(`geometry` / `calib` / `features` / `objdetect` の追加)は当初計画の側で意図的に次へ送った**(判定表は `docs/roadmap.md` の M5 節)。 **その「次」に着手し、条件 2 は「部分的に満たした」まで進んだ**(2026-09-01、ブランチ `feat/m5-modules`)。`objdetect`(QR コードの符号化・復号、`ocvu_qr_encode` / `ocvu_qr_decode`)と `features`(ORB 特徴点検出、`ocvu_orb_detect`)の 2 module を新設し、C ABI は 20 → 23 本(allowlist は 11 → 14 本)、C# の P/Invoke 宣言は 25 本になった。**続けて `geometry` も出した**(`ocvu_find_homography`。C ABI は 24 本、allowlist は 15 本)。**残るは `calib` だけである。** この作業で分かったのは、`geometry` は**リンクが安い**ということである。復元済みの OpenCV ツリーには 7 つのライブラリが在り、`flann` と `geometry` は他 module の依存として**既にビルドされている**(`COMPONENTS` に足すだけでよい)。**対して `calib` だけが高い** —— `tools/opencv-config.psd1` の `Modules` に無いため、足すと構成ハッシュが変わって 5 platform 分の OpenCV を作り直すことになる(実測: `4785d98e9aad` → `09fcbe260d87`。**この値は 2026-09-01 に測り直した** —— それまで書いてあった `a197bbcbdaf5` は `geometry` を足したときの値で、`calib` のものではなかった)。その後 `geometry` も出したので、**条件 2 は「4 module のうち 3 つを出し、残るは `calib` だけ」という状態である。** `calib` が高いのは変わらない(`Modules` に無いので構成ハッシュが変わり、5 platform 分の OpenCV を作り直す)。 @@ -147,7 +149,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co | `Packages/.../Runtime/UnityIntegration/RenderTextureConverter.cs` | `RenderTexture` から `CvMat` を作る(M7a)。**新しい C ABI 関数は使わない**(既存の `CopyFrom(IntPtr, long, long)` の上に立つ純 C#)。同期の `ToMat` は GPU の転送が済むまで戻らず、`RequestMat`(`AsyncGPUReadback`)は依頼だけして戻る。**`-nographics` では動かない** —— `RenderTexture.Create()` は true を返すが `ReadPixels`/readback の画素が塗った色にならない(実測)。`WebCamTextureConverter` と同じ規約で上下を反転する | | `tests/UnityProject/Assets/Tests/Shared/` | EditMode と PlayMode が**共有する**検証本体(M4)。**本体はここにしか無い** —— 写して 2 つ持つと、片方だけ直って「Editor と Player で同じ結果」を確かめられなくなる。**M5 で `AbiReachabilityChecks.g.cs` が加わった**(生成物)—— spec が載せる宣言を 1 本残らず 1 回ずつ呼ぶ。結果は見ず、**呼べたことだけ**を見る。IL2CPP の stripping が消せるのは**呼ばれない**宣言なので、これを確かめられるのは Player だけである | | `tools/run-benchmarks.ps1` | Unity の結果 XML から `OCVU_BENCH:` 行を集めて `artifacts/benchmarks/latest.json` へ書く(M7a)。**時間の速い・遅いは判定しない** —— 時間の閾値は共有ランナーの上でフレークになるので、「測れたか」だけを見る: **XML ごとに**(M7a のレビューで直した。連結後に見ると片方のレーンの benchmark 本体が消えても気づけない)1 本以上拾えたか、そして各値が 0(単位は entry ごと。key が `_ns` で終わればナノ秒)でないか(測定が効いていない値を publish しない)。**ログではなく結果 XML の `//output` を読む** —— このリポジトリの確立した型は `TestContext.WriteLine` で、NUnit3 がそれを結果 XML の `` ノードへ入れる | -| `tools/measure-package-size.ps1` | UPM tarball のバイト数を測り、上限(`-MaxBytes`)を超えたら落とす(M7a)。**時間と違ってこれは assert してよい** —— 同じ入力から同じ tarball ができるので CI ランナーの負荷に左右されない。`tools/tests/PackageSize.Tests.ps1` が合成した入力(fake tarball)で発火を確かめ、`release.yml` が全部入りの実物に対して呼ぶ(`-MaxBytes 104857600` = 100 MB。**実測 66 MB に対して約 1.5 倍** —— 倍増を捕まえつつ、通常の増分では発火しない余裕) | +| `tools/measure-package-size.ps1` | UPM tarball のバイト数を測り、上限(`-MaxBytes`)を超えたら落とす(M7a)。**時間と違ってこれは assert してよい** —— 同じ入力から同じ tarball ができるので CI ランナーの負荷に左右されない。`tools/tests/PackageSize.Tests.ps1` が合成した入力(fake tarball)で発火を確かめ、`release.yml` が全部入りの実物に対して呼ぶ(`-MaxBytes 104857600` = 100 MB。**v0.4.0 の実測 77,530,189 バイトに対して約 1.35 倍** —— 倍増を捕まえつつ、通常の増分では発火しない余裕。**この比は版ごとに縮む** —— 上限を固定したまま中身が増えるので、**余裕が無くなる前に「上限を上げるか、配る形を変えるか」を決めることになる**) | | `tools/assert-unity-results.ps1` | Unity のテスト結果 XML の判定。**ローカルと CI の両方がここを通る** —— CI では game-ci が Unity を起動するので起動の仕方は分かれるが、判定は分けない。「0 件で緑にしない」もここが持つ。**`-RequireTest` は「その 1 群だけが消えた」を捕まえる**(M3.5 の追補)—— passed が 1 以上なら緑になるので、`PluginGatingTests` が assembly から外れても残りが通れば気づけない。実測: 結果 XML から gating の 6 件を抜くと `10 passed` になり、以前はそれで緑だった。**`Passed` であることまで見る** —— NUnit は `[Ignore]` を `Skipped` として出力し `failed` に数えないので、存在だけを見ると `[Ignore]` 1 行で満たせる(実測)。**`-RequireOutput` はさらに「どの分岐を通ったか」を見る** —— テストが通っても、合図が届かなければ弱い側の分岐を通っただけで、出力は成功時と 1 バイトも違わない。入力(合図を書く step が在ること)をいくら検査しても届いたことの証明にはならないので、テスト自身が出した事実(`native plugins present: 6`)を要求する。**数は写さず `tools/dev.ps1` の `$AllPlatformBinaries` から導く**(M6 のレビューで「検査が古い数を機械で強制していた」ことが分かったため) | | `tools/pack-upm-tarball.ps1` | UPM tarball を作る唯一の入口。`release.yml` と `dev.ps1 test-unity-tarball` の**両方**がここを通る(作り方が分かれると、導入を確かめた tarball と実際に配る tarball が別物になる)。中身は npm と同じく `package/` の下に入れる — package ID のディレクトリごと固めると UPM が 展開後の root に `package.json` を見つけられず導入に失敗する(M3 で実測)。**M3.5 で `-AllPlatforms` が加わり、これが配る正になった** —— 全 platform 分の binary を 1 つに束ね(**数を写さない。正本は `tools/dev.ps1` の `$AllPlatformBinaries` である**)、名前から版番号を落とす(`com.ayutaz.opencv-unity-native.tgz`)。**存在検査だけにしない**: 全部入りは中身の一覧そのものが契約なので、**全 platform 分が揃っている**ことに加えて**予期しない binary が 1 つでもあれば止め**、固めた後の archive の中を数え直す。`-MaxBytes`(既定 512 MB)を**引数にしてあるのは、既定のままではこの検査が働くところを誰も確かめられないから**である(現在の配布物は上限に対して 1 桁以上小さい) | | `tools/assemble-plugins.ps1` | 全 platform の plugin 木を 1 つに重ねる(全部入りの材料。M3.5。**数を写さない**)。**何でもコピーしない** —— 既知の binary と `.meta` だけを運び、知らないファイルがあれば止める。binary と `.meta` は必ず対で運ぶ(**binary の無い `.meta` を置くと Unity が消す**。下の `tools/plugin-meta/` の行)。**位置引数を禁止してある** —— `pwsh -File` から空白区切りで 2 つ渡すと 2 つ目が `PackageDir` に入り、**元の木を上書き先と取り違えたまま静かに成功する**(実測で踏んだ)。複数の元は ';' 区切りで受ける | @@ -324,7 +326,7 @@ C++ を選んだ主因は、**sanitizer が安定版ツールチェーンで使 再評価を安価に保つため、**public C header と契約テスト(L1 / L3)は backend 実装から独立に保つ**。この不変条件は M0 で確立し、以降のすべてのマイルストーンで維持する。 -## マイルストーン(現在地: **M7(Optional profiles と性能)は完了条件 5 件すべてを満たした**(2026-09-10)。**M7 が最後のマイルストーンである** —— `docs/roadmap.md` の `## M` 見出しは M0 から M7 までで、M8 は無い。**判定が 1 節にまとまっていないのは M7 だけで、5 件が 4 節(`M7a の判定` / `M7b の判定` / `CUDA / cuDNN 同梱の判定` / `M7c の判定`)に分かれている** —— 索引は同文書の `M7 の判定`。**「満たした」と「実証した」は M7 では大きく食い違う** —— `dnn` は実機で 1 度も動かしておらず、`RenderTexture` の画素を運ぶ経路は CI が 1 度も実行せず、CUDA / cuDNN のライセンス条項は読んでいない。**穴の一覧は roadmap の `M7 の判定` にある。ここに写さない。** **M7 の成果はまだどの公開版にも入っていない**(最新の公開版は v0.3.0)。その前の **M6(Web / Wasm)も完了条件 5 件すべてを満たした**(2026-09-03、PR #63 → `1e68d27`)—— **Web が 6 つ目の platform になった**(判定表は `docs/roadmap.md` の M6 節)。**M6 が足した 3 本の check を必須にするかは下の「機構として強制されていること」が持つ**(**ここには書かない** —— 昇格した日に、写した側だけが嘘になる)。**Web にだけ在る制限が 1 つある: `imgcodecs` は JPEG のみで PNG を持たない**(Unity の WebGL 支援が自前の libpng を同梱しているため。他の 5 platform は両方持つ)。その前の **M5(binding specification と generator)も完了条件 5 件すべてを満たした**(2026-09-02)。生成の仕組みは `docs/superpowers/plans/2026-08-31-m5-binding-generator.md` で成立し、**条件 2(`geometry` / `calib` / `features` / `objdetect` の追加)は 3 つの続きの計画で閉じた** —— `objdetect` / `features`(`.superpowers/sdd/2026-09-01-m5-modules-objdetect-features/`)、`geometry`(同上の続き。**リンクは無料だった** —— `features` / `objdetect` の依存として推移的に引かれており `COMPONENTS` に足す必要すら無かった)、カメラの歪み補正(`docs/superpowers/plans/2026-09-01-m5-calib-undistort.md`)、そして **`calib` module と `cv::calibrateCamera`**(`docs/superpowers/plans/2026-09-02-m5-calib-camera.md`)。**最後の 1 つだけが高かった** —— 構成ハッシュが `4785d98e9aad` → `09fcbe260d87` に変わり、5 platform 分の OpenCV を作り直した。**本数は `docs/api-map.md` の冒頭が数える。****M4(Mobile)も完了していない** —— 完了条件 9 件のうち **3 件**が閉じていない(iOS 実機 / lifecycle / macOS 上の Unity)。**Windows IL2CPP は「結論を出す」ことが条件だったので満たしている**(2026-08-31 に実測して「CI で回さない」と結論した)。判定表は roadmap の M4 節が正本。**v0.3.0 を 2026-09-04 に公開した。** **M4(5 platform)・M5(生成器と校正 API)・M6(Web)の成果が、これで初めて利用者に届いた** —— v0.2.0 以来である。**版番号は当初「v0.3.0 を飛ばして v0.4.0」と書いていたが覆した** —— v0.3.0 という名前で世に出た物が 1 つも無いことを実測したためで、2026-08-31 の下書き(生成物が 1 つも入っていない)と tag は破棄して `03a4557` に打ち直した。**OpenUPM も `0.3.0` を配信している**(公開の約 4 時間後に `dist-tags.latest` が変わった。pipeline は `state=2` / `commit=03a4557` —— **打ち直した tag に紐づいたまま配信された**)。**配布の完了条件 7 件はすべて満たした。****配布の記録は `docs/roadmap.md` の「配布 その 5」にある。** 判定表はいずれも roadmap にある) +## マイルストーン(現在地: **M7(Optional profiles と性能)は完了条件 5 件すべてを満たした**(2026-09-10)。**M7 が最後のマイルストーンである** —— `docs/roadmap.md` の `## M` 見出しは M0 から M7 までで、M8 は無い。**判定が 1 節にまとまっていないのは M7 だけで、5 件が 4 節(`M7a の判定` / `M7b の判定` / `CUDA / cuDNN 同梱の判定` / `M7c の判定`)に分かれている** —— 索引は同文書の `M7 の判定`。**「満たした」と「実証した」は M7 では大きく食い違う** —— `dnn` は実機で 1 度も動かしておらず、`RenderTexture` の画素を運ぶ経路は CI が 1 度も実行せず、CUDA / cuDNN のライセンス条項は読んでいない。**穴の一覧は roadmap の `M7 の判定` にある。ここに写さない。** **M7 の成果は v0.4.0(2026-09-12 公開)で初めて利用者に届いた**(最新の公開版は v0.4.0)。その前の **M6(Web / Wasm)も完了条件 5 件すべてを満たした**(2026-09-03、PR #63 → `1e68d27`)—— **Web が 6 つ目の platform になった**(判定表は `docs/roadmap.md` の M6 節)。**M6 が足した 3 本の check を必須にするかは下の「機構として強制されていること」が持つ**(**ここには書かない** —— 昇格した日に、写した側だけが嘘になる)。**Web にだけ在る制限が 1 つある: `imgcodecs` は JPEG のみで PNG を持たない**(Unity の WebGL 支援が自前の libpng を同梱しているため。他の 5 platform は両方持つ)。その前の **M5(binding specification と generator)も完了条件 5 件すべてを満たした**(2026-09-02)。生成の仕組みは `docs/superpowers/plans/2026-08-31-m5-binding-generator.md` で成立し、**条件 2(`geometry` / `calib` / `features` / `objdetect` の追加)は 3 つの続きの計画で閉じた** —— `objdetect` / `features`(`.superpowers/sdd/2026-09-01-m5-modules-objdetect-features/`)、`geometry`(同上の続き。**リンクは無料だった** —— `features` / `objdetect` の依存として推移的に引かれており `COMPONENTS` に足す必要すら無かった)、カメラの歪み補正(`docs/superpowers/plans/2026-09-01-m5-calib-undistort.md`)、そして **`calib` module と `cv::calibrateCamera`**(`docs/superpowers/plans/2026-09-02-m5-calib-camera.md`)。**最後の 1 つだけが高かった** —— 構成ハッシュが `4785d98e9aad` → `09fcbe260d87` に変わり、5 platform 分の OpenCV を作り直した。**本数は `docs/api-map.md` の冒頭が数える。****M4(Mobile)も完了していない** —— 完了条件 9 件のうち **3 件**が閉じていない(iOS 実機 / lifecycle / macOS 上の Unity)。**Windows IL2CPP は「結論を出す」ことが条件だったので満たしている**(2026-08-31 に実測して「CI で回さない」と結論した)。判定表は roadmap の M4 節が正本。**v0.3.0 を 2026-09-04 に公開した。** **M4(5 platform)・M5(生成器と校正 API)・M6(Web)の成果が、これで初めて利用者に届いた** —— v0.2.0 以来である。**続けて v0.4.0 を 2026-09-12 に公開した** —— M7(`dnn` の opt-in profile ほか)と 2026-09 の API 拡張が、これで初めて届いた。**PNG の ARM 加速を Android / iOS / macOS arm64 で失う退行を含む**(リリースノートに明記してある)。**版番号は当初「v0.3.0 を飛ばして v0.4.0」と書いていたが覆した** —— v0.3.0 という名前で世に出た物が 1 つも無いことを実測したためで、2026-08-31 の下書き(生成物が 1 つも入っていない)と tag は破棄して `03a4557` に打ち直した。**OpenUPM は v0.3.0 のとき、公開の約 4 時間後に `dist-tags.latest` を切り替えた**(pipeline は `state=2` / `commit=03a4557` —— **打ち直した tag に紐づいたまま配信された**)。**v0.4.0 が配信されたかどうかは、確かめてから書くこと** —— レジストリは Release より数時間遅れるので、公開直後にここへ「配信している」と書くと嘘になる。**配布の完了条件 7 件はすべて満たした。****配布の記録は `docs/roadmap.md` の「配布 その 5」にある。** 判定表はいずれも roadmap にある) 詳細と完了条件は `docs/roadmap.md` にある。要点のみ: diff --git a/README.ja.md b/README.ja.md index 3e4c67b..b01fc9d 100644 --- a/README.ja.md +++ b/README.ja.md @@ -4,7 +4,7 @@ OpenCV 5 を、このプロジェクトが所有する C ABI 越しに Unity へ [English](README.md) -> **現状: 公開済みの最新版は v0.3.0 です(2026-09-04)。リポジトリはその先へ大きく進んでいます。** 以下はその公開版ではなく、リポジトリの説明です。**v0.3.0 は tag `03a4557` で、2026-09 の API 拡張よりも M7 よりも前の版です** —— 差は「いくつかの機能」ではなく、それ以降に入った全部です。両端とも生成物から取れる唯一の数字を挙げると、`docs/api-map.md` は **v0.3.0 で公開 C ABI 27 本、ここでは 57 本**と書いています。C# 側では `CvAruco` / `CvCoreOps` / `CvStereo` / `CvDnn` / `RenderTextureConverter` がその tag には存在しないので、v0.3.0 に対して `OCVU_PROFILE_DNN` を立ててもその先には何もありません。**実際に配られたものの正本は[ロードマップ](docs/roadmap.md)の「配布」の節であって、この段落ではありません。** **6 platform を配る最初の版**であり(Windows x64 / macOS arm64 / Linux x64 / Android arm64-v8a / iOS arm64 / Web (WebGL))、**生成される binding 層とカメラ校正を含む最初の版**でもあります。どの platform も CI がビルド・テスト・パッケージ化し、Unity 自身が Mono(EditMode)・実物の IL2CPP Player・headless のブラウザでプラグインを動かしています。**正直な限界を先に書きます。** **Android と iOS は実機で一度も動かしていません** —— CI はクロスコンパイルして成果物を検査しますが、どの端末もこの binary を読み込んだことがありません。**Web には PNG がありません**(`imgcodecs` は JPEG のみ。下記)。動かしたブラウザも Linux の headless Chromium 1 つだけです。**macOS 上で Unity を起動したこともありません**(`.meta` の解釈は他の OS の Unity に問うて確認済みです)。**公開している C ABI は意図的に狭くしてあります** —— 面積を覆うことではなく、所有権・stride・エラー処理・IL2CPP・platform の振り分けを正しくすることを目的にしているからです。**Linux では v0.1.1 以降を使ってください** —— v0.1.0 の Linux プラグインは glibc 2.38 を要求し、Ubuntu 22.04 では読み込めませんでした。 +> **現状: 公開済みの最新版は v0.4.0 です(2026-09-12)。** 以下は、tag を打った後に直した文書を除けば、そのまま公開版の説明でもあります。**v0.4.0 は、2026-09 の API 拡張と M7 の成果を初めて配る版です。** 両端とも生成物から取れる唯一の数字を挙げると、`docs/api-map.md` は **v0.3.0 で公開 C ABI 27 本、v0.4.0 で 57 本**と数えています。C# 側の `CvAruco` / `CvCoreOps` / `CvStereo` / `CvDnn` / `RenderTextureConverter` は v0.3.0 には 1 つも存在せず、**いま落とせるパッケージに入っています**。まだ v0.3.0 を使っているなら、そこで `OCVU_PROFILE_DNN` を立ててもその先には何もありません。**実際に配られたものの正本は[ロードマップ](docs/roadmap.md)の「配布」の節であって、この段落ではありません。** **6 platform**(Windows x64 / macOS arm64 / Linux x64 / Android arm64-v8a / iOS arm64 / Web (WebGL))を配り、**ONNX 推論(`dnn`、opt-in)・ArUco・姿勢推定・ステレオ視差・`RenderTexture` 連携を含む最初の版**です(6 platform・生成される binding 層・カメラ校正は v0.3.0 から入っています)。どの platform も CI がビルド・テスト・パッケージ化し、Unity 自身が Mono(EditMode)・実物の IL2CPP Player・headless のブラウザでプラグインを動かしています。**正直な限界を先に書きます。** **Android と iOS は実機で一度も動かしていません** —— CI はクロスコンパイルして成果物を検査しますが、どの端末もこの binary を読み込んだことがありません。**Web には PNG がありません**(`imgcodecs` は JPEG のみ。下記)。動かしたブラウザも Linux の headless Chromium 1 つだけです。**macOS 上で Unity を起動したこともありません**(`.meta` の解釈は他の OS の Unity に問うて確認済みです)。**`dnn` も実機で一度も動かしておらず、推論の速さも測っていません。** **v0.4.0 で悪くなった点が 2 つあるので、上げる前に知っておいてください**: **PNG が Android・iOS・macOS arm64 で ARM 加速を失ったこと**(下の「対応 platform」)と、**Android の `.so` からシンボル表を落として配るようになったこと** —— 後者のため、実機で native crash が起きても関数名を復元できません(symbolicate 用の debug package はどこにも出していません)。**公開している C ABI は意図的に狭くしてあります** —— 面積を覆うことではなく、所有権・stride・エラー処理・IL2CPP・platform の振り分けを正しくすることを目的にしているからです。**Linux では v0.1.1 以降を使ってください** —— v0.1.0 の Linux プラグインは glibc 2.38 を要求し、Ubuntu 22.04 では読み込めませんでした。 ## これは何か @@ -28,7 +28,7 @@ OpenCV のアルゴリズムを実装し直すこと。OpenCV の API 全面を macOS のプラグインはパッケージに入っており、Unity 自身が Plugin Import Settings を読むところまでは確かめてあります —— EditMode のテストが、全 platform の binary を置いた状態で Unity の `PluginImporter` に「その `.meta` をどう解釈したか」を問います。**ただし macOS のライブラリは一度も読み込まれておらず、macOS 上で Unity を起動したこともありません。** あの platform は「ビルドされ、gating されている」であって「動かした」ではないと考えてください。 -**配っているが、実機で一度も動かしていないもの**: Android arm64-v8a と iOS arm64。CI は両方をクロスコンパイルし、Android の `.so` については**実物の ELF program header を読んで** 16 KB page 整列を確かめ、iOS の `.a` については**このプラグインが参照する OpenCV のシンボルを実際に束ねているか**を確かめます。**しかしそれは、電話機の上で動かすこととは別です。** Android / iOS のどの端末も、これらの binary を読み込んだことがありません。**v0.3.0 に入っているので、いま利用者に届いています。**[実機検証の手順](docs/m4-device-verification.md)を誰かが実施するまでは未検証として扱ってください。 +**配っているが、実機で一度も動かしていないもの**: Android arm64-v8a と iOS arm64。CI は両方をクロスコンパイルし、Android の `.so` については**実物の ELF program header を読んで** 16 KB page 整列を確かめ、iOS の `.a` については**このプラグインが参照する OpenCV のシンボルを実際に束ねているか**を確かめます。**しかしそれは、電話機の上で動かすこととは別です。** Android / iOS のどの端末も、これらの binary を読み込んだことがありません。**v0.3.0 から配っており、v0.4.0 にも入っているので、いま利用者に届いています。**[実機検証の手順](docs/m4-device-verification.md)を誰かが実施するまでは未検証として扱ってください。 **Web / Wasm はリポジトリに入っており、実際にブラウザで動きます** —— headless の Chromium が本物の WebGL Player を読み込み、EditMode と IL2CPP Player が走らせるのと @@ -41,7 +41,7 @@ encode / decode の検査が PNG ではなく JPEG を使うので、**画素の どちらの極端も通らないので、Web のビルドでは PNG を外してあります。 **他の 5 platform は PNG / JPEG の両方を扱えます。** -**PNG のデコードは Android・iOS・macOS でも ARM 加速を失っています**(Web だけではありません)。**これは v0.3.0 には入っておらず、次の版から効きます。** 上流の OpenCV 5.0.0 の欠陥を回避するため、この 3 つの arm64 platform で `PNG_ARM_NEON` を切る必要があり、これはアセンブリで書かれたカーネルと NEON intrinsics の経路を両方とも落とします —— 同じビルドスイッチを共有しているためです。`dnn` を使うかどうかに関わらず、これらの platform で `CvCodecs` を使う利用者全員に影響します。理由の詳細は[ロードマップ](docs/roadmap.md)にあります。 +**PNG のデコードは Android・iOS・macOS でも ARM 加速を失っています**(Web だけではありません)。**これは v0.4.0 から効きます**(v0.3.0 以前には入っていません)。 上流の OpenCV 5.0.0 の欠陥を回避するため、この 3 つの arm64 platform で `PNG_ARM_NEON` を切る必要があり、これはアセンブリで書かれたカーネルと NEON intrinsics の経路を両方とも落とします —— 同じビルドスイッチを共有しているためです。`dnn` を使うかどうかに関わらず、これらの platform で `CvCodecs` を使う利用者全員に影響します。理由の詳細は[ロードマップ](docs/roadmap.md)にあります。 全体を通して Unity 6000.3 以降が必要です。 @@ -49,7 +49,7 @@ encode / decode の検査が PNG ではなく JPEG を使うので、**画素の リリースは [github.com/ayutaz/OpenCVUnityNative/releases](https://github.com/ayutaz/OpenCVUnityNative/releases) にあります。 -**公開済みの版(v0.3.0)は 6 platform 分を運びます**: `Mat` のライフサイクル、`cvtColor` / `resize` / `GaussianBlur`、メモリ上の byte 配列との画像 encode / decode、QR コードの符号化・復号、ORB の特徴点、射影変換の推定、そして単眼カメラ校正の 3 段です。**この ABI はファイルパスを一切受け取りません** —— byte buffer だけです。これは意図したもので、Android の APK に入った `StreamingAssets` のファイルには開けるパスが存在せず、境界を越えるパスは Windows の文字コードの問題を引きずり込むためです。 +**公開済みの版(v0.4.0)は 6 platform 分を運びます**: `Mat` のライフサイクル、`cvtColor` / `resize` / `GaussianBlur` と広がった画像処理(2 値化・Canny・モルフォロジー・射影変換とその適用・テンプレート照合・輪郭抽出・確率的 Hough 直線・コーナーの副画素精度化)、基本演算、メモリ上の byte 配列との画像 encode / decode、QR コードの符号化・復号、ArUco マーカー、ORB の特徴点と記述子の照合、射影変換の推定、姿勢推定、単眼カメラ校正の 3 段、ステレオの視差、そして `OCVU_PROFILE_DNN` を立てたときだけ現れる ONNX の推論です。**この ABI はファイルパスを一切受け取りません** —— byte buffer だけです。これは意図したもので、Android の APK に入った `StreamingAssets` のファイルには開けるパスが存在せず、境界を越えるパスは Windows の文字コードの問題を引きずり込むためです。 全体像と**意図的に出していないもの**は [API リファレンス](docs/api-reference.md)に、本数そのものは [API 対応表](docs/api-map.md)の冒頭にあります。 @@ -120,8 +120,7 @@ shasum -a 256 -c SHA256SUMS.txt # macOS ### 追加 profile: dnn -**v0.3.0 には入っていません。次の版から配られます。** v0.3.0 に対して -`OCVU_PROFILE_DNN` を立てても、その先には何もありません。 +**v0.4.0 で入りました。** v0.3.0 以前に対して `OCVU_PROFILE_DNN` を立てても、その先には何もありません。 native binary には OpenCV の `dnn` module(ONNX の読み込み、blob 化、forward 推論)が **常に**入っています —— profile ごとに別 binary へ分けてはいません。理由は、6 platform @@ -242,7 +241,7 @@ CI は Unity のレーン以外、すべて同じ `tools/dev.ps1` を呼びま **この 4 つのうち 3 つ(`Graphics` レーン・tarball 導入の job・benchmark の job)は必須ではありません。赤くなっても merge は止まりません。** 残る 1 つ `Web browser E2E` は**必須です** —— 2026-09-10 に昇格しました。この食い違いこそが、上の段落で「CI が走らせている」と「CI が止める」を分けて書いている理由です。 -**`RenderTexture` の公開 API のうち、GPU が要る側は Editor でだけ実行されるようになりました。** `RenderTextureConverter.ToMat` と `RequestMat` は、パッケージに入る公開 API です(**次の版から**。上の「現状」)。2026-09-11 までは、実際に画素を運ぶ経路は CI で 1 度も実行されていませんでした —— **できないと考えられていたから**です。CI の Unity レーンはどれも `-nographics` で走ると思われており、その下では `RenderTexture` の生成は成功するのに読み出した画素が塗った色になりません。**しかしその前提は 1 度も測られていませんでした。** GameCI の Linux エディタコンテナは Unity を `xvfb` の下で、**`-nographics` を付けずに**起動します。そこで `Graphics` レーンを足したところ、本物の経路が通りました —— `AsyncGPUReadback` の側も含めてです。**IL2CPP の Player は別で、いまも覆われていません**: GameCI は standalone Player を action の中から `-nographics` で起動しており、そこはこちらから変えられません。引数の検証はどのレーンでも通っています(`ToMat(null)` を拒むこと)。通っていないのは Player 側の GPU の経路です。**必須でない `Graphics` レーンにしか居ないテスト**の一覧は `tests/UnityProject/Assets/Tests/EditMode/CiVisibilityTests.cs` が名指しで固定しているので、増えるときは意図して増やすことになります。 +**`RenderTexture` の公開 API のうち、GPU が要る側は Editor でだけ実行されるようになりました。** `RenderTextureConverter.ToMat` と `RequestMat` は、パッケージに入る公開 API です(**v0.4.0 から**。上の「現状」)。2026-09-11 までは、実際に画素を運ぶ経路は CI で 1 度も実行されていませんでした —— **できないと考えられていたから**です。CI の Unity レーンはどれも `-nographics` で走ると思われており、その下では `RenderTexture` の生成は成功するのに読み出した画素が塗った色になりません。**しかしその前提は 1 度も測られていませんでした。** GameCI の Linux エディタコンテナは Unity を `xvfb` の下で、**`-nographics` を付けずに**起動します。そこで `Graphics` レーンを足したところ、本物の経路が通りました —— `AsyncGPUReadback` の側も含めてです。**IL2CPP の Player は別で、いまも覆われていません**: GameCI は standalone Player を action の中から `-nographics` で起動しており、そこはこちらから変えられません。引数の検証はどのレーンでも通っています(`ToMat(null)` を拒むこと)。通っていないのは Player 側の GPU の経路です。**必須でない `Graphics` レーンにしか居ないテスト**の一覧は `tests/UnityProject/Assets/Tests/EditMode/CiVisibilityTests.cs` が名指しで固定しているので、増えるときは意図して増やすことになります。 Unity のレーンは Linux で走り、Windows の IL2CPP Player はローカルのレーンだけが担います。**これはいまや推測ではなく実測に基づく結論です。** 以前ここに書いてあった理由は、実際には別の action と別のイメージ系統についての上流 issue を挙げていました。2026-08-31 に `windows-2022` で実際に試したところ、**EditMode は動いて 33 件通りました。Standalone は動きませんでした** —— IL2CPP は C++ を生成し、GameCI の Windows コンテナにはそれをコンパイルする MSVC が無いため、`ToolchainNotFoundException` でビルドが落ちます。**したがって Windows 固有の IL2CPP の欠陥は、見落としではなく設計上 CI に映りません。** macOS は同じ時期に 4 回試し、さらに手前で失敗します —— GameCI は darwin を支えず、エディタを直接入れる経路はライセンスが「entitlement 0 件」を返すところで止まります。ロードマップに両方の試行が記録されています。 diff --git a/README.md b/README.md index c8c4e8e..08aad2e 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ OpenCV 5 for Unity through a project-owned C ABI, distributed as a reproducible [日本語](README.ja.md) -> **Status: v0.3.0 is the newest published release (2026-09-04), and the repository is now well ahead of it.** Everything below describes the repository, not that release. **v0.3.0 is tag `03a4557`, which predates both the September API expansion and all of M7** — so the gap is not a short list of features, it is everything merged since. The one number that is generated at both ends: `docs/api-map.md` lists **27 public C ABI functions at v0.3.0 and 57 here**. On the C# side `CvAruco`, `CvCoreOps`, `CvStereo`, `CvDnn` and `RenderTextureConverter` do not exist at that tag at all, so setting `OCVU_PROFILE_DNN` against v0.3.0 defines a symbol with nothing behind it. **What has actually shipped is recorded in the "配布" sections of the [roadmap](docs/roadmap.md)** — that, not this paragraph, is the source of truth for it. It is the first release with six platforms — Windows x64, macOS arm64, Linux x64, Android arm64-v8a, iOS arm64 and Web/WebGL — the first with a generated binding layer, and the first with camera calibration. Every platform is built, tested and packaged by CI; Unity itself exercises the plugin on Mono (EditMode), a real IL2CPP player, and a headless browser. **Some honest limits.** **Android and iOS have never been run on a device** — CI cross-compiles them and inspects the artifacts, but no phone has loaded these binaries. **Web has no PNG**: `imgcodecs` there decodes and encodes JPEG only (see below), and the browser it was driven in is one headless Chromium on Linux. **Unity has never been run on macOS at all**, though its plugin settings are verified by asking Unity itself on other systems. The public C ABI is deliberately narrow, because the point was getting ownership, stride, error handling, IL2CPP and platform gating right rather than covering surface area. **If you are on Linux, take v0.1.1 or later:** the Linux plugin in v0.1.0 required glibc 2.38 and would not load on Ubuntu 22.04. +> **Status: v0.4.0 is the newest published release (2026-09-12).** Everything below describes the repository, which matches that release apart from documentation edited after the tag was cut. **v0.4.0 is the first release to carry the September 2026 API expansion and all of M7.** The one number that is generated at both ends: `docs/api-map.md` counted **27 public C ABI functions at v0.3.0 and 57 at v0.4.0**. On the C# side `CvAruco`, `CvCoreOps`, `CvStereo`, `CvDnn` and `RenderTextureConverter` did not exist at v0.3.0 at all and are in the package you download now; if you are still on v0.3.0, setting `OCVU_PROFILE_DNN` there defines a symbol with nothing behind it. **What has actually shipped is recorded in the "配布" sections of the [roadmap](docs/roadmap.md)** — that, not this paragraph, is the source of truth for it. It carries six platforms — Windows x64, macOS arm64, Linux x64, Android arm64-v8a, iOS arm64 and Web/WebGL — and is the first release with opt-in ONNX inference (`dnn`), ArUco markers, pose estimation, stereo disparity and the `RenderTexture` integration; six platforms, the generated binding layer and camera calibration first shipped in v0.3.0. Every platform is built, tested and packaged by CI; Unity itself exercises the plugin on Mono (EditMode), a real IL2CPP player, and a headless browser. **Some honest limits.** **Android and iOS have never been run on a device** — CI cross-compiles them and inspects the artifacts, but no phone has loaded these binaries. **Web has no PNG**: `imgcodecs` there decodes and encodes JPEG only (see below), and the browser it was driven in is one headless Chromium on Linux. **Unity has never been run on macOS at all**, though its plugin settings are verified by asking Unity itself on other systems. **`dnn` has never been run on a device either, and its inference speed has not been measured.** Two things changed for the worse in v0.4.0 and are worth knowing before you upgrade: **PNG lost its ARM acceleration on Android, iOS and macOS arm64** (see *Platforms*), and **the Android `.so` now ships stripped of its symbol table**, so a native crash on Android cannot be symbolicated — no debug package is published anywhere. The public C ABI is deliberately narrow, because the point was getting ownership, stride, error handling, IL2CPP and platform gating right rather than covering surface area. **If you are on Linux, take v0.1.1 or later:** the Linux plugin in v0.1.0 required glibc 2.38 and would not load on Ubuntu 22.04. ## What this is @@ -40,7 +40,7 @@ gated rather than exercised. both, checks the Android `.so` for 16 KB page alignment against the real ELF program headers, and confirms the iOS `.a` actually bundles the OpenCV symbols this plugin references. **None of that is the same as running on a phone.** No Android or iOS device -has ever loaded these binaries. **They are in v0.3.0, so they reach users today**; +has ever loaded these binaries. **They have shipped since v0.3.0 and are in v0.4.0, so they reach users today**; treat them as unverified until someone runs [the device checklist](docs/m4-device-verification.md). @@ -55,7 +55,7 @@ fail to link on undefined ones. Neither extreme works, so the Web build has PNG off. Every other platform has both. **PNG decoding lost its ARM acceleration on Android, iOS and macOS** (not just Web). -**This is not in v0.3.0; it takes effect from the next release.** +**This shipped in v0.4.0; v0.3.0 and earlier are unaffected.** Working around an upstream OpenCV 5.0.0 defect required turning off `PNG_ARM_NEON` on those three arm64 platforms, which drops both the hand-written assembly kernel and the NEON intrinsics path — they share the same build switch. This affects every `CvCodecs` @@ -68,10 +68,7 @@ Unity 6000.3 or newer throughout. Releases live at [github.com/ayutaz/OpenCVUnityNative/releases](https://github.com/ayutaz/OpenCVUnityNative/releases). -**The published release (v0.3.0) carries all six platforms**: `Mat` lifecycle, -`cvtColor` / `resize` / `GaussianBlur`, encoding/decoding images to and from byte -arrays in memory, QR encode/decode, ORB keypoints, homography estimation, and the -three stages of monocular camera calibration. The ABI takes no file paths at all — +**The published release (v0.4.0) carries all six platforms**: `Mat` lifecycle, `cvtColor` / `resize` / `GaussianBlur` plus the wider `imgproc` set (thresholding, Canny, morphology, perspective transform and warp, template matching, contours, probabilistic Hough lines, sub-pixel corners), the core array operations, encoding/decoding images to and from byte arrays in memory, QR encode/decode, ArUco markers, ORB keypoints and descriptor matching, homography and pose estimation, the three stages of monocular camera calibration, stereo disparity, and — only when you set `OCVU_PROFILE_DNN` — ONNX inference. The ABI takes no file paths at all — only byte buffers. That is on purpose: a `StreamingAssets` file inside an Android APK has no path that can be opened, and a path crossing this boundary would drag Windows text encoding along with it. @@ -189,8 +186,7 @@ every release, so they are not repeated here. ### Optional profiles: dnn -**Not in v0.3.0 — this ships in the next release.** Setting `OCVU_PROFILE_DNN` -against v0.3.0 defines a symbol with nothing behind it. +**New in v0.4.0.** Against v0.3.0 or earlier, setting `OCVU_PROFILE_DNN` defines a symbol with nothing behind it. The native binary always contains OpenCV's `dnn` module (ONNX loading, blob conversion, and forward inference) — it is not split into a separate binary, @@ -350,7 +346,7 @@ it"; the two are not the same thing. **The GPU half of the `RenderTexture` API is now exercised, in the Editor only.** `RenderTextureConverter.ToMat` and `RequestMat` are public API in the package -(from the next release — see *Status*). Until 2026-09-11 the code path that +(since v0.4.0 — see *Status*). Until 2026-09-11 the code path that actually moves pixels had never run in CI, on the assumption that it could not: every CI Unity lane was believed to run with `-nographics`, where `RenderTexture` creation succeeds but the pixels read back are not the ones you drew. **That diff --git a/docs/README.md b/docs/README.md index 1c11110..f9dccd9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -56,7 +56,7 @@ ## Status -M0〜M3.5 は完了しました(**M3.5 は完了条件 6 件すべてを 2026-08-30 に満たしました**。判定は roadmap の M3.5 節が正本)。M2(Windows vertical slice)は 8 件、M3(Desktop 3 platform と配布の再現性)は 6 件の完了条件をすべて実測で満たし、**v0.1.0(2026-08-28)と v0.1.1(2026-08-29)を公開しました**(**その後 v0.2.0 / v0.3.0 と重ね、現在の最新は v0.3.0(2026-09-04、6 platform)です**)。**M3.5 の成果は v0.2.0 で、M4 / M5 / M6 の成果は v0.3.0 で配りました。M7 の成果はまだ配っていません** —— 最新の公開版は v0.3.0 で、`dnn` を含む M7 の成果が利用者に届くのは次の版からです。 +M0〜M3.5 は完了しました(**M3.5 は完了条件 6 件すべてを 2026-08-30 に満たしました**。判定は roadmap の M3.5 節が正本)。M2(Windows vertical slice)は 8 件、M3(Desktop 3 platform と配布の再現性)は 6 件の完了条件をすべて実測で満たし、**v0.1.0(2026-08-28)と v0.1.1(2026-08-29)を公開しました**(**その後 v0.2.0 / v0.3.0 / v0.4.0 と重ね、現在の最新は v0.4.0(2026-09-12、6 platform)です**)。**M3.5 の成果は v0.2.0 で、M4 / M5 / M6 の成果は v0.3.0 で、M7(`dnn` の opt-in profile ほか)と 2026-09 の API 拡張の成果は v0.4.0 で配りました。** M2 の最後に残っていた条件 7(CI 上で L4/L5 を実行)は、game-ci でランナーへの Unity 導入とライセンスのアクティベーションを行い、Linux で走らせることで満たしました。**その過程で、公開済み v0.1.0 の Linux 版が古い環境で読み込めない欠陥が判明しました** —— ubuntu-24.04 でビルドした `.so` が GLIBC_2.38 を要求していたためで、Unity を CI で実際に動かすまで誰も気づけませんでした。Linux のビルドを `ubuntu:22.04` コンテナへ移し、要求を 2.34 に下げたうえで、ビルド時点で上限を検査するようにしています。 @@ -64,7 +64,7 @@ M3(Desktop 3 platform と配布の再現性)は、roadmap の完了条件 6 M3.5(配布の形と、実用に必要な最小の穴)は、roadmap の完了条件 **6 件すべてを満たしました**(2026-08-30)。**v0.2.0 を公開し、OpenUPM にも登録されています。****CI は green で main に入りました**(PR #34、`41cda19`、2026-08-29。チェックの内訳と Unity レーンの実測は roadmap の M3.5 節にあります)。 -**最後に閉じたのは条件 3 と、条件 4 の (c)(OpenUPM の登録申請)です。** 条件 3 について: M3.5 の時点では「満たすが未実証」で、**自動で走る唯一の場所(`ci-unity.yml`)に Linux の plugin 1 つしか無く、6 件が要素 1 個の集合を検査して緑になっていました**。PR #37 で `ci-unity` が windows / macOS の plugin も自分でビルドして重ねる形にし、**CI が 3 platform 同居の状態で `native plugins present: 3` と gating 4 件の個別 Passed を出しました**(run 33290375806)。条件 4 の (c) は **v0.2.0 を公開し、openupm/openupm へ提出して受理されました**(PR #6843。`https://package.openupm.com/com.ayutaz.opencv-unity-native` が `0.2.0` を配信しています)。 +**最後に閉じたのは条件 3 と、条件 4 の (c)(OpenUPM の登録申請)です。** 条件 3 について: M3.5 の時点では「満たすが未実証」で、**自動で走る唯一の場所(`ci-unity.yml`)に Linux の plugin 1 つしか無く、6 件が要素 1 個の集合を検査して緑になっていました**。PR #37 で `ci-unity` が windows / macOS の plugin も自分でビルドして重ねる形にし、**CI が 3 platform 同居の状態で `native plugins present: 3` と gating 4 件の個別 Passed を出しました**(run 33290375806)。条件 4 の (c) は **v0.2.0 を公開し、openupm/openupm へ提出して受理されました**(PR #6843。`https://package.openupm.com/com.ayutaz.opencv-unity-native` が**当時 `0.2.0` を配信していました**)。 以下のローカルの数字はこのマシン(Windows)での 2026-08-30 の実測です。 @@ -76,7 +76,7 @@ M3.5(配布の形と、実用に必要な最小の穴)は、roadmap の完 `imgcodecs` は **M3.5 で初めてリンクされました**。それまで `cmake/FindOpenCvUnityDeps.cmake` は `COMPONENTS core imgproc` だけで、リポジトリ内の複数箇所にあった「モジュールはリンク済み」という記述は**誤り**でした。誤解の出どころも記録しておきます: `tools/opencv-config.psd1` の `Modules` には `imgcodecs` が入っているので **OpenCV 自体はそれを含めてビルドされており**、`ocvu_get_build_information()` も `To be built: … imgcodecs …` と報告します。**「OpenCV に入っている」と「このプラグインがリンクしている」は別です。** 気づいたのは CMake を読んだからではなく、実装を書いた時点で `cv::imencode` / `cv::imdecode` が未解決の外部シンボルになったからです。C ABI に `ocvu_imencode` / `ocvu_imdecode` が加わり、公開 ABI は 18 本から 20 本、allowlist は 9 本から 11 本になりました。**扱うのはメモリ上の byte 列だけで、ファイルパスは受けません**(理由は [所有権と versioning](./abi-ownership-and-versioning.md) §1.6)。 -検証する Unity は 6000.0 から **6000.3 LTS(6000.3.16f1)** へ載せ替えました(6000.0 の通常サポートが 2026-10 に終わるためです)。6.3 で EditMode と IL2CPP Player が通っています(**件数はここに書きません** —— 正本は `CLAUDE.md` のテストレーンの表で、写すと検査を 1 件足した日にこの行だけが嘘になります。実際 M3.5 / M4 / M5 / 2026-09 の API 拡張で 4 度動きました) —— **IL2CPP モジュールは Hub の CLI で先に入れる必要がありました**(入っていない状態では Player のビルドが「Currently selected scripting backend (IL2CPP) is not installed」で落ちます)。OpenUPM への登録は**提出し、受理されました**(openupm/openupm PR #6843、2026-08-30 に自動マージ。`https://package.openupm.com/com.ayutaz.opencv-unity-native` が 0.2.0 を配信しています。詳細は [OpenUPM への登録](./openupm-registration.md))。詳細は roadmap の M3.5 節にあります。 +検証する Unity は 6000.0 から **6000.3 LTS(6000.3.16f1)** へ載せ替えました(6000.0 の通常サポートが 2026-10 に終わるためです)。6.3 で EditMode と IL2CPP Player が通っています(**件数はここに書きません** —— 正本は `CLAUDE.md` のテストレーンの表で、写すと検査を 1 件足した日にこの行だけが嘘になります。実際 M3.5 / M4 / M5 / 2026-09 の API 拡張で 4 度動きました) —— **IL2CPP モジュールは Hub の CLI で先に入れる必要がありました**(入っていない状態では Player のビルドが「Currently selected scripting backend (IL2CPP) is not installed」で落ちます)。OpenUPM への登録は**提出し、受理されました**(openupm/openupm PR #6843、2026-08-30 に自動マージ。`https://package.openupm.com/com.ayutaz.opencv-unity-native` が**当時 0.2.0 を配信していました**。詳細は [OpenUPM への登録](./openupm-registration.md))。詳細は roadmap の M3.5 節にあります。 M5(binding specification と generator)は**完了条件 5 件すべてを満たしました**(2026-09-02。判定表は roadmap の M5 節が正本)。境界の宣言を手で書く経路が無くなり、`bindings/spec/*.json` の entry から **C ABI 宣言 / C# の P/Invoke / 全 entry point を呼ぶ到達性テスト / [API 対応表](./api-map.md)** が `./tools/dev.ps1 generate` で出るようになりました(**本数は上に書いたとおり対応表の冒頭が数えます**)。**手書きの `[DllImport]` は 0 個です。** 一致は `./tools/dev.ps1 verify-generated` が見て、これは `dev.ps1 test` に入っているので 3 platform の CI が走らせます。**条件 2(`geometry` / `calib` / `features` / `objdetect` の追加)は当初は次へ送りましたが、続く 3 つの計画で閉じました** —— `objdetect`(QR の符号化・復号)と `features`(ORB 検出)、`geometry`(射影変換の推定。**リンクは無料でした** —— 既に推移的に引かれていました)、カメラの歪み補正、そして **`calib` module と `cv::calibrateCamera`**(2026-09-02)。**最後の 1 つだけが高く**、構成ハッシュが変わって 5 platform 分の OpenCV を作り直しました。**これでカメラ校正の 3 段(格子点を見つける / 係数を解く / 係数で補正する)が揃っています。** 詳細は roadmap の M5 節。**M4(Mobile)は依然として完了していません**(9 件中 6 件。詳細は roadmap の M4 節)。 @@ -95,13 +95,15 @@ WebGL 支援が自前の libpng を同梱しているためです。他の 5 pla (**数はここに写しません** —— ABI が 1 本増えるたびに動くので、roadmap の M6 節が持ちます)。**ただし動かしているブラウザはそれ 1 つだけ**です。 -**利用者に届いているのは v0.3.0 です(2026-09-04 公開)。** +**利用者に届いているのは v0.4.0 です(2026-09-12 公開)。** その 1 つ前が v0.3.0(2026-09-04 公開)で、 **M4(5 platform)・M5(生成器と校正 API)・M6(Web)の成果が、これで初めて 届きました** —— v0.2.0 以来です。**版番号は当初「v0.3.0 を飛ばして v0.4.0」と 決めていましたが覆しました** —— v0.3.0 という名前で世に出た物が 1 つも無いことを 実測したためで、2026-08-31 の下書き(生成物が 1 つも入っていない)と tag は 破棄して打ち直しました。配布の記録は -[ロードマップ](./roadmap.md) の「配布 その 5」にあります。 +[ロードマップ](./roadmap.md) の「配布 その 5」に、v0.4.0 のそれは「配布 その 6」にあります。 + +**v0.4.0 で初めて届いたのは、M7(`dnn` の opt-in profile / `RenderTexture` の低コピー経路 / native と C# の module 分離)と 2026-09 の API 拡張です。** **退行が 1 つ入っています** —— PNG の encode / decode が Android・iOS・macOS arm64 で ARM 加速を失いました(上流 OpenCV 5.0.0 の vendoring の欠陥を避けるための取引で、JPEG と `core` / `imgproc` の SIMD には触れていません)。**実機で一度も動かしていないことは、この版でも変わりません。** M7(Optional profiles と性能)は**完了条件 5 件すべてを満たしました**(2026-09-10)。 **M7 が最後のマイルストーンで、後続はありません** —— roadmap の `## M` 見出しは diff --git a/docs/api-reference.md b/docs/api-reference.md index c16250a..78981cc 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -29,7 +29,8 @@ M5 の追加は §3.6〜§3.9)を、所有権契約そのものは同 §1・§ 6000.3.16f1 の 1 版だけ**)。**対応 platform は最新の公開版のもの**(**一覧をここに写さない** —— 正本は [README](../README.md) の Status である)。 **どこまでが「対応」かの正本は [README](../README.md) の Status である** —— -mobile と Web の現況(何がビルドされ、何が公開版に入っておらず、何が実機で +mobile と Web の現況(何がビルドされ、何が実機で動いていないか)は +あちらに 1 箇所だけ書いてあるので、**ここには写さない。** 動いていないか)はあちらに 1 箇所だけ書いてあるので、**ここには写さない。** **native plugin の binary はリポジトリに入っていない。** @@ -960,7 +961,9 @@ CPU から読むには GPU → CPU の転送が要る。 (実測。詳細は [性能](./performance.md))。この経路を検証するレーンは `-nographics` を付けずに走る —— ローカルの `test-unity-graphics` と、 **2026-09-11 に足した CI の `Graphics` レーン**(`ci-unity.yml`)である。 -**ただし後者は必須チェックではないので、赤くても merge は止まらない。** +****このレーンが merge を止めるかどうかは `CLAUDE.md` の「機構として強制されて +いること」が持つ**(正本はさらにその先の GitHub 側 branch protection の設定で +ある)—— ここに写すと、昇格した日にこちらだけが静かに嘘になる。** ### 2.17 `CvUnity.Dnn.CvDnn` / `CvNet`(M7c で追加、`dnn` profile) diff --git a/docs/m4-device-verification.md b/docs/m4-device-verification.md index 33b3fbf..4f057b3 100644 --- a/docs/m4-device-verification.md +++ b/docs/m4-device-verification.md @@ -21,11 +21,13 @@ roadmap の M4 完了条件のうち、次の 2 件がこれに当たる。 **~~`v0.3.0` の下書きを公開してはならない。~~ この警告は 2026-09-04 に失効した。** 指していた下書きは M5 が main に入る前に作ったもので生成物が 1 つも入っておらず、 **下書きと tag は破棄して `03a4557` で打ち直し、v0.3.0 として公開済みである** -(roadmap の「配布 その 5」)。**いまの v0.3.0 は「出してはいけないもの」ではなく、 -現在の最新公開版である。** +(roadmap の「配布 その 5」)。**その v0.3.0 も、もう最新ではない** —— +**2026-09-12 に v0.4.0 を公開した**(roadmap の「配布 その 6」)。 +**この手順書が対象にすべきは、常に最新の公開版である。** **この手順書は `dnn`(M7c)を扱っていない。** M7 で `dnn` が opt-in profile として 入ったが、実機での確認手順はここに無い —— **`dnn` も実機で 1 度も動かしていない。** +**v0.4.0 でその `dnn` が利用者に届いた**ので、**手順が無いまま配った状態**である。 **ここを実施して問題が見つかったら、その版を直した新しい版を出す**(一度配った ものは黙って差し替えない。v0.1.1 がその形だった)。 diff --git a/docs/openupm-registration.md b/docs/openupm-registration.md index a73bd43..158fb86 100644 --- a/docs/openupm-registration.md +++ b/docs/openupm-registration.md @@ -56,14 +56,26 @@ M3.5 で 2 つの前提が揃った。 ```yaml name: com.ayutaz.opencv-unity-native displayName: OpenCV Unity Native -description: OpenCV 5 for Unity through a project-owned C ABI. Apache-2.0. +description: >- + OpenCV 5 for Unity through a project-owned C ABI. Ships prebuilt native + binaries for Windows x64, macOS arm64, Linux x64, Android arm64-v8a, iOS + arm64 and Web (WebGL) in a single package, so one dependency covers the + editor and the build target. + + + Not a wrapper around OpenCvSharp. The C ABI is versioned, IL2CPP-safe and + built reproducibly by CI; ownership, stride and error handling are contract + tested. Requires Unity 6000.3 or newer. repoUrl: 'https://github.com/ayutaz/OpenCVUnityNative' parentRepoUrl: null licenseSpdxId: Apache-2.0 licenseName: Apache License 2.0 +# **この 2 つは提出前に差し替えてある。** `computer-vision` と `native` は +# どちらも OpenUPM に存在しない slug で(正本は openupm/openupm の +# `data/topics.yml`)、そのままでは Data validation に弾かれていた。 topics: - - computer-vision - - native + - integration + - utilities hunter: ayutaz image: null gitTagPrefix: 'v' diff --git a/docs/roadmap.md b/docs/roadmap.md index 878d0d1..fc428b3 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -72,7 +72,7 @@ public OSS リポジトリのため GitHub-hosted runner を無償で使える | ~~`ci-desktop-matrix.yml`~~ | — | **作らなかった。** 3 platform は `ci-native.yml` の job 追加(`macos` / `linux`)と `ci-sanitizers.yml` の `linux-asan` job で実現した。別ファイルにすると同じ手順が 2 箇所に分かれるため | M3 | | ~~`ci-mobile.yml`~~ | —— | **作らなかった。** Android / iOS のクロスビルドは `ci-native.yml` の job として足し、実機 smoke test は CI では原理的に閉じないので `docs/m4-device-verification.md` の手順書に落とした | M4 | | ~~`ci-web.yml`~~ | — | ~~Unity 同梱 Emscripten での Wasm ビルドと browser E2E~~ | **作らなかった。** Wasm のクロスビルドは `ci-native.yml` のクロス job、browser E2E は `ci-unity.yml` の `web-e2e` job に置いた。**nightly でもない** —— pull request と push で走る。Player を建てる job を別にしたのは、**Unity Test Framework が WebGL の Player を batchmode から走らせられない**ためで、Unity のレーンとは起動の仕方が根本的に違う | -| `release.yml` | tag / **pull request**(空撃ち) / `workflow_dispatch` | **全部入りの UPM tarball(配る正)** と platform ごとの tarball、manifest / checksums / SBOM / third-party notices と `SHA256SUMS.txt` を GitHub Release へ。**staging した数を数え**、全部入りが名前で並んでいることも見る(**件数は platform が増えれば増えるので、実数は `CLAUDE.md` の workflow 表が持つ**)。**pull request でも走るようにしたのは M4 の後**で、tag でしか走らなかった間に欠陥が 3 件たまったためである(うち 1 件は「tag を打つと Release が 1 件も作られない」)。**全部入りには SBOM と build-manifest を付けない** —— どちらも復元済みの OpenCV artifact から作るので、束ねる job には元が無く、混ぜた版を捏造しない。**M3.5 が足した配線(全部入りの組み立て・17 件の staging・SHA256SUMS)は 2026-08-30 の空撃ちで初めて通した。** それまで空撃ちは publish job を丸ごと飛ばしており、**束ねる側は tag を打つまで 1 行も動かなかった** —— job を `assemble`(条件なし)と `publish`(job 単位で tag に限る)に割って直した。**実績は 2 つ**: run 33286928144 は条件を最後の step に降ろしただけの形(レビューで取り消した)、run 33289128197 が**いまの 2 job 構成**である。どちらも Release は作られていない。**tag で 2 回実行済み**(v0.1.0 = 2026-08-28、v0.1.1 = 2026-08-29。どちらも `--draft` で下書きを作り、人が点検してから公開した)。**M3 当時の空撃ち**(run 33156465235、3 platform とも success)は publish job ごと skip されていた —— **この形は 2026-08-30 に変えた**(上記)ので、いまの空撃ちは Release を作る job 以外を通る | M3 | +| `release.yml` | tag / **pull request**(空撃ち) / `workflow_dispatch` | **全部入りの UPM tarball(配る正)** と platform ごとの tarball、manifest / checksums / SBOM / third-party notices と `SHA256SUMS.txt` を GitHub Release へ。**staging した数を数え**、全部入りが名前で並んでいることも見る(**件数は platform が増えれば増えるので、実数は `CLAUDE.md` の workflow 表が持つ**)。**pull request でも走るようにしたのは M4 の後**で、tag でしか走らなかった間に欠陥が 3 件たまったためである(うち 1 件は「tag を打つと Release が 1 件も作られない」)。**全部入りには SBOM と build-manifest を付けない** —— どちらも復元済みの OpenCV artifact から作るので、束ねる job には元が無く、混ぜた版を捏造しない。**M3.5 が足した配線(全部入りの組み立て・17 件の staging・SHA256SUMS)は 2026-08-30 の空撃ちで初めて通した。** それまで空撃ちは publish job を丸ごと飛ばしており、**束ねる側は tag を打つまで 1 行も動かなかった** —— job を `assemble`(条件なし)と `publish`(job 単位で tag に限る)に割って直した。**実績は 2 つ**: run 33286928144 は条件を最後の step に降ろしただけの形(レビューで取り消した)、run 33289128197 が**いまの 2 job 構成**である。どちらも Release は作られていない。**tag で実行した実績がある**(v0.1.0 / v0.1.1 / v0.2.0 / v0.3.0 / v0.4.0。どちらも `--draft` で下書きを作り、人が点検してから公開した)。**M3 当時の空撃ち**(run 33156465235、3 platform とも success)は publish job ごと skip されていた —— **この形は 2026-08-30 に変えた**(上記)ので、いまの空撃ちは Release を作る job 以外を通る | M3 | | `ci-lint.yml` | push(main) / PR / 手動 | actionlint / shellcheck / PSScriptAnalyzer / 文書の相対リンク検査の 4 job。**静的に読めば分かる誤りを、CI を 1 周(10〜20 分)回して確かめていた**のを埋める | M3 後 | | `codeql.yml` | push(main) / PR / 週 1 / 手動 | C++ と C# の静的解析。sanitizer が「実際に踏んだ経路」を見るのに対し、CodeQL は経路を実行せずに探すので**重なっていない** | M3 後 | | `nightly.yml` | 毎日 04:00 UTC / 手動 | 誰も push していない間に壊れることを見つける。Linux 成果物の移植性 / Windows・macOS の速いレーン / OpenCV artifact の期限切れ確認の **3 job 定義**(速いレーンは `lanes` という 2 runner の matrix なので、**実行時は 4 件**になる)。**2026-08-29 から schedule で毎日走っている**(下記) | M3 後 | @@ -744,7 +744,7 @@ M5 の module 拡張で `objdetect` / `features` / `geometry` / `calib`、そし | --- | --- | --- | --- | | 1 | ~~**1 つの package に 1 platform 分の binary しか入らない**~~ **M3.5 で解消** | Unity は同じ package ID を 1 つしか導入できない。「エディタは Windows、実機は Android」が表現できなかった | **M3.5 完了**。全部入り tarball(`com.ayutaz.opencv-unity-native.tgz`)が配る正になり、Desktop 3 platform が同居した状態で `test-unity-tarball` が 16 passed | | 2 | ~~画像を encode / decode できない~~ **M3.5 で解消** | 比較した競合はいずれも画像の入出力を持つ(そちらはファイル経路まで含む)。**ここに「モジュールはリンク済みで、足りないのは ABI 関数だけ」と書いていたのは誤りで、実際は `imgcodecs` をリンクしていなかった**(下記 M5 節) | **M3.5 完了**(M5 から前倒し)。component を足し、`ocvu_imencode` / `ocvu_imdecode` を出した | -| 3 | ~~**OpenUPM に載っていない**~~ **解消済み(2026-08-30)** | OSS の Unity パッケージが探される場所。#1 に加えて asset 名と容量の条件がある | **(a) 版番号なしの asset 名・(b) 容量の検査・(c) 登録申請のすべてが済んだ。** openupm/openupm PR #6843 が自動マージされ、`https://package.openupm.com/com.ayutaz.opencv-unity-native` が配信している([登録の記録](./openupm-registration.md))。**配信されている版は `0.3.0` である**(2026-09-04 に確認。下の「配布 その 5」)—— 登録と、新しい版が届くことは別で、`0.2.0` から `0.3.0` へ切り替わるのに公開の約 4 時間を要した | +| 3 | ~~**OpenUPM に載っていない**~~ **解消済み(2026-08-30)** | OSS の Unity パッケージが探される場所。#1 に加えて asset 名と容量の条件がある | **(a) 版番号なしの asset 名・(b) 容量の検査・(c) 登録申請のすべてが済んだ。** openupm/openupm PR #6843 が自動マージされ、`https://package.openupm.com/com.ayutaz.opencv-unity-native` が配信している([登録の記録](./openupm-registration.md))。**配信されている版は、v0.4.0 を公開した直後はまだ `0.3.0` である**(v0.4.0 の公開は 2026-09-12。OpenUPM は自前のビルドキューを持つので反映まで数時間かかり、`0.2.0` から `0.3.0` へ切り替わったときは公開の約 4 時間後だった。**`0.4.0` に切り替わったのを確かめたら、この行をそう直すこと** —— 確かめ方は「配布 その 6」の step 9)—— 登録と、新しい版が届くことは別で、`0.2.0` から `0.3.0` へ切り替わるのに公開の約 4 時間を要した | | 4 | 検証している Unity が 1 版だけ | **M3.5 でその 1 版を 6000.0.82f1 → 6000.3.16f1 に載せ替えた**(6000.0 LTS の通常サポートが 2026-10 に終わるため。6.3 LTS は 2027-12 まで)。**版が 1 つしかないこと自体は変わっていない** | **M3.5 完了**(載せ替えのみ。複数版の検証は担当なし) | | 5 | ~~カメラ映像を受け取れない~~ **M4 で解消** | `WebCamTextureConverter`(3 overload)が `WebCamTexture` から `CvMat` を作る。**新しい C ABI 関数は 1 本も増えていない** —— 既存の上に立つ純 C# である | **解消済み(2026-08-30)** | | 6 | macOS で Unity に読み込ませたことがない | 「iOS のビルドに macOS runner が要るので M4 で自然に埋まる」と書いていたが、**埋まらなかった。** macOS runner は plugin をビルドするだけで Unity を起動しない | **未解消。2026-08-31 に 4 回試して「CI では閉じない」と確定した**(game-ci は macOS を支えず、Hub で直接入れる経路は Editor が 14 分で入るのにライセンスで止まる)。詳細は下の「担当が無かった制約」 | @@ -1094,7 +1094,7 @@ linkage 検証も配布物生成も通ったのに、Linux の `.so` は古い ので**大きな後退**になる。(c) **明記すれば利用者が判断できる** —— v0.1.0 との違いは そこである。あのときは「動く」と暗黙に主張していた。 -**実機で動かないと分かったら v0.4.1 を出す。** このリポジトリは一度配ったものを +**実機で動かないと分かったら v0.3.1 を出す。** このリポジトリは一度配ったものを 黙って差し替えない(v0.1.1 がそうだった)。 #### やること @@ -1224,7 +1224,9 @@ linkage 検証も配布物生成も通ったのに、Linux の `.so` は古い `docs/README.md`(Status)、`README.md` と `README.ja.md`(冒頭の Status と 「導入」の節)、`docs/api-reference.md`(対象範囲)、 `.github/release-notes.md`(次の版のために「前の版」を繰り上げる)、 - `docs/openupm-registration.md`(「`0.2.0` を配信している」)、 + `docs/openupm-registration.md`(**v0.4.0 の時点で版番号を書かない形に直した** —— + 「配信している」とだけ書く。出すたびにその行だけが古くなるため。 + **直っているので、次からはここを見る必要が無い**)、 `docs/unity-opencv-integration-research-and-plan.md`(比較表の前書き。 **ここは既に古い** —— M6 が抜けている)。 **もう 1 つある: `docs/m4-device-verification.md`** —— @@ -1388,6 +1390,126 @@ tag を打ち直した後に OpenUPM がそれを拾い直すかは、**確か - **M4 の残り 4 件を閉じること**(実機 2 件は端末が要り、CI の 2 件は「CI では閉じない」と結論済み) - **v0.3.0 の下書きを再利用すること**(M5 前のものなので作り直す) +### 配布 その 6 — v0.4.0(**2026-09-12 に公開した**) + +> **公開済み(2026-09-12T17:04:16Z)。** https://github.com/ayutaz/OpenCVUnityNative/releases/tag/v0.4.0 +> +> **M7 の成果(`dnn` の opt-in profile・低コピー経路・module 分離)と、 +> 2026-09 の API 拡張が、これで初めて利用者に届いた** —— v0.3.0 以来である。 +> **公開している C ABI は 27 本から 57 本になった**(`OCVU_ABI_VERSION` は 1 のまま)。 + +#### 実測 + +| 確かめたこと | 結果 | +| --- | --- | +| asset | **33 件**(6 platform × 5 + 全部入りの 2 + `SHA256SUMS.txt`)。`sha256sum -c` で 32 件すべて OK | +| 全部入りの大きさ | **77,530,189 バイト**(v0.3.0 は 69,565,901)。上限 104,857,600 に対して約 1.35 倍の余裕 | +| 全部入りの中身 | 正本(`$AllPlatformBinaries`)から導いた **6 platform の binary と `.meta` がすべて在る**。`package.json` は `0.4.0`、生成物の `.g.cs` が 10 本(`NativeMethods.Dnn.g.cs` を含む) | +| Linux の移植性 | `GLIBC<=2.34, GLIBCXX<=3.4.29`(上限 2.35 / 3.4.30) | +| Android の 16 KB page size | `PT_LOAD 3 件、最小 p_align = 16384`。`.so` は **24,385,832 バイト**で、**strip が配る実物に効いている** | +| iOS / WebGL の `.a` | どちらも `!`。**束ねは CI が検証済み**(`iOS arm64 (cross-build)` が 71 個の `cv::` シンボルの解決を確認し、束ねていない archive では 71 個とも未解決になる負の対照つき) | +| **step 7(実際に導入)** | **`UPM tarball install: 59 passed`** / `resolved from file:../../upm/com.ayutaz.opencv-unity-native.tgz` / `native plugins present: 6 [` / exit 0 | +| Latest バッジ | 公開直後に `releases/latest` が `v0.4.0` を返した ——**`--draft=false` は `make_latest` を送る**(それまで未検証だった) | + +#### この配布で新しく分かったこと + +**1. tag を打ち直すより、本文だけ差し替えるほうが強い場合がある。** + +step 6 の途中で、本文が「全部入りは 124,102,343 → 77,528,652 バイト」と書いた直後に +「v0.3.0 の実物は 69,565,901 バイト」と並べているのを見つけた。**前者は strip の効果を +別ビルドで再現した値、後者は実際に配った asset の値**で、**種類の違う数字を同じ比較の +中で混ぜていた。** 実物は 77,530,189 だった。 + +直して tag を打ち直そうとしたが、**監査がそれを覆した**: + +- 在る 33 件は**配りたいものそのもの**で、**step 6・7 を既に通してある** +- 打ち直すと「この版の実物は…バイト」と「**この asset そのもの**で確かめた」が + **両方とも偽になる** +- **native binary はバイト単位で再現しない**ので、測り直し → 本文修正 → 再 tag の + **無限ループ**が起こりうる +- 代償は `blob/v0.4.0/.github/release-notes.md`(tag 側の写し)と公開本文が + 食い違うことだけで、**本文はそのファイルへリンクしていない** + +**`gh release edit v0.4.0 --notes-file .github/release-notes.md` で足りた。** +手順書の「tag を打ち直すときの順序」に、この判断の分岐を書いてある。 + +**2. 手順のコマンドに版を直書きすると、無音で前の版を検証して緑になる。** + +step 7 のコマンドは `gh release download v0.3.0 ...` のままだった。**そのまま +実行しても落ちない** —— 全部入りの asset 名には**版番号が入っていない**ので +(OpenUPM が安定した接頭辞で選ぶため)、前の版の asset も同じ名前である。前の版は +公開済みで現存し、中には全 platform が揃っているので `native plugins present: 6` まで +通って **exit 0 になる。** `dev.ps1 test-unity-tarball` は package の version を +照合しない。**完全に無音の偽合格である。** + +手順に `grep '"version"' /package/package.json` を足した —— +**「前の版を検証して合格した」と「この版を検証して合格した」を見分ける唯一の手段**である。 + +**3. リリースノートの検証が、この作業で最も価値があった。CI は本文を 1 文字も検査しない。** + +ultracode で 10 agent の監査を回し、別セッションの調査 7 件と合わせて、 +**本文の誤りを 13 件直した。** うち利用者に直接効いたもの: + +- **PNG の ARM 加速喪失が 1 文字も書かれていなかった**(`-DPNG_ARM_NEON=off` は + M7c で arm64 3 platform に入り v0.3.0 には無い)。**`README` 自身が「`dnn` を + 使うかどうかに関わらず `CvCodecs` を使う利用者全員に影響する」と書いていた**のに、 + 本文の PNG の話は「Web にだけ在る制限」だけで、**読者を「PNG の話は Web だけ」と + 積極的に誤解させる形**だった +- **存在しない API 名**(`CvGeometry.GetPerspectiveTransform`。実物は `CvOps`) +- **`CvOps` の本数が 8 と 9 で自己矛盾** +- **`checksums.txt` は展開先の root では 6 件とも失敗する**(各行が `package/` からの + 相対パス。監査が実際に走らせて確かめた) +- **OpenUPM は Release より数時間遅れ、それまで `openupm add` は 1 つ前の版を入れる** + (エラーにならない。**この版は差が大きいので「本文に書いてある `CvDnn` が + 見当たらない」という形で踏む**) +- **Scripting Define Symbols は build target ごと**(エディタの platform にだけ + 足すと Android のビルドで消える) + +**4. `state=3` を「失敗」と読まない、の 2 例目。** + +公開直後に OpenUPM の pipeline を見ると `state=3` / `reason=904`(asset が無い) +だったが、**最後の probe は 2026-09-12T15:50:02Z、公開は 17:04:16Z** で、 +**74 分前の記録**だった。v0.3.0 のときと同じ形である。 + +#### 完了条件 + +- [x] **tag から `release.yml` が 6 platform 分と全部入りを作り、draft で止まる** +- [x] **draft の asset を実物で検証する**(上の表) +- [x] **配る tarball を、実際に Unity へ導入して確かめる**(step 7。 + **draft の asset そのものを落として材料にした** —— `test-unity-tarball` は + 必ず固め直すので、確かめられたのは「同じ配線が作った同じ中身の tarball が + 導入できる」ところまでである) +- [x] **リリースノートに、この版で増えたものと、確かめていないことが書いてある** +- [x] **PNG の退行を利用者向けに明記する**(arm64 3 platform。**`README` にしか + 書かれておらず、リリースノートから落ちていた**) +- [x] **公開する**(2026-09-12T17:04:16Z。Latest バッジも移った) +- [x] **OpenUPM が `0.4.0` を配信する。2026-09-12T17:17:31Z に確認した:** + `dist-tags.latest = 0.4.0`、pipeline は `state=2`(公開済み)/ `reason=0` / + `commit=6713e51`。**公開(17:04:16Z)から 13 分である。** + + **v0.3.0 のときは約 4 時間かかったので、待ち時間は版によって大きく違う。** + **「前の版が 4 時間だったから今回も」と見積もらないこと。** + + **懸念が 1 つあり、実測で解けた。** v0.3.0 は**打ち直して commit が変わった** + ことで拾い直された経路だったが、今回は本文だけ差し替えたので + **`commit` は `6713e51` のまま**だった。**commit が変わらないまま拾い直すかは + 確かめるまで分からなかったが、拾い直した** —— OpenUPM の probe は + commit ではなく **asset の有無**を見ている(`reason=904` は「asset が無い」で、 + 公開した瞬間にそれが解消した)。 + + **経過も残しておく。** 公開の 11 分後(17:15:05Z)に `state=3 → 1`(ビルド待ち)、 + その 2 分後(17:17:31Z)に `state=2`。**`state=3` を見た時点で諦めなくてよい** + ——下の「`state=3` を『失敗』と読まない」を参照。 +- [x] 公開後に「最新の公開版」の記述を更新する(**やること 10 の一覧に + `docs/m4-device-verification.md` を足して 10 ファイルにした**) + +#### 非ゴール + +- **実機検証**(2026-09-01 に「やらない」と決めた。この配布でも覆していない —— + **`dnn` は実機で 1 度も動かさないまま配った**) +- **M4 の残り 3 件を閉じること** +- **Player 側の GPU 経路**(game-ci が `-nographics` を action の中で固定している) + ### OpenUPM への登録(条件 4 (c)) **openupm/openupm PR #6843 として提出し、自動マージされた**(2026-08-30。`Data validation` @@ -1550,7 +1672,7 @@ Android arm64-v8a と iOS arm64 で実機 smoke test が通る。 - **実機は事実上すべて arm64-v8a である。** x86_64 が要るのはエミュレータでの 開発中だけで、配る成果物の対象ではない - **含めると全部入りが大きくなる。** OpenCV を静的リンクした `.so` が 1 つ増える - ぶん、OpenUPM の 512 MB 上限に対する余裕が減る(**3 platform 時点の実測で 9.6 MB。その後 platform が増えたが測り直していない**。**モバイルを + ぶん、OpenUPM の 512 MB 上限に対する余裕が減る(**3 platform 時点の実測は 9.6 MB だった。その後 6 platform になってから測り直してあり、いまの値は「配布 その 6」の検証表が持つ**。**モバイルを 足した後の実測は下の表に入れる**) - **エミュレータでの開発を止めるわけではない。** 利用者が自分でビルドする経路は 残る —— `tools/opencv-config.psd1` の `Toolchains` に `android-x64` を足し、 @@ -1979,8 +2101,7 @@ Emscripten は既定で C++ 例外を無効にするので、`throw` は残る **次にやることは配ることである**(「配布 その 5」)。 → **2026-09-04 に v0.3.0 として配った**(「配布 その 5」)。M4 / M5 / M6 の成果は -これで届き、この懸念は解消した。**同じ形は M7 で戻ってきている** —— **M7 の成果 -(`dnn` を含む)はまだどの公開版にも入っていない。** +これで届き、この懸念は解消した。**同じ形が M7 で戻ってきていたが、2026-09-12 に v0.4.0 として配って解消した**(「配布 その 6」)—— M7 の成果(`dnn` を含む)と 2026-09 の API 拡張は、これで利用者に届いた。 --- @@ -2198,7 +2319,7 @@ M3.5 節を参照)、`ocvu_imencode` / `ocvu_imdecode` を出した。ここ - **大きさ(ライセンスより先に効く)。** **実測(2026-08-30、PyPI の `nvidia-cudnn-cu12` 9.25.1.1): 1 platform あたり 698〜772 MB**(win_amd64 698.4 / manylinux x86_64 716.4 / aarch64 772.1)。`tools/pack-upm-tarball.ps1` の上限は - **512 MB** で、全部入りは **69,565,901 バイト(66 MB。v0.3.0 の実物の release asset、 + **512 MB** で、全部入りは **約 74 MB(v0.4.0 の実物の release asset、6 platform。**正確なバイト数は「配布 その 6」の検証表が持つ** —— ビルドごとに数十バイト動くので、ここには丸めた値だけを置く。v0.3.0 の同じ asset は 69,565,901 バイト = 66 MB だった)**である。**1 platform 分だけで既に上限を超える** —— 6 platform、2026-09-06 に実測し直した ——「3 platform 時点の実測で 9.6 MB」は platform が増えて古くなっていた数字だった)**である。**1 platform 分だけで既に上限を超える** —— ライセンスが解決しても、いまの形では配れない。同梱するのか、利用者側での導入を @@ -2940,15 +3061,20 @@ M0 ハーネス ──> M1 OpenCV ビルド ──> M2 Windows slice ──> M3 v M7 profiles (5 件すべて達成。判定は M7a / M7b / CUDA / M7c の 4 節に分かれ、 - 索引は「M7 の判定」。M7 が最後のマイルストーンで、後続は無い。 - 成果はまだどの公開版にも入っていない) + 索引は「M7 の判定」。M7 が最後のマイルストーンで、後続は無い) + | + v + 配布 v0.4.0 + (2026-09 の API 拡張と M7 の成果を届けた。2026-09-12 に公開。 + 「配布 その 6」を参照) ``` **配布はマイルストーンではないが、マイルストーンの間に必ず挟まる。** M3 が v0.1.0 / v0.1.1、M3.5 が v0.2.0、そして **M4 / M5 / M6 の成果をまとめた v0.3.0 を 2026-09-04 に公開した**(「配布 その 5」を参照。**その前に作った下書きは M5 が main に入る前のもので、破棄して打ち直した** ——「配布 その 4」)。 -**この段が計画のどこにも書かれていなかったので、上の図と「配布 その 5」の節に足した。** +**その後、2026-09 の API 拡張と M7 の成果をまとめた v0.4.0 を 2026-09-12 に公開した**(「配布 その 6」を参照。**draft を作った後にリリースノートの数字を 1 件直したので、tag を打ち直してから公開している**)。 +**この段が計画のどこにも書かれていなかったので、上の図と「配布 その 5」「配布 その 6」の節に足した。** **API 拡張(A〜F)も同じ位置づけである** —— マイルストーンではないが、 M6 と M7 の間に挟まる。**26 本を 4 つの計画に分けて出す**もので、 diff --git a/docs/unity-opencv-integration-research-and-plan.md b/docs/unity-opencv-integration-research-and-plan.md index f701a1c..015e0fc 100644 --- a/docs/unity-opencv-integration-research-and-plan.md +++ b/docs/unity-opencv-integration-research-and-plan.md @@ -172,7 +172,7 @@ Unity 6 の managed plug-in サポート表では、.NET Standard と .NET Frame 2026-08-29 時点の対応範囲。**機能の総数で競わない**方針(§7)は変えないが、 **何が無いかを数えずに「競わない」と言うのは、単に知らないのと区別がつかない。** -| 種別 | OpenCV for Unity | 本案(**この表は M3.5 時点の記録である**。その後 v0.3.0(2026-09-04)まで公開し、M4 / M5 / M6 の成果は届いている。**最新の公開版は `docs/roadmap.md` の「配布」の節が正本**) | +| 種別 | OpenCV for Unity | 本案(**この表は M3.5 時点の記録である**。その後 v0.4.0(2026-09-12)まで公開し、M4 以降 M7 までの成果はすべて届いている。**最新の公開版は `docs/roadmap.md` の「配布」の節が正本**) | | --- | --- | --- | | モジュール | **30 以上**(`dnn` / `photo` / `ml` / `video` / `videoio` / `tracking` / contrib 各種を含む) | **数も一覧もここに写さない** —— OpenCV としてビルドしている module の正本は `tools/opencv-config.psd1` の `Modules`、プラグインがリンクしている module の正本は `cmake/FindOpenCvUnityDeps.cmake` の `COMPONENTS` である(**写していた頃は実際に古くなった**: M7c が `dnn` を両方に足したのに、この行は「ビルド 6 / リンク 8」のままだった)。C ABI に出ているのはさらにその一部で、**本数を数える正本は [API 対応表](./api-map.md) の冒頭**である | | platform | Windows / macOS / Linux / Android / iOS / WebGL / UWP / ChromeOS / visionOS beta | **この行は M3.5 時点の記録**(Windows / macOS / Linux)。**その後 M4 で Android / iOS、M6 で Web が加わった** —— 現況は [ロードマップ](./roadmap.md) が持つ | @@ -216,8 +216,7 @@ platform ごとの tarball のうち 1 つを選んで公開すれば、`openupm 落ちるところを見られるようにするためである** —— 既定値のままでは現状の配布物が上限まで 大きく余裕があり、この検査が働くところを誰も確かめられない。**検査は packer に置いた** (呼ぶ側が `release.yml` と `dev.ps1 test-unity-tarball` の 2 つあり、片方に置くと -もう片方が素通しする)。**全部入りの tarball は 9.6 MB**(2026-08-30、CI 実測。内訳は下記)なので、 -**効いてくるのは DNN や contrib を含む profile を配る段階(M7)である。** +もう片方が素通しする)。**全部入りの tarball は 9.6 MB**(2026-08-30、CI 実測。内訳は下記)だった。**その段階は M7 で来た** —— `dnn` を足した v0.4.0(2026-09-12 公開)の全部入りは約 74 MB である。**ただし実際に発火したのはこの 512 MB ではなく、`release.yml` が配る package に掛ける 100 MB のほうである**(PR #72。原因は `dnn` ではなく Android の `.so` に積もっていたデバッグ情報で、strip して解消した —— 実測は [ロードマップ](./roadmap.md) の「dnn の配布の形」)。 **(2) 版番号を含まない安定した接頭辞の asset 名。** 全部入りの名前を `com.ayutaz.opencv-unity-native.tgz` にした(版番号なし)。platform ごとの tarball は