開源 Nix 生態系統正在見證一項令人興奮的發展:nix-ninja,這是一個透過利用 Nix 的實驗性動態派生(dynamic derivations)功能來徹底改變編譯工作流程的工具。這一創新在開發者社群引起了極大的興趣,特別是那些使用複雜構建系統的開發者。
動態派生:通往穩定版本的道路
社群中討論最多的方面之一是 Nix 中動態派生穩定化的時間表。目前,nix-ninja 依賴於 Nix 未釋出版本中的實驗性功能,這引發了關於這些功能何時可能得到官方支援的問題。
一位參與動態派生開發的 Nix 核心開發者對路線圖提供了一些清晰的解釋,他解釋說動態派生依賴於內容定址派生(content-addressing derivations),這項功能已經在實驗性功能狀態中停留了一段時間。然而,透過集中精力和範圍管理,穩定化可能在不久的將來實現。該開發者將剩餘的工作描述為儘管是一系列的犛牛剃毛(yak shaves)——一個指代在解決主要目標之前必須完成一系列看似不相關任務的術語——但實際上工作量並不是很大。
複雜構建的效能潛力
nix-ninja 的效能影響尤其令人期待。該工具旨在實現真正的增量編譯,在構建圖中任何位置更改單個 C/C++ 檔案只需要重新編譯該檔案,並且只重新連結受影響的可執行檔案或共享庫。
雖然仍在開發中,但早期測試表明,Nix 的沙盒環境開銷對增量編譯任務幾乎沒有影響。然而,一些功能仍然缺失,例如對依賴生成原始檔的目標的適當處理(如 Nix 的 bison 解析器),這目前被追蹤為一個未解決的問題。
「長期的最終目標是,如果你不更改標頭檔案,只更改構建圖中任何位置的單個 C/C++ 檔案,你應該能夠快速地只重新編譯該檔案,並且只重新連結輸出物件檔案所構建的可執行檔案/共享庫。」
nix-ninja 的主要特點
- 解析 ninja.build 檔案併為每個編譯單元生成一個派生項(derivation)
- 將構建輸入和輸出儲存在基於內容定址的派生項中,以實現細粒度的增量構建
- 提供與 ninja 相容的命令列介面(可作為直接替代品使用)
- 支援本地執行或在 Nix 派生項內執行
系統要求
- 啟用了以下實驗性功能的 Nix:
- nix-command
- dynamic-derivations
- ca-derivations
- recursive-nix
開發里程碑
- 0.1.0:首個版本,專注於正確性
- 0.2.0:主要效能特性,使增量構建更加高效
戰略性聚焦於 Ninja 構建檔案
開發者選擇專門針對 Ninja 構建檔案,這被證明是一個戰略性決定。透過支援 Ninja 作為構建圖表示,nix-ninja 可以與眾多流行的構建系統一起工作,如 CMake、meson、premake 和 gn,這些系統都輸出 Ninja 檔案。
這種方法對 Nix 社群特別相關,因為 Nix 本身使用 meson 並輸出 Ninja 檔案。這一選擇允許透過增量、可眾包的方式改進整個生態系統的構建效能,首先從 LLVM 和 Chromium 等大型專案開始,這些專案最能從增量編譯中受益。
隨著 nix-ninja 繼續朝著其專注於正確性的 0.1.0 里程碑以及隨後專注於效能功能的 0.2.0 版本發展,該專案代表了一個有希望的步驟,旨在使 Nix 構建更加高效,而無需對現有構建系統進行大規模重寫。對於使用複雜程式碼庫的開發者來說,這個工具可以透過減少編譯時間並透過 Nix 的內容定址派生提供更細粒度的增量性,從而顯著提高生產力。
參考:nix-ninja