世界を動かす技術を、日本語で。

デバッグモードでのデフォルトは自己ホスト型x86バックエンドになりました

概要

  • Zigのmainブランチにおける2025年の主な変更点まとめ
  • 自己ホストx86バックエンドのデフォルト化やクロスコンパイル対応強化
  • ビルドシステム解説動画やウェブサイトのZineアップデート
  • UBSanエラーメッセージの改善やメモリアロケータの最適化
  • 主要な開発進捗、今後の展望、寄付の呼びかけ

2025年 Zig Devlog 主な更新

2025年6月8日: 自己ホストx86バックエンドがDebugモードでデフォルト化

  • x86_64ターゲット時、 Zig独自のx86バックエンド をデフォルト利用
  • WindowsではCOFFリンカ作業が残るため未適用
  • 1987個の動作テスト に合格し、LLVMバックエンド(1980個)より堅牢性向上
  • LLVMと比較し コンパイル速度が大幅向上
    • hello.zigのビルド時間: 918ms(LLVM) → 275ms(Zig x86)
    • Zigコンパイラ自体のビルド時間: 75秒 → 20秒
  • コード生成の完全並列化やインクリメンタルビルドの安定化も進行中
  • aarch64バックエンドへの展開も準備中
  • 最新masterビルドで体験可能、 Zig Software Foundation への寄付呼びかけ

2025年6月6日: Zigビルドシステム入門動画公開

  • Loris Croによる YouTube解説動画 公開
  • Zigビルドシステムの基本操作やモジュール作成・インポート方法を解説
  • 今後もシリーズとして動画追加予定
    • 動画リンク: https://youtu.be/jy7w_7JZYyw

2025年5月20日: FreeBSD・NetBSDクロスコンパイル対応

  • PR #23835, #23913により FreeBSD 14.0.0+、NetBSD 10.1+ 向けバイナリ生成が可能に
  • 任意のマシンからzig cc/zig buildでクロスコンパイル実現
  • libc等のシンボル情報を abilistsファイル に集約し、クロスリンク時に利用
  • crt0コードは最新リリースからインポートしパッチ適用
  • FreeBSD/NetBSDの システム・libcヘッダ も同梱
  • OpenBSD/Dragonfly BSD/SerenityOS/Android/Fuchsia libc対応も検討中
  • バグ報告・協力者募集

2025年4月9日: ウェブサイトがZine 0.10.0にアップデート

  • 公式Zigサイトが スタンドアロンZine でビルドされるように変更
  • ZineがZigビルドスクリプトから実行ファイルへ進化
  • zine initで サンプルサイトやdevlog機能 を即時体験可能
  • サイト各エントリーに 日付表示 を追加
  • 不具合報告はリグレッションのみ受付

2025年3月3日: 0.14.0リリースタグ進捗

  • 0.14.0リリース 間近
  • リリースノート作成中、CI開始予定
  • 0.14.1や0.15.0での追加改善も計画中

2025年2月24日: UBSanエラーメッセージ改善

  • David Rubinによる UBSanランタイム統合
  • zig ccでCをコンパイル時、 -fsanitize=undefined がデフォルト有効
  • 以前はSIGILL(不正命令)のみで原因特定困難
  • 新ランタイムで 詳細なエラー内容と発生箇所 が出力されデバッグ容易化
  • C++のvptr/ライフタイム検出やassume_aligned等の属性位置表示は未対応(今後の課題)

2025年2月7日: No-Libc ZigがGlibc Zigを上回る性能に

  • Andrew Kelleyによる デバッグアロケータの最適化
  • ページサイズの ランタイム検出 対応でAsahi Linux動作も実現
  • メモリ初期化・解放・データ構造の効率化
  • スロット数計算を コンパイル時に事前計算 し、実行時の高速化を実現

今後の展望・協力のお願い

  • 自己ホストバックエンドの品質向上 と他アーキテクチャへの展開
  • BSD系や新OSへのクロスコンパイル対応拡大
  • コミュニティからのバグ報告・パッチ貢献・寄付 を広く募集

Hackerたちの意見

そういえば、helloworldプログラム(zig init)はコンパイルすると9.3MBになるんだよね。-Doptimize=ReleaseSmallの7.6KBと比べると、めっちゃ大きい(1000倍以上だね)。

確かに、いい観察だね。もう一つの観察としては、その82%がデバッグ情報だってこと。-OReleaseSmall -fno-stripだと580Kの実行ファイルができるけど、-ODebug -fstripだと1.4Mの実行ファイルになる。zigのx86バックエンドは、このzig対応のlldbフォークを使うとデバッグ体験がかなり良くなるよね:https://github.com/ziglang/zig/wiki/LLDB-for-Zig 今のところコンパイル時のロジックをステップ実行できるかは覚えてないけど、最近その話をしたばかりだよ。

僕の知る限り、Zigはより良い開発体験のためにいろいろなことを進めてるよ。ほぼ毎日何かが進行中で、例えば今だとhttps://github.com/ziglang/zig/pull/24124みたいな感じ。Zigは過去にホットコードスワッピングにも取り組む予定があったんだ。こんなペースで開発が進んでいけば、x86_64でホットコードスワッピングが機能するのも1年以内かもしれないね。今のところ、Zigで一番辛いのはcomptimeの速度かな。コンパイラがここでやるべきことがたくさんあって、コンパイル時にbrainF DSLを実行するのはかなり遅い(経験から言うと、すごく面白い実験だったけどね)。このコンパイラの部分に改善があるといいな。全体的には、Zigが新しいバックエンドを導入するのがすごく楽しみだよ。自分のURCL(https://github.com/ModPunchtree/URCL)バックエンドをZig用に作るのが待ちきれない! ;)

ホットコードスワッピングはゲーム開発にとって大きな進展だよ。Zigが基本的にコンパイラフラグでそれをサポートするっていうのはすごい。clangもそれやってみてよ。

comptimeのパフォーマンス改善については、何をするべきか分かってるよ。ずいぶん前にブランチを作り始めたんだけど、残念ながらセマンティック分析のコードをたくさん再構築する必要があるんだ。これは絶対にやらなきゃいけないし、やるべきことなんだけど、他の優先事項と競合してるんだよね。

comptimeの遅さって本当に問題なの?今、JSON-RPCライブラリを作ってて、JSONリクエストを任意の関数にディスパッチするためにcomptimeをめっちゃ使ってるんだ。厳格な静的型付けのせいで、実行時に任意のパラメータを持つ関数に動的にディスパッチする方法がないんだよね。見つけた唯一の方法は、コンパイル時にcomptimeを使って関数の型マッピングを考えることだった。これ、任意の関数ごとにcomptimeされたコードのコピーが増えて、コードサイズが膨れ上がるのは確実だわ。

カスタムバックエンドを作るのは簡単なの?まだ見てないけど、ちょっと実験してみたいんだ。具体的には、AIRを使ってメモリ安全レポートを生成するバックエンドを作れると思うんだ。(未定義の値を使ってるか、スタックポインタが逃げてるか、解放後に使ってるか、ダブルフリー、エイリアスxorミュートを特定できるようにね)

URCLが俺を迷宮に引き込んでる。まだ深くは見てないけど、最も面白いシナリオは、Minecraftのために作られたIRが言語の有効なコンパイルターゲットになることだな。

これだけでもすごい成果だけど、デブログにもあるように、まだまだこれからが楽しみだね! コンパイラがコンパイル中に必要な部分だけをバイナリに変更するってアイデアは、すごく新鮮で、同時にめちゃくちゃ面白い。でも、今やZigプロジェクトの手の届くところにあるんだ。ワクワクする時代が来るね。

Zigコンパイラのような大きなプロジェクトでは、75秒から20秒に短縮されるんだ。まだ始まったばかりだよ。彼がこれで何をするのか楽しみだね。彼は本当に頭の良い人みたいだ。パッケージ管理はどうなってるの? QuickJS + SDL3でアプリを動かそうとしたけど、C++のごちゃごちゃに押し戻されて、結局Rustに行っちゃった。Rustでは全部うまくいくからね。Zigでも試してみたいな。

Zigのパッケージ管理はRustよりも手動で、CLIを使ってパッケージのURLを取得してから、ビルドスクリプトでモジュールをインポートする必要があるんだ。これには利点もあって、任意のアーカイブに依存できるから、たくさんのZigパッケージがCライブラリのビルドスクリプトと未修正のtarballリリースに依存してるよ。でも、初心者にはちょっと難しいかもね。SDL3にはネイティブのZigラッパーがあるよ:https://github.com/Gota7/zig-sdl3 それとCライブラリ/APIのもっと基本的な再パッケージも:https://github.com/castholm/SDL QuickJSについては、唯一の選択肢はC APIだね:https://github.com/allyourcodebase/quickjs-ng ZigはCパッケージを直接使うのがすごく簡単だけど、Zigの型はかなり厳密だから、APIとやり取りする時にはたくさんキャストしなきゃいけないよ。

Zigが自分自身を75秒でコンパイルできるなんて、マジで驚きだわ(llvm使っても)。

dmd Dコンパイラは自分自身をコンパイルできる(デバッグビルド):実行時間 0m18.444s ユーザー 0m17.408s システム 0m1.688s 古いプロセッサで(速すぎて全然アップグレードしてない):cat /proc/cpuinfo プロセッサ : 0 ベンダーID : AuthenticAMD CPUファミリー : 15 モデル : 107 モデル名 : AMD Athlon(tm) 64 X2 Dual Core Processor 4400+ ステッピング : 2 CPU MHz : 2299.674 キャッシュサイズ : 512 KB 物理ID : 0 シスブレッド : 2 コアID : 0 CPUコア : 2 apicid : 0 初期apicid : 0 fpu : yes

JuliaはZigに切り替えてパフォーマンスを大幅に向上させることを考えた方がいいかもね。llvmのリリースごとにパフォーマンスの低下を心配してた著者たちの気持ちを思い出すよ。

LLVMってJuliaの公開APIの一部と見なされてるんじゃないの?@code_llvmみたいなマクロがあって、実際にIRを見せてくれるし。

Juliaは実質的にLLVMにがっちり固定されてる。エコシステムの大部分が、インストリンシックや自動微分(Enzyme)、GPUコンパイルのためにLLVMに依存してるからね。BaseやCoreは言うまでもない。コンパイラはかなりリターゲット可能で、これは今も活発に取り組まれている分野だよ。だから、将来的にはZigが言語の一部のための代替コンパイラとして考えられるかもしれないね。

それがコンパイル時間を短縮する方法になるかもだけど、Julia側にはまだやることがたくさんあると思う。もっと細かいコンパイルキャッシュとか、無効化を防ぐためのツールが必要だし、ワールドスプリッティング最適化の削除、コンパイラ内でのマルチスレッドの活用、具体的なシグネチャの自動プリコンパイル、コンパイル時にコードをホットスワップするような怠惰なコードの生成とか。

これってasync/awaitをZigに戻すための前提条件の一つじゃないの? https://github.com/ziglang/zig/wiki/FAQ#what-is-the-status-o...

リンクを読んでみたけど、asyncは戻ってこないか、少なくとも2028年までは無理そうだね。

その辺は全部整理できたよ。今後2〜3ヶ月でみんなに面白いアップデートができると思う。I/Oをゼロからやり直してるところで、ほとんど標準ライブラリの作業だね。

これはZigにとって素晴らしいことだと思う。この方向性がRustとの比較での主な差別化要因になるんじゃないかな。そういえば、俺はそのパフォーマンスアナライザーのレンダリングコードの多くを書いたんだ。自分の作品がネットに出てるのを見るのはいつも楽しいよ。 https://github.com/andrewrk/poop

これはZigにとって素晴らしいことだと思う。この方向性がRustとの比較での主な差別化要因になるんじゃないかな。ちなみに、Rustでもcraneliftを使った似たような取り組みがあるよ: https://github.com/rust-lang/rustc_codegen_cranelift

完全な初心者なんだけど、Zigの他の言語に対する利点は何なの?もっとモダンなCだと思うけど、モダンな部分って何?

それについてググってみるね: https://ziglang.org/documentation/0.14.1/

思いつくままにいくつか挙げると:

  • 複数の難解なツールや言語を使わない統合ビルドシステム
  • Zigのスライスは長さが分かるけど、Cの配列はバッファオーバーフローの問題がある
  • 明示的なオプショナル型があって、必ずチェックしなきゃいけない。ヌルポインタは許可されてない(Cコードと統合する時は、その型が明確に示してくれる)
  • 列挙型、タグ付きユニオン、"switch"式に対する徹底的なチェックが強制される
  • エラーハンドリングが明示的で、関数はエラー(列挙型の値)を返すから、呼び出し側は何らかの形で対処しなきゃいけない。Cでは、関数がエラーを示すために整数を返すことがあるけど、それを完全に無視してもいい。言語に組み込まれたエラーとデータを返す標準的な方法が欠けてる(エラー構造体をパラメータで渡すパターンは無理やり感があるから、特別な構文が必要だと思う)
  • "defer"や"errdefer"ブロックで関数の返却後やエラー時のクリーンアップ
  • マクロの代わりにコンパイル時コード生成(Zigで)や型リフレクション(@typeInfoなど)
  • 呼び出し側がライブラリにアロケータを渡すことで、メモリの割り当て方法や場所を決定することが多い
  • 一般的なアロケータを使うだけでメモリリークを見つけやすい(少なくとも初心者には)

プログラミングを始めてからずっと高級言語を使ってきて、Cやその周辺のエコシステムの難解で直感に反する部分が嫌いだった私にとって、Zigはシステムプログラミングを楽しめる形で始めさせてくれた。

もちろん、要求しているわけではなく、感謝していないわけでもないけど、Zigは無料のプロジェクトだから、現実的な1.0のタイムラインに興味がある。Zigは私が低レベル言語に求めていたものそのものだから、安定するのを待ってる。もちろん、素晴らしいデザイン哲学には感謝してるよ。

macOSもいつか自己ホストされたバックエンドのサポートが来るのかな?