Bazel 構建工具介紹
什麼是 Bazel
Bazel 是一個開源的構建和測試工具,類似於Make、Maven及Gradle。它使用一種人易於理解的高階構建語言。Bazel 支援多種開發語言的專案,能夠基於多個平臺來構建。Bazel支援跨多個製品庫和大規模使用者的大型程式碼倉庫。
為什麼我們需要Bazel
Bazel 具有以下優勢:
高階構建語言 Bazel使用一種抽象的、人易於理解的、語義級別的高階語言來描述專案的構建屬性。與其他工具不同,Bazel基於庫,二進位制檔案,指令碼和資料集的概念進行操作,使您免於陷入將單個呼叫編寫到編譯器和連結器等工具的複雜性。
Bazel高效可靠 Bazel快取以前完成的所有工作,並跟蹤檔案內容和構建命令的更改。通過這種方式,Bazel知道何時需要重建某些東西,並僅重建那些東西。為了進一步加快構建速度,您可以將專案設定為以並行和增量的方式構建。
Bazel是跨平臺的 Bazel可以在Linux,macOS和Windows上執行。Bazel可以為同一個專案中的多個平臺(包括桌面,伺服器和移動裝置)構建二進位制檔案和可部署軟體包。
Bazel擴充套件性強 Bazel在使用100k+原始檔處理構建時仍然保持良好的效能表現。它適用於多個製品儲存庫和10K使用者規模。
Bazel是可擴充套件的 您可以擴充套件Bazel以支援您選擇的語言。
Bazel 核心概念
Bazel根據在稱為工作空間(WORKSPACE)的目錄中組織的原始碼構建軟體。工作空間中的原始檔以包的巢狀層次結構進行組織,其中每個包都是包含一組相關原始檔和一個BUILD檔案的目錄。BUILD檔案指定可以從源構建哪些軟體輸出。
工作空間
工作空間是檔案系統上的目錄,其中包含要構建的軟體的原始檔,以及指向包含構建輸出的目錄的符號連結。每個工作空間目錄都有一個名為WORKSPACE的文字檔案,該檔案可能為空,或者可能包含對構建輸出所需的外部依賴項的引用。
包
工作空間中程式碼組織的主要單元是包。包是相關檔案的集合,以及它們之間的依賴關係的規範。包被定義為包含名為BUILD的檔案的目錄,該檔案位於工作空間中的頂級目錄下。包中包含其目錄中的所有檔案,以及其下的所有子目錄,除了那些本身包含BUILD檔案的子目錄。
例如,在以下目錄樹中有兩個包,my/app
和子包my/app/tests
。請注意,my/app/data
my/app
的目錄。
src/my/app/BUILD
src/my/app/app.cc
src/my/app/data/input.txt
src/my/app/tests/BUILD
src/my/app/tests/test.cc
目標
包是一個容器。包的元素稱為目標。大多數目標是兩種主要型別之一,即檔案和規則。此外,還有另一種目標,包組,但它們的數量要少得多。
檔案進一步分為兩種。原始檔通常由開發者的努力編寫,並簽入程式碼儲存庫。生成的檔案(有時稱為派生檔案)不會簽入,而是由構建工具根據特定規則從原始檔生成。
第二種目標是規則。規則指定一組輸入和一組輸出檔案之間的關係,包括從輸入中匯出輸出的必要步驟。規則的輸出始終是生成的檔案。規則的輸入可以是原始檔,但也可以是生成的檔案; 因此,一條規則的輸出可能是另一條規則的輸入,允許構建長鏈規則。
在大多數情況下,規則的輸入是原始檔還是生成的檔案都是無關緊要的; 重要的只是該檔案的內容。這一事實使得用規則生成的生成檔案替換複雜的原始檔變得容易,例如當手動維護高度結構化檔案的負擔變得太煩人時,有人編寫程式來派生它。該檔案的使用者無需更改。相反,生成的檔案可以很容易地被僅具有本地更改的原始檔替換。
規則的輸入還可以包括其他規則。這種關係的確切含義通常非常複雜,並且依賴於語言或規則,但直觀上很簡單:C++庫規則A可能有另一個C++庫規則B用於輸入。這種依賴性的影響是B的標頭檔案在編譯期間可用於A,B的符號在連結期間可用於A,B的執行時資料在執行期間可用於A。
所有規則的不變數是規則生成的檔案始終屬於與規則本身相同的包; 無法將檔案生成到另一個包中。但是,規則的輸入來自另一個包的情況並不少見。
包組是一組包,其目的是限制某些規則的可訪問性。包組由package_group
函式定義。 它們有兩個屬性:它們包含的包列表及其名稱。 唯一允許引用它們的方法來自規則的visibility
屬性或package
函式的default_visibility
屬性; 他們不生成或使用檔案。
總結
Bazel 預設支援多種開發語言,如Java,C++,Javascript, Android等等,您還可以根據需要擴充套件它。在很多開源專案中都有用到它,由於其支援並行構建,增量構建等特性,與傳統構建工具區別很大,因此備受青睞,後續會詳細介紹其他概念和入門使用,敬請關注。