本頁面說明完整性、使用完整建構作業的優點,以及識別建構作業中非完整行為的策略。
總覽
如果輸入的原始碼和產品設定相同,密封建構系統一律會傳回相同的輸出內容,因為建構作業與主機系統的變更內容隔離。
為隔離建構作業,密封建構作業不會受到本機或遠端主機上安裝的程式庫和其他軟體影響。這類模組依附於特定版本的建構工具 (例如編譯器) 和依附元件 (例如程式庫)。這樣一來,建構程序就不會依賴建構環境外部的服務,因此可獨立運作。
密封性有兩個重要層面:
- 隔離:密封建構系統會將工具視為原始碼。他們可以下載工具副本,並在受管理檔案樹狀結構中管理儲存空間和用量。這會在主機和本機使用者之間建立隔離區,包括已安裝的語言版本。
- 來源身分:嚴密建構系統會盡量確保輸入內容相同。程式碼存放區 (例如 Git) 會使用專屬雜湊碼識別程式碼變動集。嚴密建構系統會使用這個雜湊值,識別建構輸入內容的變更。
優點
密封建構作業的主要優點如下:
- 速度:動作的輸出內容可以快取,除非輸入內容有變更,否則不需要再次執行動作。
- 平行執行:針對指定輸入和輸出內容,建構系統可以建構所有動作的圖表,計算有效率的平行執行作業。建構系統會載入規則,並計算動作圖和雜湊輸入內容,以便在快取中查詢。
- 多個建構作業:您可以在同一部機器上建構多個密封建構作業,每個建構作業使用不同的工具和版本。
- 可重現性:密封建構作業有助於排解問題,因為您確切知道產生建構作業的條件。
找出非密封性
如果您準備改用 Bazel,請預先改善現有建構作業的密封性,這樣遷移作業會更輕鬆。建構作業中常見的非密封性來源包括:
- 在
.mk
個檔案中任意處理 - 以非決定性方式建立檔案的動作或工具,通常涉及建構 ID 或時間戳記
- 不同主機的系統二進位檔 (例如
/usr/bin
二進位檔、絕對路徑、用於原生 C++ 規則自動設定的系統 C++ 編譯器) - 在建構期間寫入來源樹狀結構。這樣可避免將同一棵來源樹狀結構用於其他目標。第一次建構會寫入來源樹狀結構,修正目標 A 的來源樹狀結構。因此嘗試建構目標 B 可能會失敗。
排解非密封建構作業的問題
從本機執行作業開始,影響本機快取命中率的問題會顯示非密封動作。
- 確保連續建構作業為空值:如果您執行
make
並順利建構,再次執行建構作業時,不應重建任何目標。如果您在不同系統上或兩次執行每個建構步驟,並比較檔案內容的雜湊值,結果卻不同,則表示建構作業無法重現。 - 執行步驟,從各種可能的用戶端電腦偵錯本機快取命中,確保您能找出任何用戶端環境洩漏至動作的情況。
- 在 Docker 容器中執行建構作業,該容器只包含已簽出的來源樹狀結構和主機工具的明確清單。建構中斷和錯誤訊息會擷取隱含的系統依附元件。
- 使用遠端執行規則找出並修正密封性問題。
- 在每個動作層級啟用嚴格的沙箱,因為建構作業中的動作可能是有狀態的,並影響建構作業或輸出內容。
- 工作區規則
可讓開發人員將依附元件新增至外部工作區,但這些規則已足夠豐富,可讓任意處理程序在過程中發生。如要取得 Bazel 工作區規則中部分可能非密封動作的記錄,請在 Bazel 指令中加入
--experimental_workspace_rules_log_file=PATH
標記。
使用 Bazel 確保密封性
如要進一步瞭解其他專案如何透過 Bazel 使用密封建構作業獲得成功,請參閱下列 BazelCon 演講:
- 使用 Bazel 建構即時系統 (SpaceX)
- Bazel 遠端執行和遠端快取 (Uber 和 TwoSigma)
- 透過遠端執行和快取功能加快建構速度
- 融合 Bazel:加快增量建構作業
- 遠端執行與本機執行
- 提升遠端快取可用性 (IBM)
- 使用 Bazel 建構自動駕駛車輛 (BMW)
- 使用 Bazel 建構自駕車 + 問與答 (GM Cruise)