RFC-0186:Fuchsia 適用的 Bazel

RFC-0186:Fuchsia 適用的 Bazel
狀態已接受
區域
  • 建構
說明

採用 Bazel 做為 Fuchsia 元件的主要建構系統,並將 Bazel 導入 fuchsia.git。

問題
  • 108259
變更
作者
審查人員
提交日期 (年/月)2022-04-21
審查日期 (年/月)2022-08-29

摘要

我們預計將 Fuchsia SDK 和 Bazel 導入 fuchsia.git,以採用 Bazel 做為 Fuchsia 元件的主要建構系統。

Fuchsia 團隊承諾完成這項遷移作業。具體而言,Fuchsia 建構團隊、Fuchsia Bazel SDK 整合團隊、Fuchsia Platform Infra、Fuchsia 軟體組合、Fuchsia TPM 團隊和 Fuchsia DevRel 都表示有能力提供及支援這項計畫。

定義

  • 「In-tree」是儲存在 fuchsia.git 的所有檔案。
  • 「Out-of-tree」(OOT) 是指以 Fuchsia 為目標,並以 Fuchsia SDK 做為建構基礎的程式碼,而不是在平台原始碼中採用,且儲存在 fuchsia.git 以外的位置。舉例來說,Intel wlan 驅動程式庫的建構範例會使用 Fuchsia Bazel SDK,在另一個存放區中建構。
  • Bazel - 是軟體開發的開放原始碼建構與測試工具。

提振精神

截至 2022 年第 1 季,Fusia 的平台 (即 fuchsia.git 中的程式碼) 版本會使用 GN/Ninja。2021 年,以 SDK 為基礎的開發加快了技術債和未來策略的發展。Fuchsia 選擇使用 Bazel,做為以 SDK 為基礎的開發作業順暢的路徑,且也針對現有和新的來源基礎採用這個架構。

我們發現,所有元件和產品開發人員在建構和使用 Fuchsia 時,都使用同樣的功能,不論他們所使用的樹狀結構/存放區為何。例如:將原始碼編譯為元件,並將元件及其資產封裝至 Fuchsia 套件中、在目標上執行該軟體、組合產品、產生符號、串流記錄檔等。我們打算整合一組經過整合的 Bazel 和 SDK 工作流程及執行實作作業,藉此降低複雜性和成本。

Fuchsia 團隊必須每天都使用 SDK 和 Bazel 整合服務,在運作良好的工作流程中,為樹狀結構外開發人員產生同理心,並建立及提供出色的 Bazel + SDK 體驗。

相關人員

講師:rlb

審查者:

  • 數字 - Fuchsia 組建團隊
  • chaselatta - Fuchsia 的 Bazel SDK 團隊
  • mangini - Fuchsia 的 Bazel SDK 團隊和 Fuchsia DevRel
  • nsylvain - Fuchsia's EngProd 團隊
  • abarth - Fuchsia Architecture

顧問:

  • Aaronwood - 產品組裝
  • awolter - 產品組裝
  • dannyrosen - Eng 卓越
  • keir - Pigweed
  • tmandry -《Rust for Fuchsia》
  • brunodalbo - 連線能力
  • surajmalhotra - 驅動程式架構
  • amathes - Fuchsia PM 負責人
  • cphoenix - 診斷
  • akbiggs - Fuchsia 上的 Flutter

社群媒體化:

此 RFC 的初步社交化提案都經過 Fuchsia Build 團隊、Fuchsia SDK 團隊、Fuchsia SDK 團隊、Fuchsia EngProd 團隊、Fuchsia 的 Rust 團隊,以及 Fuchsia 上的多位代表和待開發客戶。

設計

這項 RFC 旨在建立專案政策。以下列出這項政策的設計原則。

增量:我們會一次遷移一個元件,一邊學習,

多元包容:雖然 Fuchsia 團隊已採用,並會持續增加 Bazel 的使用範圍,並透過 Bazel 為使用者建立光線充足的路徑,但使用 Bazel 為 Fuchsia 建構軟體並不嚴格。IDK 必須繼續保持各建構系統的運作。

我們的原則是,「建構系統」維度可從「來源存放區」維度相互對照。將建構目標遷移至 Bazel 和 SDK 不需要將程式碼遷移至其他存放區。

我們最後會想用多種「專案」來組織 Fuchsia 開發作業,每項專案都會取得 Fuchsia SDK 的輸入內容,並產生一些可組合成 Fuchsia 系統映像檔的套件或其他二進位構件。這些專案可能為 Fuchsia、 我們的合作夥伴或第三方開發人員所擁有這些專案的大小也可能不同,無論是將單一二進位檔傳送至大型專案的小型專案,都能為 Fuchsia 平台提供相當程度的效益,例如 fuchsia.googlesource.com/platform.git。在我們深入處理這個情況後,就能決定如何將程式碼彙整到專案中,盡可能提高效率。

本 RFC 說明邁向最終的關鍵步驟,也就是重構要由 Fuchsia SDK 上執行的大量 Fuchsia 開發作業。重新託管於 Fuchsia SDK 後,我們就能更彈性地將該開發歸類到專案中。

實作

現有的採用計畫

我們已經開始評估並採用 Bazel 和 SDK,以達成以下目標:

  • 建構並測試整合至工作站的簡單但引入傾向驅動程式庫
  • 建構並測試簡單但可供使用者存取的元件,整合至工作站
  • 建構及測試可選及持續增加的驅動程式
  • 建構及測試範例和其他專案,協助開發人員開始開發 Fuchsia 應用程式
  • 在 Fuchsia 嵌入器上建構及測試 Flutter
  • 建構及測試 Workstations 體驗程式碼
  • 推動 Google 產品進行產品組裝

其他採用提案

在繼續進行之前,我們會收集證據,證明 Bazel SDK 具備足夠的最低可行性和功能,足以支援即將有部分使用者使用的軟體和系統。系統會以 SDK 建構簡易的驅動程式庫和簡易元件 (如上所述),並發布至全球整合,然後納入目前的 Workstations 產品組合程序。接著,Bazel SDK 中的程式碼及其在代管簡易驅動程式庫和簡易元件存放區中的設定,而我們發布這些預先建構元件以供 Workstations 建構程序使用的機制,將由 Fuchsia Engineering 與 Fuchsia 安全性團隊進行審查。只有在使用者通過評論,且收到內含簡易驅動程式庫和簡易元件的產品後,我們才會繼續處理。

在執行上述的「現有採用計畫」之外,我們會在 fuchsia.git 內建立 Bazel 建構樹狀結構和 GN 建構樹狀結構,Bazel 建構作業將能夠建構及測試封裝元件及組合產品。我們會將邏輯 (Bazel 啟動程序、Starlark 規則) 與 Fuchsia Bazel SDK 共用,供樹狀結構外開發人員使用。

我們會先使用 Bazel 和 SDK 在 fuchsia.git 中實作產品組合用途。我們將從 fx build 程序的結尾進行反向作業,這表示我們可以提供線性 GN/Ninja -> Blaze 流程。

替代文字:從 ninja 平台版本組裝成竹子組件,再以竹子製成。

然後,我們會找出一些候選元件,以便從 GN/Ninja 平台建構作業中逐步擷取到 Bazel 平台建構作業,同時保留從相同成果組合連貫的 Fuchsia 映像檔,以及保留或改善其他支援的工作流程。

替代文字:從 ninja 平台版本,將樹狀結構內邊框組件 - 將元件移至邊框

在為這些第一個候選元件導入支援時,我們會留意 KPI (如下方所述),並會與早期採用者互動,確保其工程工作效率不會迴歸。我們也會持續向 Fuchsia 團隊回報狀態和測量結果。

我們預期 fuchsia.git 貢獻者會使用 fx 做為建構建構的前端,而 fx 會同時管理背景中的 Bazel 和 GN/ninja 叫用。針對轉換作業,保留 fx setfx build 等前端將有助於我們封裝遷移作業的詳細資料,並保留工作流程。

目前的計畫是將 GN/Ninja 和 Bazel 封裝於 fint 內封裝的所有內容,然後留意,任何以 fint 實作的 fx 建構工作流程,且會因協助封裝而保留。

Fuchsia Build 團隊負責保留編譯器/模型訓練能力,並與 GN 版本合作協助保留語料庫大小。

將 fuchsia.git 遷移至 Bazel 中的元件,並不會與存放區間移動的元件有所衝突。遷移至 Bazel 的 fuchsia.git 元件可以保留在 fuchsia.git。存放區移動不在這個 RFC 的適用範圍內。不過,在完成將所有目標元件遷移至 Bazel 和 SDK 之前,我們打算重新審視建構架構,並與 FEC 合作,以確定將 Bazel 和 SDK 建構的任何元件從 fuchsia.git 樹狀結構中移出。

KPI

為達成這項目標,建議您採用下列 KPI:

  • 開發人員滿意度 (根據問卷調查評估)
  • 空值建構時間
  • 做為長版預先提交建構工具的設定的完整建構時間
  • 針對該設定預先提交測試時間

針對「空值建構時間」,這是瞭解啟動建構系統本身延遲時間的一種方式,我們會在這方面考量開發人員的整體滿意度和產品性。我們的目標是禁止在空值建構時間發生 50% 的迴歸,除非我們判斷空值建構時間是限制開發人員滿意度和工作效率的重要因素。

針對「設定的完整建構時間」和「預先提交測試時間」,我們建議您不要為 KPI 執行超過 10% 的轉換迴歸,不過我們最終能夠改善所有 KPI。

人員招募

這項作業的人力與資金細節尚未定案,超出這個 RFC 範圍。然而,我們也注意到,軟體供應商與資助計畫是成功將軟體順利導入 SDK 和 Bazel 的關鍵。Fuchsia 有兩支團隊 (Bazel SDK 整合團隊 Fuchsia Build 團隊),最初承諾投資各項資源,讓 Fuchsia 工程師能與元件團隊合作,享有順暢無比的使用體驗。我們預期 Bazel SDK 整合團隊和 Fuchsia Build 團隊將第一次遷移至 Bazel 和 SDK,然後根據這些經驗,我們可以針對後續的遷移提供充足的資訊,包括人員編列/資金估算。

自動化工具

在將相關功能遷移至 Bazel 後,我們會探索如何新增自動檢查,確保日後不會因意外使用 GN 進行建構而增加這些領域。這個階段應該正朝整個流程或在程序結束時發生,在我們確認達成 KPI 目標且不會遭到迴歸後。

未來可能的注意事項

日後如果有明顯的期望,我們可能會將 Fuchsia 原始碼的所有程式碼遷移至 Bazel。在這個潛在的未來,我們期望採用單純的 Bazel 建構作業,並淘汰用來管理建構作業的 fxfint 指令,而不是在 Bazel 名詞中完全管理事務。

說明文件

我們在 RFC-139 中更新了 fuchsia.dev 的說明文件,藉此解釋及說明如何搭配 Bazel 使用 SDK。

我們會在 fuchsia.dev 上更新適用於 Fuchsia 的協作者說明文件,瞭解樹狀結構內使用 Bazel 的時機和方式。在本文件中,我們會針對使用 Bazel 或 GN 建構的元件設定 何時的指南,以及執行建構作業的貢獻者指南。這份說明文件也會公開。

缺點、替代方案和未知

請注意,RFC-0153 提議使用 Fuchsia 平台建構作業所用開放原始碼 Ninja 工具的臨時自訂版本,該工具仍在持續進行中,不在上述 RFC 的涵蓋範圍內。Fuchsia 將繼續使用 Ninja 一段時間 因此改善 Ninja 的生活品質固然重要,也歡迎加入我們的行列。

不明:如果技術上可行,可以將 Fuchsia 的所有程式碼全部移至 Bazel,同時維持良好的使用者體驗,並確保使用 Bazel 時符合慣用習慣。我們會與建構合作夥伴一同探索這個潛力,藉此判斷是否有視線可及。請注意,這個未知情況並不阻礙我們將 Fuchsia 元件和套件移至 Bazel,而是以刻意來說,這類 RFC 不會獲得核准。

功能差異:Bazel 不支援同一建構叫用中的目標設定轉換。舉例來說,如果使用者想將所有執行檔建構為「release」,那麼一個執行檔為 asan,就等於兩個 bazel build 叫用。我們認為這並非風險或即興表演者,而是源自 Fuchsia 現有的 GN 變化版本系統。

可能的風險:我們知道 Bazel 內建的 C/C++ 規則的限制可能不足以建構低階 Fuchsia 程式庫和二進位檔。根據 Bazel 團隊的 Fuchsia 更新內容及公開藍圖,將 Bazel C/C++ 移植到社群自有且維護的 Starlark 規則是優先要務。這個概念已充分證明,大部分風險都已移除。

不明:Bazel 的檔案系統沙箱機制和網路結果的正確性/密封性取捨的影響。Bazel 會使用檔案系統沙箱和符號連結,藉此提升正確性和密封度保證。已知程式碼可以在一般建構工作站上乾淨的建構工作負載中增加高達 10%,並對建構時間長度有所影響。我們預期在結合遠端建構執行功能時,能應用到展現保存在密封上的好處,從而提供更佳的快取使用率、早期截止和淺層建構作業。不過,如果我們發現保存程度的成本超出預期,且沒有不符合預期效能的好處,就會考慮停用沙箱 (即 --spawn_strategy=local)。

不明:Bazel 團隊的上游擁有者將獲得何種支援。我們沒有理由認為我們不會獲得支援服務,而這個 RFC 的目標,是與 Bazel 擁有者建立更緊密的合作夥伴關係。我們與 Bazel 團隊的初始會議和互動都很有生產力,也願意深入瞭解我們的要求和觀察結果。而我們向 Bazel 團隊提出的問題將迅速獲得解答。我們認為,隨著 Fuchsia 持續針對 SDK (RFC-139) 採用 Bazel,而 Fuchsia 也證明它是絕佳的客戶,Bazel 團隊將持續給予支援和互動。

不明:我們如何使用 Bazel 和 Fuchsia SDK 編譯 Rust 程式碼。我們發現正在積極開發適用於 Bazel 的 Rust,但我們需要測試這個架構,並探索其是否符合 Fuchsia 的需求。我們預期會有後續的 RFC,描述我們支援使用 Bazel 和 Fuchsia SDK 建構 Rust 程式碼的方式。這會與 Rust on Fuchsia 團隊密切合作。

不明,需要判斷:由 GN/Ninja 建構的構件和使用 Bazel 在 fuchsia.git 中建構的封裝元件之間的確切介面,以便組合成產品映像檔。我們預計會擴大產品組合的涵蓋範圍,以解決這個問題,詳細內容待定。

不明:Fuchsia 團隊正在評估如何支援 Windows 做為開發人員主機環境,而這將會引入新的要求,說明 Fuchsia 如何支援使用 Bazel 進行以 SDK 為基礎的開發。我們尚未具備所有需求條件。不過請注意,Bazel 支援 Windows 做為開發人員主機,因此目前對於 Bazel 無法在 Windows 中運作,目前並沒有理由。若發生這類攔截器問題,我們將與 Bazel 團隊密切聯絡。

不明:是否能使用 bazel test 在基礎架構中進行測試。這不是這個 RFC 的阻斷器,因為我們主要著重於使用 Bazel 進行編譯。

替代做法:繼續使用目前的 GN/Ninja 版本處理 fuchsia.git 中的元件。我們持續為平行工作提供資金,並失去因 Bazel 帶來工程工作效率的優勢,而繼續與我們的開發人員生態系統維持同理心。此外,平台建構維護人員指出如果繼續仰賴 GN/Ninja 就能運作,因為這類系統無法保證建構的簡潔版本或正確的漸進式建構作業。

替代做法:重新考慮 RFC-0139 中記錄的決策以採用 Bazel,而是採用不同的建構系統,然後對齊相同建構系統的樹狀結構內和樹狀結構外。由於沒有重新考慮 RFC-0139 的基礎,因此我們拒絕採用這個替代做法。

替代做法:與其在 fuchsia.git 中採用 Bazel 和 SDK,我們也可以優先將元件程式碼從 fuchsia.git 移至採用 Bazel 和 SDK 技術的其他存放區。這些存放區之間的整合作業只能透過預先建構完成。成果也相同:Fuchsia 團隊決定採用 Bazel 和 SDK,做為 Fuchsia 開發業務的主要方式,而開發 Fuchsia 用的方式與 Google 以外的 Fuchsia 開發人員相同。考慮到這個選項,但部分團隊表示希望能夠變更可透過 SDK (例如介面) 存取的程式碼,以及其元件程式碼做為同一修訂版本的一部分。我們注意到,部分團隊已計劃採用 Bazel 和 SDK,將程式碼移至 fuchsia.git 以外的存放區。

替代做法:(已考慮但遭到拒絕),而不是針對 fuchsia.git 內部編寫兩個程式碼系統,而是將元件移出樹狀結構,以便使用 SDK 和 Bazel 建構這些元件。這將實現相同的長期目標 (使用 SDK 和 Bazel 建構更多程式碼),但我們相信這種情境在更短的時間內就能達成目標。這也可能引進多個變數,例如將程式碼的建構遷移至 Bazel + SDK,並將程式碼遷移至其他存放區,而我們只想一次變更一個變數。我們想要先將元件的建構變更為 Bazel 和 SDK,然後再視需要將元件的程式碼移至其他存放區。

先前的圖片和參考資料

使用或遷移至 Bazel 的其他範例專案

Bazel 使用者社群不斷成長。Android 開放原始碼計畫正遷移至 Bazel,先前使用 Ninja 和 Make 的組合。Bazel 是 Google 針對多個成功的開放原始碼專案 (例如 Abseil 和 Tensorflow) 精選的建構系統。

其他建構系統遷移作業

紫紅色

其中會說明 Fuchsia 執行的另一個建構系統遷移作業:ZN->GN 遷移作業 (又稱「建構統合」)。

在建構統合之前,Fusia 有兩個以 GN/Ninja 為基礎的建構作業,系統會依序呼叫這些版本。ZN/Ninja 版本會先建構一些構件,接著 GN/Ninja 版本便會開始建構其他構件。您可以在 GN 中使用 ZN 輸出,但反之亦然。

ZN 和 GN 之間的界線是圍繞 ZBI 內容等構件繪製。這個介面並不是很好的介面,因為會導致無法使用內建於 GN 的構件 (例如 FIDL、元件、套件、Rust 支援) 產生在 ZN 中建構的構件,例如驅動程式、早期啟動程式等。

我們提議將 GN 構件遷移至 ZN,但實際上無法這麼做。而只是將 ZN 構件移至 GN。這項移動構件的程序會逐步進行驗證,方法是產生建構結果的「摘要資訊清單」,並確保沒有任何單一遷移步驟意外變更資訊清單。當 ZN 版本變成空白 (並未計入上述資訊清單) 後,再移除這項工作,這項工作就會結束。

經驗談:

  1. 在遷移期間維持重要工作流程的連續性。
  2. 使用明確且明確的合約來分階段遷移。與 Fuchsia GN 簽訂的 Fuchsia ZN 合約並非刻意簽訂的合約 (Fuchsia 不會只為外部使用或延長使用 ZBI)。這項 RFC 提議使用套件和產品組合做為合約,示範學習課程 (請參閱 RFC-0072RFC-0095 是即將推出的 Fuchsia 平台藍圖)。
  3. 在製定完成的計畫之前,系統不應開始進行遷移作業。

Chrome 的 GYP-> GN

另一項建構系統遷移作業,涉及 Fuchsia 團隊成員參與其中,那就是 Chrome 的從 GYP 遷移至 GN。

由於 GYP 版本不易理解、難以解釋,而相當於「gn gen」的條件約一分鐘,因此是希望 Chrome 從 GYP 遷移至 GN。Chrome 團隊的工作效率會大幅下降,而您希望使用另一個建構系統。

遷移作業已順利完成。我們估計需要 3 人以上的工作 大約需要 3 秒鐘的時間

Chrome 團隊嘗試採取漸進做法,但決定在 9 個月後暫停這項工作。他們發現建構設定中的阻抗不符,是漸進式方法阻礙的主要來源。後來,團隊與 GYP 版本並行啟動一個「由下而上」的 GN 版本。首先是訓練機器人,再來是真正的機器人。這項遷移範圍擴大到目標平台 (Linux、Windows、Mac、Android、iOS)。遷移作業順利完成的其中一個關鍵原因是,這項技術的擁護者承諾將自己付諸實行。

我們從這次遷移中學到:

  • 請使用簡單易懂的指示說明該怎麼做,因為案例太籠統。完成轉換的使用者必須完全瞭解新舊建構系統。幾乎沒有人具備這些知識。
  • 這類遷移作業需要耗費許多心力和麻煩,而且可能難以長期維持的貢獻。
  • 我們能明確告知事件發生順序,並提供易於存取的追蹤和整理功能,方便人員輕鬆協助完成遷移作業。
  • 使用者的感受和同理心是影響遷移成功的關鍵。本次遷移作業需要長尾使用者功能和使用者工作流程,才能妥善遷移這些資料。