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