Zig: すべてのパッケージ管理機能をコンパイラからビルドシステムへ移動
(ziglang.org)- Zigは
build.zigとビルドシステムを別プロセスに分離した流れに合わせて、パッケージ管理ロジックをコンパイラ実行ファイルの外にある maker プロセスへ移動 zig build,zig fetch,zig init,zig libcが maker 側へ移り、HTTP、TLS、Git、圧縮、build.zig.zon処理コードが ソース形式で配布されるようになった- この構成ではコンパイラを再ビルドせずにパッケージ管理機能を修正でき、maker は
ReleaseSafeでコンパイルされるため、ネットワーク処理の 安全性チェック も有効になる - 元の目的は build server protocol を公開し、ZLS を妨げていた
--build-runner変更問題を解決することであり、新しいプロセスツリーでは maker が configurer の親として残るため、設定の再実行もより安定して処理できる - ユーザーへの影響は大きくないが、Zig 実行ファイルは 14.1MiB から 13.5MiB へ 4% 縮小し、
--maker-optと--zig-lib-dirはそれぞれZIG_DEBUG_MAKER、ZIG_LIB_DIR環境変数に置き換えられる
パッケージ管理ロジックの移動
- Zig はユーザーの
build.zigスクリプトとビルドシステム本体が別プロセスに分離された後、パッケージ管理ロジック もビルドシステム側に置く構成へ変更 - maker プロセスへ移されたサブコマンドは次のとおり
zig buildzig fetchzig initzig libc
コンパイラ実行ファイルから外されたコード
- 以前はコンパイラ実行ファイル内に含まれていた大きなコード領域が、現在は ソース形式 で配布される
- パッケージ取得ロジック
- HTTP クライアントとネットワーキング
- TLS と関連する暗号化
- Git プロトコル
xz,gzip,zstd,flate,zipbuild.zig.zonファイルの解析、検証、その他の処理
- これらの機能はコンパイラを再ビルドしなくてもパッチを当てられるため、ユーザーやコントリビューターがより容易に実験できる
- maker 実行ファイルは
ReleaseSafeモードでコンパイルされるため、パッケージ管理のネットワーク処理では 安全性チェック が有効になる - ネットワーキングとファイルハッシュ計算に使われる暗号化コードは、ホストで利用可能な 特殊な CPU 命令 を活用できる
プロセス構造と build server
- 当初の動機は build server protocol を公開し、ZLS を妨げていた問題を解消することだった
- 以前の構成では
zig buildがコンパイラとパッケージマネージャの両方を担い、その配下の builder がユーザーのbuild.zigロジックとビルドシステム実装を保持していた - maker/configurer 分離後の構成は次のようになっていた
zig build: コンパイラ + パッケージマネージャconfigurer: ユーザーのbuild.zigロジックmaker: ビルドシステム
- この構成では長時間動作する
zig build --watchがbuild.zigや関連ファイルの変更を検知すると configurer を再実行する必要があり、そのために maker が終了してzig buildにパッケージ管理ロジックを再度実行させる必要があった - 新しい構成では
zig buildはコンパイラだけを担当し、その配下の maker が ビルドシステムとパッケージマネージャ を担い、configurer は maker の子プロセスになる - 設定を再実行する必要がある場合でも、maker は親プロセスとして動作し続けられる
- 将来の build server では、サーバー終了後にクライアントが再接続する代わりに、クライアントへ 設定変更 を通知する構成が可能になる
目に見える変更点
- ほとんどは非互換な変更ではないが、ユーザーから見える違いはある
- Zig 実行ファイルのバイナリサイズ: LLVM なしの
ReleaseSmall基準で 14.1MiB から 13.5MiB へ減少し、4% 縮小 --maker-optフラグはZIG_DEBUG_MAKER環境変数に置き換え--zig-lib-dirフラグはZIG_LIB_DIR環境変数に置き換え
- Zig 実行ファイルのバイナリサイズ: LLVM なしの
Zig 0.17.0 前に残るブロッカー課題
- この変更群の後に残る主なブロッカー課題が、Zig 0.17.0 タグ付け前までの中核作業となる
- 7月には 2 つのカンファレンスと発表準備があるため、これらの作業を完了する時期は現実的には 8 月初旬になる見込み
- ZLS チームの Techatrix が build server protocol の作業について連絡と協業を行っており、スポンサーを募集している
1件のコメント
Hacker Newsのコメント
Zig、Go、Python の開発者はときどき燃料タンクから冷却水を抜いたと発表し、支持者たちはそれが言語にとって良く、性能も大きく向上すると歓声を上げる
でも、そもそもなぜ冷却水を燃料タンクに入れたのかのほうが気になる
パッケージ管理をコンパイラの中に入れるのは便利だったが、言語とツールが広く使われ始めると、個人に有利だった機能が導入を妨げる負債になる
多くのプロジェクトで、開発者は「ちゃんとやるなら必要な難しい作業」を避けるために楽な方法を選び、他の人たちもその難しい作業をやりたがらないので、それが慣習になってしまう
ビルドシステムの中にパッケージマネージャを実装しつつコンパイラにも残したいなら、まずコンパイラとビルドシステムの間にどんな抽象化を置くかを決める必要がある
これは import システムや言語の根本的な部分にも影響し、こうした部分はきちんと設計すべきで、後から変えるのも難しい
最初はパッケージ管理とコンパイラを強く結合して、望むプログラマ体験から逆算して設計し、その後で実装を変えるほうが、ユーザーへの影響は小さいかもしれない
特に Python の import システムは、パッケージ管理がさまざまな方式で行われることを受け入れた結果、非常に複雑で欠点の多いものになったと思う
一方 Go は、最初からパッケージ管理を念頭に置いて設計されたので、import 関連の構文が比較的小さくすっきりしている。もちろん、すべての設計判断に同意しているわけではない
小さな製品でさえ、各構成要素がどう相互作用するかを予測するのは難しく、継続的に修正が必要になる
ここでセルフホストな C 代替言語を作ると考えてみればいい
速度向上が大きいほど歓声が上がるが、ほとんどの最適化は巧妙な手法ではなく、プロファイラで「おっと、冷却水が燃料タンクに入っていてはいけない」と見つける作業だ
ほとんどの性能ボトルネックは、ハードウェアや問題そのものの本質的な限界ではない
結果を得るのに必要な最小限の作業量はあるが、アプリケーションが遅い理由はほとんど常に、その上に積み上げたがらくたのせいだ
Zig の開発は本当に健全な雰囲気に感じられる
LLM を毎日使っていて、さまざまな問題タイプで驚くほどよく働くのは認めるが、LLM が作ったプログラミング言語は欲しくない
プログラミング言語では、すべてのコード行、判断、トレードオフが重要だ
雰囲気だけで設計しコーディングされた言語は災厄になる
それに反する確信を持てるコードを、どのモデルも示したことがない。Fable ですら以前の最高モデルより明らかに良くなったが、それでも同じだ
モデルには欲望がなく、意味のある見解もなく、言語における快適さと不快さが何かも分からない。十分に複雑な GUI や CLI インターフェースでも同じだ
Zig のような言語は、単に Zig をコピーしない限り LLM からは出てこないし、コピーしたとしても、より劣った複製になるだろう
ここで LLM でコピーするというのは、ソースツリーを文字どおり
cpすることではなく、LLM が仕様を書き、別の LLM がその仕様どおりに言語を実装するようなことを指しているブートローダを作って UEFI 作業をしてみたが、個人的には C でやるよりずっと簡単だった
ただし、新しくてきらきらしたものを学ぶ楽しさがあるので、その分かなりバイアスがかかっている
この変更が、Zig で
@cImportを削除してビルドシステムに移すことになったあの変更なのか気になる純粋にユーザー体験の問題であり、ビルドシステムとコンパイラを分離する変更がメンテナにとって重要なのは分かるが、それでも開発の安定性がユーザー体験より先に来るのは少し残念だ
正しい判断ではあるが悲しく、
@cImportはこの言語の強力なキラー機能だったと思うこの変更はサードパーティパッケージをダウンロードして展開するコードに関するものだ
@cImportの変更は、Zig のLLVM/libclang 依存を将来的にオプションにし、後にはサードパーティパッケージとして切り出せるようにするための作業の一部だったが、直接関係しているようには見えない長期目標がビルドシステムをWebAssembly VM の中に移すことだとどこかで読んだ
だとしたらすごいことだ
Zig にとって良い変化だ
Go から Zig に移りたい気持ちはかなりあるが、とりあえず横で見ているのも楽しんでいる
言語が独自のパッケージシステムを作るたびに、何か大きな機会を逃した気しかしない
唯一の例外は C/C++ で、良くも悪くも十分に定着したものがない
こうした選択は、後で複数言語を混在させて使う必要が出たときに、非常に複雑な手順を生みがちだ
パッケージングシステムは仕事を楽にする一方で、別の言語を使わなければならなくなった瞬間に、その後の工程をより複雑にする
すべての言語のための単一のビルドシステムを望んでいるのか? Bazel のようなシステムは存在し、多言語プロジェクトでもよく使われるが、現実には言語ごとの知識を持つビルドシステムのほうがはるかに扱いやすいことが証明されているように見える
依存関係を追加する前によく考えるようになるからだ
こうした依存関係には、セキュリティ脆弱性のような隠れたコストがあることが多い
重要なシステムのかなりの部分が C++ で書かれている以上、容易に手に入るサードパーティパッケージ数十個に、各パッケージをきちんと監査せず依存するのは危険が大きすぎる
Zig がその空白を埋めている
事実上そうしたビルドシステムは Buck と Bazel しかないが、どちらも背後の巨大組織由来の重荷が多すぎる
残念なことだ
関心の分離がとても納得しやすい形で行われた