prebuiltがないときのsource build fallbackは同じ意味ではない
prebuilt package managerを比較するとき、「binaryがなければsourceからbuildできる」という機能だけを見ると似て見える。しかしfallbackがpackage modelのどこに位置するかで意味は異なる。
ビルド済みパッケージ配布を一括りにしない の分類では、Nix/Guix、Homebrew/Spack、aquaでsource buildへの戻り方が違う。
Nix/Guix: substituteがなければ本来のbuildを行う
Nixのsubstituteは「バイナリパッケージ」よりbuild resultに近い のNix/Guix系では、prebuilt objectはもともとbuild resultのsubstituteである。したがってcache missは「binary packageが存在しない例外」というより、本来のderivation buildを実行する通常経路へ戻ることに近い。
このモデルではpackage definitionが一次的で、binary cacheはその結果を省略するoptimization layerである。
Homebrew: Bottleが使えなければformulaをbuildする
Homebrewではformulaがrecipeであり、Bottleはそのformulaを事前buildしたbinary packageである。Bottleがsystemに適合しない、checksumが合わない、Cellar条件を満たさない、userが--build-from-sourceを指定した、といった場合はBottleを使わない。
Nixと似てrecipeが存在するが、formulaのbuild環境やHomebrew prefix等のpackage-manager固有条件が強く、Bottleの利用可否判定はビルド済みバイナリのrelocationには複数の解法があるとも結び付いている。
Spack: concretized specごとにcache使用を選べる
Spack Build Cacheでは、prebuilt specをmirrorから利用しつつ、見つからなければsource buildできる。さらに--use-buildcache等でpackage/dependenciesごとにauto、only、neverを選べる。
これはHPCのように、あるdependencyはvendor/compiler条件に合わせてlocal buildし、他はcacheから取るといった混在を可能にする。
aqua: upstream binary方式に限定的なbuild backendを重ねる
aquaは中心的にはaquaはupstream releaseを正規化するパッケージマネージャーと捉えられるであり、GitHub Releases等のupstream artifactを取る。しかしbuild設定により、prebuilt binaryがpublishされていないplatformだけgo_buildまたはgo_installへfallbackできる。
ここでは「同じrecipeをcacheで省略する」のではなく、primary distribution methodはupstream releaseだが、一部platformにalternative installerを定義する形である。
この違いはreproducibilityにも影響する。Nix/Spack型ではcache artifactとsource build resultの対応関係がpackage modelの中心にある。一方、upstream releaseとlocal go buildをfallbackとして併用する場合、upstream releaseがどのflags/toolchainでbuildされたかとlocal buildが同じとは限らない。
そのため「fallback可能」を評価するときは、次を確認する必要がある。
- prebuiltとsource buildは同じbuild definitionを共有するか
- output equivalenceを期待しているか
- source fallback用toolchain自体を誰が用意するか
- offline / hermeticにbuildできるか
- fallbackでsecurity verification modelが変わらないか
特にprebuilt artifactにはsignature/provenanceがあるがsource fallbackにはない、あるいは逆にlocal buildはsourceを検証するがupstream binaryは別trust chain、といった非対称性があり得る。これは checksum・signature・provenanceは別の保証をする と binary cacheの公開鍵を追加することはbuilderを信頼することに近い に繋がる。
source fallbackはavailability向上には有効だが、「binaryがなくても動く」というUXだけで同じ設計とみなさない方がよい。