如有疑問或需要協助,請參閱取得說明。
什麼是 Bazel?
Bazel 是用來自動化軟體建構和測試的工具。支援的建構工作包括執行編譯器和連結器,以產生可執行的程式和程式庫,以及為 Android、iOS 和其他目標環境組合可部署的套件。Bazel 與 Make、Ant、Gradle、Buck、Pants 和 Maven 等其他工具類似。
Bazel 有何特別之處?
Bazel 的設計目的是符合 Google 的軟體開發方式。其功能如下:
- 支援多種語言:Bazel 支援多種語言,且可擴充為支援任意程式設計語言。
- 高階建構語言:專案會以
BUILD
語言描述,這是一種精簡的文字格式,可將專案描述為一組互相連結的小型程式庫、二進位檔和測試。相反地,使用 Make 等工具時,您必須描述個別檔案和編譯器叫用作業。 - 多平台支援:同一個工具和相同的
BUILD
檔案可用於為不同架構,甚至不同平台建構軟體。在 Google,我們使用 Bazel 建構所有項目,包括在資料中心系統上執行的伺服器應用程式,以及在手機上執行的用戶端應用程式。 - 可重現性:在
BUILD
檔案中,每個程式庫、測試和二進位檔都必須完整指定其直接依附元件。Bazel 會使用這項依附性資訊,瞭解您在變更來源檔案時必須重建哪些項目,以及哪些工作可並行執行。也就是說,所有版本都是增加的,且一律會產生相同的結果。 - 可擴充:Bazel 可處理大型建構作業;在 Google 中,伺服器二進位檔通常有 100k 個來源檔案,且在沒有變更任何檔案的情況下,建構作業大約需要 200 毫秒。
為什麼 Google 不使用...?
- Make、Ninja:這些工具可精確控制要叫用哪些指令來建構檔案,但使用者必須自行編寫正確的規則。
- 使用者會以更高層級與 Bazel 互動。舉例來說,Bazel 內建的規則適用於「Java 測試」、「C++ 二進位檔」以及「目標平台」和「主機平台」等概念。這些規則經過實戰測試,可確保萬無一失。
- Ant 和 Maven:Ant 和 Maven 主要針對 Java 設計,而 Bazel 則可處理多種語言。Bazel 建議將程式碼集細分為可重複使用的較小單元,並只重新建構需要重建的單元。這可在處理較大的程式碼集時加快開發速度。
- Gradle:Bazel 設定檔的結構比 Gradle 更為嚴謹,可讓 Bazel 精確瞭解每個動作的作用。這可提高平行處理和可重現性。
- Pants、Buck:這兩個工具分別是由 Twitter 和 Foursquare 以及 Facebook 的 Google 前員工所創建和開發。這些工具都是以 Bazel 為範本,但功能組合不同,因此無法取代 Bazel。
Bazel 的來源為何?
Bazel 是 Google 用於在內部建構伺服器軟體的工具。這項服務也擴展至建構其他軟體,例如連線至我們的伺服器的行動應用程式 (iOS、Android)。
您是否將內部工具重寫為開放原始碼?是否為分支版本?
Bazel 會與內部工具共用大部分程式碼,而且其規則每天都會用於數百萬個建構作業。
Google 為何建構 Bazel?
很久以前,Google 會使用大型產生的 Makefile 建構軟體。這導致建構作業速度緩慢且不可靠,進而影響開發人員的生產力和公司的敏捷性。Bazel 就是解決這些問題的方法。
Bazel 是否需要建構叢集?
根據預設,Bazel 會在本機執行建構作業。不過,Bazel 也可以連線至建構叢集,進一步加快建構和測試速度。詳情請參閱遠端執行和快取和遠端快取說明文件。
Google 的開發流程如何運作?
對於伺服器程式碼集,我們採用以下開發工作流程:
- 所有伺服器程式碼都位於單一龐大的版本控制系統中。
- 每個人都會使用 Bazel 建構軟體。
- 不同的團隊擁有來源樹狀結構的不同部分,並將其元件做為
BUILD
目標提供。 - 分支功能主要用於管理版本,因此每個人都會在最新修訂版本中開發軟體。
Bazel 是這項理念的基礎:由於 Bazel 要求完整指定所有依附元件,我們可以預測哪些程式和測試會受到變更影響,並在提交前進行審查。
如要進一步瞭解 Google 的開發程序,請參閱 eng tools 網誌。
為什麼要開放 Bazel?
建構軟體應該既有趣又簡單。緩慢且無法預測的建構作業會讓程式設計變得乏味。
為什麼要使用 Bazel?
- Bazel 只會重新編譯需要重新編譯的檔案,因此可縮短建構時間。同樣地,它也可以略過重複執行已知未變更的測試。
- Bazel 會產生確定性結果。這樣一來,就能消除增量和清除版本、筆電和 CI 系統之間的偏差。
- Bazel 可在同一個工作區中使用相同工具建構不同的用戶端和伺服器應用程式。舉例來說,您可以在單一提交中變更用戶端/伺服器通訊協定,並測試更新後的行動應用程式是否可與更新後的伺服器搭配運作,同時使用相同工具建構這兩者,充分發揮 Bazel 的所有上述優點。
能否提供一些範例?
是的,您可以參考簡單範例,或查看Bazel 原始碼,瞭解更複雜的範例。
Bazel 最擅長什麼?
Bazel 可透過下列屬性建構及測試專案:
- 程式碼集數量龐大的專案
- 使用 (多種) 編譯語言編寫的專案
- 在多個平台上部署的專案
- 有大量測試的專案
我可以在哪裡執行 Bazel?
Bazel 可在 Linux、macOS (OS X) 和 Windows 上執行。
只要有適用於該平台的 JDK,轉移至其他 UNIX 平台應該會比較容易。
我應該避免在哪些情況下使用 Bazel?
- Bazel 會盡量聰明地快取。也就是說,如果建構作業的輸出內容不應快取,就不適合使用此方法。舉例來說,請勿從 Bazel 執行下列步驟:
- 從網際網路擷取資料的編譯步驟。
- 與網站品質確保例項連結的測試步驟。
- 變更網站雲端設定的部署步驟。
- 如果您的建構作業包含幾個長時間的連續步驟,Bazel 可能無法提供太多協助。將冗長的步驟分解為較小的個別目標,讓 Bazel 可以並行執行,就能加快速度。
Bazel 的功能組合穩定性如何?
核心功能 (C++、Java 和 Shell 規則) 在 Google 內部廣泛使用,因此經過徹底測試,且幾乎不會發生流失。同樣地,我們每天會在數十萬個目標上測試 Bazel 的新版本,以找出迴歸現象,並每個月多次發布新版本。
簡單來說,除了標示為實驗功能的功能之外,Bazel 應該都能正常運作。對非實驗規則所做的變更將回溯相容。如需功能支援狀態的詳細清單,請參閱支援文件。
Bazel 的二進位檔穩定性如何?
在 Google 內部,我們會確保 Bazel 很少發生當機情形。這也適用於我們的開放原始碼程式碼集。
如何開始使用 Bazel?
請參閱入門指南。
Docker 無法解決可重現性問題嗎?
有了 Docker,您就能輕鬆建立使用固定 OS 版本的沙箱,例如 Ubuntu 12.04、Fedora 21。這可解決系統環境的重現問題,也就是「我需要哪個版本的 /usr/bin/c++?」
Docker 不會針對原始碼的變更處理可重現性問題。在 Docker 容器中執行 Make 時,如果使用寫得不夠完善的 Makefile,仍可能會產生無法預測的結果。
在 Google 內部,我們會將工具納入原始碼控管系統,以便重現。這樣一來,我們就能以與基礎程式庫變更相同的機制,檢查工具變更 (「將 GCC 升級至 4.6.1」) 和修復 OpenSSL 中的邊界檢查。
我可以建構用於 Docker 部署的二進位檔嗎?
您可以使用 Bazel 在 C/C++ 中建構靜態連結的獨立二進位檔,以及 Java 的自給自足 JAR 檔案。這些程式在執行時,對一般 UNIX 系統的依附元件很少,因此應該很容易在 Docker 容器中安裝。
Bazel 有結構較複雜程式的慣例,例如使用一組資料檔案的 Java 程式,或以子程序執行其他程式。您可以將這類環境封裝為獨立的封存檔,以便部署至不同的系統,包括 Docker 映像檔。
我可以使用 Bazel 建構 Docker 映像檔嗎?
可以,您可以使用我們的 Docker 規則建構可重現的 Docker 映像檔。
Bazel 是否會自動讓建構作業可重現?
就 Java 和 C++ 二進位檔而言,如果您不變更工具鍊,答案是肯定的。如果建構步驟涉及自訂食譜 (例如透過規則中的 Shell 指令碼執行二進位檔),您就需要特別小心:
- 請勿使用未宣告的依附元件。沙箱執行作業 (–spawn_strategy=sandboxed,僅適用於 Linux) 有助於找出未宣告的依附元件。
- 請勿在產生的檔案中儲存時間戳記和使用者 ID。ZIP 檔案和其他封存檔特別容易發生這種情況。
- 避免連上網路。沙箱執行作業也能在這方面提供協助。
- 避免使用隨機數字的程序,特別是許多程式設計語言中的字典檢索程序。
您是否有二進位版本?
我使用 Eclipse/IntelliJ/XCode。Bazel 如何與 IDE 互通?
如要使用 IntelliJ,請查看 IntelliJ 搭配 Bazel 外掛程式。
如要使用 XCode,請試試 Tulsi。
如果是 Eclipse,請查看 E4B 外掛程式。
如要瞭解其他 IDE,請參閱這篇網誌文章,瞭解這些外掛程式的運作方式。
我使用 Jenkins/CircleCI/TravisCI。Bazel 如何與持續整合系統互通?
如果建構或測試叫用失敗,Bazel 會傳回非零的結束代碼,這應該足以進行基本持續整合整合。由於 Bazel 不需要清除建構作業來確保正確性,因此在開始建構/測試執行作業前,請勿將持續整合系統設為清除。
如要進一步瞭解結束碼,請參閱使用者手冊。
我們可以期待 Bazel 日後推出哪些功能?
請參閱路線圖。
我可以使用 Bazel 建構 INSERT LANGUAGE HERE 專案嗎?
Bazel 可擴充。任何人都可以新增支援新語言。支援多種語言:請參閱Build 百科全書,查看建議清單,並造訪 awesomebazel.com,取得更完整的清單。
如要開發擴充功能或瞭解其運作方式,請參閱 擴充 Bazel 的說明文件。
我可以為 Bazel 程式碼庫做出貢獻嗎?
請參閱貢獻指南。
為什麼不是所有開發作業都公開進行?
我們仍必須經常重構 Bazel 中公開程式碼與內部擴充功能之間的介面。因此,開發人員很難在公開場合進行開發。
您是否已將 Bazel 開放原始碼?
我們正在進行 Bazel 的開放原始碼作業。我們仍在努力開放原始碼:
- 許多單元和整合測試 (這應該可讓您更輕鬆地提供修補程式)。
- 完整的 IDE 整合。
除了程式碼之外,我們希望最終能公開進行所有程式碼審查、錯誤追蹤和設計決策,並納入 Bazel 社群。我們尚未達到這個目標,因此某些變更會直接出現在 Bazel 存放區,而沒有明確的說明。儘管我們無法掌握相關資訊,但我們仍希望能協助外部開發人員,並與他們合作。因此,我們會開放程式碼,即使部分開發作業仍在 Google 內部進行。如果在轉換為開放式模型的過程中,有任何不清楚或不合理的情況,請告訴我們。
Bazel 是否有部分內容永遠不會開放原始碼?
是的,部分程式碼庫已整合 Google 專屬技術,或我們一直想找藉口移除 (或兩者皆是)。這些程式碼集的部分內容無法在 GitHub 上取得,而且可能永遠無法取得。
如何與團隊聯絡?
歡迎透過 bazel-discuss@googlegroups.com 與我們聯絡。
該到哪裡回報錯誤?
在 GitHub 上提出問題。
程式碼庫中為何出現「Blaze」這個字?
這是工具的內部名稱。請以 Bazel 的名稱稱呼 Bazel。
為什麼其他 Google 專案 (Android、Chrome) 使用其他建構工具?
在第一個 (Alpha) 版本推出之前,Bazel 並未對外開放,因此 Chromium 和 Android 等開放原始碼專案無法使用這項工具。此外,Chrome 等 Windows 應用程式的建構作業,也因為缺乏 Windows 支援而遇到問題。由於專案已成熟且更加穩定,Android 開放原始碼計畫正在遷移至 Bazel。
「Bazel」要怎麼唸?
與美國英語中的「basil」(香草) 一樣:「BAY-zel」。與「hazel」同音。IPA:/ˈbeɪzˌəl/