
2026/07/05 1:30
Zig:パッケージ管理機能すべてをコンパイラからビルドシステムへ移行
RSS: https://news.ycombinator.com/rss
要約▶
日本語訳:
2025 年末から 2026 年中盤にかけて、Zig はパッケージ管理をコンパイラのコアから非同期化する大規模なアーキテクチャ進化を遂げ、ビルド効率を大幅に向上させシステムオーバーヘッドを削減します。主なマイルストーンには、
zig libc を共有コンパイルユニット(ZCU)へと移行し、Windows 向けにネイティブ I/O ハンドリングを実装して kernel32.dll への依存関係を削減することが含まれます。プロセス分離によりビルドツリーは別々の役割「maker(ビルドシステム/パッケージマネージャ)」と「configurer(ユーザーロジック)」に分割され、長時間稼働しているプロセスを再起動することなく設定の再実行が可能になります。
パフォーマンスベンチマークでは、ビルド操作の起動時間が 90.4% 削減され、実行可能バイナリのサイズは 14.1 MiB から 13.5 MiB に縮小しました(4% の減少)。具体的の変更点には、外部ライブラリとの増分再構築を有効にする ELF リンカーの実装、新しい
@SpirvType ビルテン関数やマルチスレッドのコード生成パスの復元といった SPIR-V バックエンドの改良、パッケージフェッチロジックにおける CPU 固有の暗号化指令へのサポート強化が含まれます。
現在、0.17.0 リリースタグ向けのリリースを妨げる主な課題は、ZLS に必要なビルドサーバープロトコル MVP の最終確定とパス依存関係バグの修正です。将来的には SPIR-V バックエンドのさらなる堅牢性の向上を目指しています。これらのアップデートにより、より高速なコンパイルサイクル、小型化されたバイナリ、増強されたマルチスレッド互換性、ならびにハイパフォーマンスコンピューティングタスク向けにより安定した基盤が提供されることになります。
本文
Zig メインブランチの最近の変更点 (2026 年)
本記事では、Zig メインブランチで 2026 年に公開された主要な変更点を整理します。各エントリは日付順に配置されています。
2026 年 6 月 30 日:パッケージ管理機能全体をコンパイラからビルドシステムへ移行
著者: Andrew Kelley
- 移行の内容:
- ユーザーの
スクリプトとビルドシステム自体が別のプロセスとして実装されたため、パッケージ管理ロジックの配置先が明確化されました。build.zig - 以下のコマンドはすべて**「メーカー(Maker)」プロセス**へ移動:
zig buildzig fetchzig initzig libc
- ユーザーの
- ソースコードの配布変化:
- コンパイラ実行ファイルに組み込まれていた機能が、ソース形式で配布されるようになりました。
- 含まれる機能:
- パッケージ取得ロジック
- HTTP クライアントとネットワーキング機能
- TLS(トランспорт層セキュリティ)および関連する暗号化処理
- Git プロトコル
- xz、gzip、zstd などの圧縮処理および
ファイルの処理モジュールbuild.zig.zon
- メリット:
- コンパイラを再ビルドせずにパッチ適用が可能になり、開発・実験が容易になりました。
- ネットワーキング時のセーフティチェックが有効化されました(メーカー実行ファイルは
モードでコンパイルのため)。ReleaseSafe - 暗号処理において、ホスト機器の特殊な CPU 命令を活用できるようになりつつあります。
🍰 AOT(ランタイム結合型)のケーキと JIT(ランタイムインタプリタ型)を同時に楽しむことができます!
- 動機:
- ビルドサーバープロトコルの公開により ZLS をブロックしている状態を解消するため。
- メーカー/コンフィグラープロセスの分離が
オーバーライドフラグに対応するために必要でした。--build-runner
プロセスツリーの変化
| 以前 | その後(移行後) |
|---|---|
(Zig コンパイラ + パッケージマネージャー) └─ builder (ユーザーの ロジック + ビルドシステム実装) | (Zig コンパイラ) └─ maker (ビルドシステム + パッケージマネージャー) └─ configurer (ユーザーの ロジック) |
- 設定を再実行する場合でも、メーカープロセスは親プロセスとして存在し続けます。
- upcoming(予定中)のビルドサーバーでは、クライアントへの再接続が必要となる状況を避け、構成変更の通知だけで対応できるようになります。
目に見える差分
- Zig 実行可能ファイルのサイズ: LLVM を無効にした ReleaseSmall モードにおいて、14.1 MiB から 13.5 MiB に約 4% 縮小しました。
フラグは、環境変数--maker-opt
に置き換えられました。ZIG_DEBUG_MAKER
フラグは、環境変数zig-lib-dir
に置き換えられました。ZIG_LIB_DIR
アフターアクション(Zig 0.17.0 までの課題)
- ビルドサーバープロトコル MVP の実装(ZLS ブロック解除用)。
- ビルドスクリプトのパス依存関係の導入。
のビルドスクリプト変更検知機能の実装。zig build --watch- ワーキングディレクトリ(cwd)の違いによるキャッシュミスの解消。
作者は現在、会議や資料作成に追われており、作業完了までには数週間かかる見込みです。コントリビューション歓迎です。
2026 年 6 月 26 日:SPIR-V バックエンドの進捗状況
著者: Ali Cheraghi
直近の変更以降、機能退行(bitrot)が進んでいた SPIR-V バックエンドを正常状態に復元しました。
-
@SpirvType の導入:
- Zig の型システムでは表現できなかった SPIR-V 用の新しいビルトイン関数
を追加し、長年のボトルネックを解消しました。@SpirvType
const Sampler = @SpirvType(.sampler); const Image = @SpirvType(.{ .image = .{ .usage = .{ .sampled = u32 }, .format = .unknown, .dim = .@"2d", // ... } }); - Zig の型システムでは表現できなかった SPIR-V 用の新しいビルトイン関数
-
呼び出し規約と実行モード:
- 実行モード情報は、
の発行ではなく、呼び出し規約によって運ばれるようになりました。OpExecutionMode - 旧来の
は廃止されました。std.gpu.executionMode() - メッシュシェーディングのために、新しい呼び出し規約
およびspirv_task
が追加されました。spirv_mesh
export fn vert() callconv(.spirv_vertex) void {} export fn frag() callconv(.{ .spirv_fragment = .{ .depth_assumption = .greater } }) void {} export fn mesh() callconv(.{ .spirv_mesh = .{ .stage_output = .output_lines, .max_primitives = 1 } }) void {} - 実行モード情報は、
-
CPU 機能からのキャパビリティ:
- キャパビリティと拡張機能は、CPU 機能セットによって完全に駆動されるようになりました。SPIRV-Headers から依存関係チェーンが抽出されています。
-
マルチスレッドコード生成:
- リンカースレッド内でシングルスレッドで行われていた処理が、
値を生成してコンパイラのスレッドプールでスケジューリングされる方式に変更されました。Mir - これにより以前削除されていた**「同等な型指示をマージする処理」と「デッドコードを除去する処理」**が復活しました。
- リンカースレッド内でシングルスレッドで行われていた処理が、
-
オブジェクトファイルへのリンク:
ファイルはオブジェクトファイルとして認識され、SPIR-V リンカーによる連結が可能になりました。.spv
総括
- バグ修正により動作テストの通過率は約 10% 増加しました(現在は 49%)。
はstd.gpu
に改名されました。std.spirv- 多くのバグ修正が行われたため、シェーダーや計算カーネル向けの試行を始めるのに良い時期です。バグ報告は Codeberg で歓迎します。
2026 年 6 月 25 日:新しい @bitCast の意味と LLVM バックエンドの改善
著者: Matthew Lugg
LLVM バックエンドを大幅に改善するブランチを完了しました。これには、言語提案の実装や未修正バグの修正が含まれます。
LLVM バックエンド整数降下 (Integer Lowering)
- 過去に
などの変なビット幅整数型を直接降下させていた場合、LLVM は公式定義外の挙動を示すことが知られていました。u40 - 新しい設計では、値は SSA 形式で操作され、メモリ保存時は ABI サイズの型(
,i8
,i16
)へゼロ/符号拡張されます。これにより Clang のi32
対応も改善されています。_BitInt(N)
@bitCast の再定義
- 従来の「ポインター取得→キャスト→読み込み」というメモリ再解釈アプローチは、大端系・小端系やサイズ不一致で動作が不安定でした。
- 新しい意味論:
は**論理的ビットレイアウト(logical bit layout)**に基づいて定義されるようになりました。@bitCast- 例:
を[2]u8
にキャストする際、小端系での動作が全てのプラットフォームで共通化されました。u16
- 例:
新しい @bitCast の動作の例
- 集合型(配列やベクトル)への操作が可能になりました。
const arr: [2]u3 = .{ 0b001, 0b011 }; const vec: @Vector(3, u2) = @bitCast(arr); // arr[0]=0b001, arr[1]=0b011 のビットを連結し、順に 2 ビットずつ読み取る // vec[0] = 0b01, vec[1] = 0b10, vec[2] = 0b01
にキャストすることで、整数を個別のビットベクトルとして分解・操作できます。@Vector(n, u1)
パフォーマンス向上
- LLVM バックエンドが ABI 整数型を降下させる方法の変更により、見逃されていた最適化が回復し、約 5% のパフォーマンス向上が確認できました。
2026 年 5 月 30 日:ELF リンカーの改善
著者: Matthew Lugg
Zig 0.16.0 で登場した新しい ELF リンカーをさらに進化させました。現在は LLVM と LLD ライブラリを有効にしたまま、セルフホスト型の Zig コンパイラをビルドできます。
デモ
# 新しいリンカーを使って Zig コンパイラをビルド zig build -Dno-lib -Dnew-linker -Denable-llvm # そのコンパイラを使って LLVM と LLD を有効にした何かをビルド ./zig-out/bin/zig build-exe ~/hello.zig -fllvm -flld
主要機能:高速なインクリメンタルコンパイル
- x86_64 Linux で、外部ライブラリや C ソースと一緒に外部ライブラリの再リンク処理なしで、ミリ秒単位の高速再ビルドが可能になりました。
- Zig コンパイラ自体の再ビルドでも同様の効果があります(例:3 分ほどのコンパイルを 200ms〜300ms に短縮)。
今後の課題と利用方法
- 現状の欠落: DWARF デバッグ情報の生成はまだサポートされていません(優先事項)。
- 推奨: x86_64 Linux で master ブランチを使用している方は、インクリメンタルコンパイルを試してください。
- タグリリース版: まだ 0.17.0 が安定版として出ていない場合は、ビルドが壊れても不安はありません(Andrew Kelley も「すぐに来る」と述べています)。
2026 年 5 月 26 日:ビルドシステムの再構築
著者: Andrew Kelley
build.zig ファイルとビルドシステム実装が、1 つのプロセス(ビルドランナー)から分離されました。
仕組みの変化
- 以前:
ロジック + ビルドシステムが 1 つの肥大化プロセスで動作。build.zig - 現在:
プロセス:ユーザーのconfigurer
ロジックを小規模プロセスでビルドし、メモリ上でグラフ構築後、シリアライズされた構成ファイルを出力。build.zig
プロセス: Release モードで非同期的にコンパイルされ、シリアライズされた構成ファイルを読み込んで実行。maker
メイン動機とパフォーマンス改善
- 目的:
の高速化。zig build - 効果:
- 各変更に対してのみユーザーロジックがコンパイルされ、ビルドシステム全体はキャッシュされるため、
,--watch
,--fuzz
で価値が増幅。--webui - 構成ファイルが同じ場合、
ロジックの再実行を完全にスキップできる。build.zig - ビルドグラフを実行するプロセスは最適化有効でコンパイルされる。
- 各変更に対してのみユーザーロジックがコンパイルされ、ビルドシステム全体はキャッシュされるため、
ベンチマーク結果(比較:master ブランチ vs 新しいブランチ)
| メトリック | 以前 (Master) | 今 (Branch) | 改善率 |
|---|---|---|---|
| Wall Time (平均) | 150ms | 14.3ms | ⚡ -90.4% |
| Peak RSS | 84.8MB | 78.5MB | -7.4% |
| CPU Cycles | 593M | 24.1M | ⚡ -95.9% |
- API の影響: ほとんどの API は破損しないですが、ビルドスクリプト内の
を観測する能力は失われます。代わりにb.args
を使用します。run_cmd.addPassthruArgs() - ZLS やサードパーティツールもシリアライズ構成ファイルを消費するため恩恵を受けます。
2026 年 4 月 8 日:LLVM を使用したインクリメンタルコンパイル
著者: Matthew Lugg
LLVM コード生成バックエンドでのインクリメンタルコンパイルが実装されました。
- 特徴:
- 「LLVM Emit Object」の加速は LLVM 側に依存するため限界がありますが、Zig コンパイラ自体の実行時間を最小化できます。
- コードにコンパイルエラーがある場合、「Emit Object」をスキップして通常よりも速くエラーを検出します。
- 利用方法:
zig build -fincremental --watch - 現状: master ブランチおよび近い将来の 0.16.0 リリースで利用可能。CI テストカバレッジも LLVM バックエンドに対応済みです。
2026 年 3 月 10 日:型解決の再設計と少しの言語変更
著者: Matthew Lugg
約 2 ヶ月の開発により、内部型解決ロジックを大幅に改善しました(PR: 30,000 行)。
ラズィー分析 (Lazy Analysis)
- 特徴: 型が決して初期化されない場合、その型の詳細な構造を解析する必要がありません。
- 例:
を使用する場合でも、コンパイラにstd.Io.Writer
の全コードを読み込ませる必要がなくなります。std.Io
const Foo = struct { bad_field: @compileError("i am an evil field"), // これを触らない限り OK const something = 123; }; comptime { _ = Foo.something; // コンパイル成功:@compileError は評価されない }
依存ループエラーの改善
- 依存ループが発生した際、どこから来たのかを正確に示す詳細なエラーメッセージが表示されるようになりました。
const Foo = struct { inner: Bar }; const Bar = struct { x: u32 align(@alignOf(Foo)) }; // エラー:循環参照 comptime { _ = @as(Foo, undefined); }
- 出力例:
note: type 'repro.Foo' depends on type 'repro.Bar' for field declared herenote: eliminate any one of these dependencies to break the loop
インクリメンタルコンパイル
- 過剰分析(over-analysis)による無駄な処理が大幅に減少し、インクリメンタル更新が高速化しました。
2026 年 2 月 13 日:io_uring と Grand Central Dispatch (std.Io) マージ
著者: Andrew Kelley
std.Io.Evented を高速化するための実装がマージされました。これらはユーザー空間でのスタックスイッチング(ファイバー・グリーンスレッド)に基づいています。
- 現状: 実験的機能として公開中。
- 今後の課題:
- より良いエラーハンドリング
- ログの削除
- パフォーマンス劣化の原因診断
- 欠落している機能の実装とテストカバールの向上
- 追加機能: 関数の最大スタックサイズを報告するビルトイン関数の実装。
const std = @import("std"); pub fn main(init: std.process.Init.Minimal) !void { var evented: std.Io.Evented = undefined; try evented.init(...) defer evented.deinit(); return app(evented.io()); }
2026 年 2 月 6 日:パッケージ管理ワークフローの強化
著者: Andrew Kelley
依存関係を持つプロジェクトにおいて、以下の 3 つの大きな変更がマージされました。
1. ローカルパッケージストレージ (zig-pkg
)
zig-pkg- 取得されたパッケージはプロジェクトルートに
ディレクトリに保存されます。zig-pkg - Git に追加しなくても良いため、
への登録をお勧めします。.gitignore
というグローバルキャッシュとの併用により、オフラインビルドやアーカイブ用途での利用が可能になります。~/.cache/zig/p/
2. グローバルキャッシュと圧縮
- 未使用ファイルのフィルタリングおよび再圧縮 (
) が行われます。tar.gz - 利点:
- コンピューター間でのキャッシュデータ共有が容易になります。
- 将来的にはピアツーピーア (P2P) の Torrent を経由したパッケージ共有をサポートする予定です。
3. --fork
フラグの追加
--fork- プロジェクト固有のパッケージソースを指定し、依存関係ツリー全体でそのプロジェクトを使用できるコマンドラインフラグです。
zig build --fork=[path] - 用途:
- 依存関係のエコシステム破損(バグ修正や新しい機能の実験)時に、一時的に自分のフォークを使用してビルドを復元できます。
を変更せずに、フォークされたコードを試せます。build.zig.zon- クリフハンガーとして動作するため、フラグを外すと元のプリストイートな依存関係ツリーに戻ります。
2026 年 2 月 3 日:Fun and Nonprofit (Windows ネイティブ API)
著者: Andrew Kelley
Windows 開発における「Win32 ラッパー API」と「ネイティブ API」の使い分けを明確化しました。Zig は「ネイティブ API(NTDll など)を優先する」方針です。
なぜネイティブ API か?
- Kernel32.dll の欠陥:
ラッパーは、不要なヘッパ配列割り当て、追加の失敗モード、意図しない CPU 使用量などを引き起こします。kernel32 - 例 1:ランダム数生成 (Entropy)
- 公式ドキュメントでは Windows が明確な RNG を持っていないとされていますが、実際には
やbcryptprimitives.dll
を介して動作しています。advapi32.dll - ネイティブ API(
など)を使用することで、DLL ロード失敗によるレイテンシやエラーを回避できます。NtQuerySystemInformation
- 公式ドキュメントでは Windows が明確な RNG を持っていないとされていますが、実際には
例 2:ファイル I/O (NtReadFile
vs ReadFile
)
NtReadFileReadFile- Kernel32 (
): 状態コードを隠蔽し、ReadFile
呼び出しが必要です。オーバーラップ処理では不要なリソース割り当てが発生します。GetLastError() - NTDLL (
): エラーコードが直接返ります。APC ルーティンを渡すことで、同期/非同期に関係なくタスクキャンセルが可能になります。NtReadFile
結論: Windows 開発は「ネイティブ API を優先」すべきです。
2026 年 1 月 31 日:zig libc
著者: Andrew Kelley
C ライブラリ関数を Zig スタンダードライブラリーラッパーとして段階的に提供し、冗長な C コードを削減するプロジェクトです。
- 現状: 約 250 の C ソースファイルを削除(2032 件残存)。
- メリット:
- サードパーティの C プロジェクトへの依存関係削減。
- コンパイル速度向上。
- インストールサイズと静的リンクリンク時のバイナリサイズ削減。
- 共有コンパイル単位 (ZCU) 化: Zig コンパイラ単一最適化のため、冗長なコードが排除され、LTO の境界を超えた最適化が可能になります。
- 将来の展開:
の変更と組み合わせることで、ユーザーが I/O 実装(io_uring など)をシームレスに切り替えることが可能になる見込みです。std.Io
投稿者の注意事項
Zig が静的な libc プロバイダーへと移行している今、もし Zig によって提供される musl や wasi-libc の機能で問題が発生したら、まず Zig にバグレポートを開いてください。独立した libc 実装の maintainer を不快にさせるのは避けたいです。
(注:記事末尾にあった「催涙ガス」に関する記述は、元の文章での無関係な付録と見做されます。)