本頁說明密封性、使用密封建構的優點,以及識別建構中非密封行為的策略。
總覽
假如有相同的輸入原始碼和產品設定,密封建構系統一律會將建構與主機系統隔離,藉此傳回相同的輸出內容。
為隔離建構作業,對本機或遠端主機上安裝的程式庫和其他軟體沒有任何密封性。它們取決於特定版本的建構工具 (例如編譯器),以及依附元件 (例如程式庫)。這使得建構程序保持獨立狀態,因為它不依賴建構環境以外的服務。
外觀的兩大面向是:
- 隔離:密封式建構系統會將工具視為原始碼。可以下載工具副本、管理儲存空間,並在代管檔案樹狀結構中使用。這會在主機機器和本機使用者 (包括已安裝的語言版本) 之間建立區隔。
- 來源身分:密封建構系統會嘗試確保輸入的相同性。程式碼存放區 (例如 Git) 會使用一組專屬的雜湊碼識別一組變異。密封建構系統會使用此雜湊識別建構輸入的變更。
優點
外觀建構的主要優點如下:
- 速度:可快取動作的輸出,且除非輸入內容有所變更,否則系統不會再次執行該動作。
- 平行執行:針對指定輸入與輸出,建構系統可建構所有動作的圖表以計算有效和平行執行。建構系統會載入規則並計算動作圖表和雜湊輸入,以在快取中查詢。
- 多個建構作業:您可以在同一部機器上建構多個密封版本,每個版本使用不同工具和版本進行建構。
- 可重現性:密封組件非常適合疑難排解,因為您知道建構版本的確切條件。
辨識不密封
如果您準備改用 Bazel,只要預先改善現有建構的安全防護機制,就可以進行遷移作業。某些建構在非建構中的非經驗來源如下:
.mk
檔案中的任意處理- 以非確定性的方式建立檔案的動作或工具,通常涉及版本 ID 或時間戳記
- 主機之間不同的系統二進位檔 (例如
/usr/bin
二進位檔、絕對路徑、原生 C++ 規則自動設定的系統 C++ 編譯器) - 在建構期間寫入來源樹狀結構。這可避免將同一個來源樹狀結構用於其他目標。第一個版本會寫入來源樹狀結構,並修正目標 A 的來源樹狀結構。因此,嘗試建構目標 B 可能會失敗。
排解非密封版本的建構問題
從本機執行開始,影響本機快取命中的問題會顯示非密封動作。
- 確保空值的依序建構:如果您執行
make
並成功執行建構作業,則再次執行建構作業不應重新建構任何目標。如果您分別執行不同的建構步驟兩次或使用不同的系統,請比較檔案內容的雜湊值以取得不同的結果,該版本就無法重現。 - 執行各種步驟,從各種潛在的用戶端機器對本機快取命中偵錯,以確保您在遇到作業時遇到任何用戶端環境問題。
- 在 Docker 容器內執行建構作業,而該容器僅包含已簽出的來源樹狀結構和主機工具明確列出的清單。建構中斷和錯誤訊息會捕捉隱含的系統依附元件。
- 使用遠端執行規則找出並修正密封問題。
- 在各動作層級啟用嚴格的沙箱,因為建構作業中的狀態可能是有狀態的,並且會影響建構或輸出內容。
- 工作區規則可讓開發人員將依附元件新增至外部工作區,但必須有足夠的豐富程度,才能在程序中執行任意處理作業。只要在 Bazel 指令中加入
--experimental_workspace_rules_log_file=PATH
旗標,即可在 Bazel 工作區規則中取得一些可能與密封作業無關的記錄。
Bazel 的傳統
如要進一步瞭解其他專案如何搭配 Bazel 使用密封版本,請參閱以下 BazelCon 討論內容:
- 使用 Bazel 建構即時系統 (SpaceX)
- Bazel Remote Execution and Remote Caching (Uber 和 TwoSigma)
- 使用遠端執行和快取功能加快建構速度
- 融合 Bazel:加快建構速度
- 遠端執行與本機執行作業
- 改善遠端快取的可用性 (IBM)
- 使用 Bazel 打造自駕汽車 (BMW)
- 使用 Bazel + Q&A 打造自駕汽車 (GM Cruise)