Bazel構建
簡介
Bazel是一個類似於Make,Maven和Gradle的開源構建和測試工具。Bazel支援多種語言混編的專案並且可以根據不同的平臺輸出不同的構建結果。
優勢:
- 加快構建和測試速度:Bazel只重建必要的東西,藉助快取,優化依賴關係分析和並行執行,可以獲得快速的和增量的構建。
- 支援多種語言:支援Java, C++, Android, iOS, Go和各種其他語言,可以執行在Windows,macOS和Linux上。
- 可擴充套件:可以擴充套件Bazel以支援您選擇的語言
基本概念
工作區
一個 工作空間
是你的檔案系統,它包含了原始檔、符號連結以及輸出目錄。每個工作空間都有一個名為 WORKSPACE
的文字檔案,該檔案可能為空,或者包含對 ofollow,noindex">外部依賴 引用
包
包被定義為包含檔案的目錄
目標
包是一個容器。包的元素稱為 目標
,大多數目標有兩種型別,即 檔案 和 規則
檔案進一步分為兩種。 原始檔 、 生成的檔案
第二種目標是 規則 ,
如何使用bazel
BUILD
Bazel如何運作
執行構建或測試時,Bazel執行以下操作:
action
由於所有以前的構建工作都是快取的,因此Bazel可以識別並重用快取,只重建或重新測試更改的內容
什麼是action圖
action圖表示各個構建輸入和他們之間的關係,以及Bazel將執行的構建操作。基於這張圖Bazel可以跟蹤檔案內容的更改
安裝
通過Homebrew安裝Bazel包,如下所示:
brew install bazel
可以了,好了!您可以通過執行以下命令確認Bazel已成功安裝:
bazel version
安裝後,您可以使用以下命令升級到較新版本的Bazel:
brew upgrade bazel
常用命令
$bazel help 用法:bazel <command> <options> ... 可用命令: analyze-profile分析構建配置檔案資料。 aquery對分析後的操作圖執行查詢。 build構建指定的目標。 canonicalize-flagsCanonicalize Bazel flags。 clean刪除輸出檔案,並可選擇停止伺服器。 cquery執行分析後依賴圖查詢。 dump轉儲Bazel伺服器程序的內部狀態。 help列印命令或索引的幫助。 info顯示有關bazel伺服器的執行時資訊。 fetch獲取目標的所有外部依賴項。 mobile-install在移動裝置上安裝應用程式。 query執行依賴關係圖查詢。 run執行指定的目標。 shutdown停止Bazel伺服器。 test構建並執行指定的測試目標。 version列印Bazel的版本資訊。 獲得更多幫助: bazel help <command> 列印<command>的幫助和選項。 bazel幫助startup_options JVM託管Bazel的選項。 bazel幫助目標語法 解釋指定目標的語法。 bazel幫助資訊鍵 顯示info命令使用的鍵列表。
構建Java專案
所有的Bazel構建都是基於一個 工作區(workspace) 概念,它是檔案系統中一個儲存了全部原始碼的目錄,同時還將包含一些構建後的輸出目錄的符號連結(例如: bazel-bin
和 bazel-out
等輸出目錄)。工作區目錄可以隨意放在哪裡,但是工作區的根目錄必須包含一個名為 WORKSPACE
的工作區配置檔案。工作區配置檔案可以是一個空檔案,也可以包含引用外部構建輸出所需的依賴關係。
-
建立BUILD檔案
$ cd ~/demo $ mkdir -p src/main/java/com/test $ cat > src/main/java/com/test/Main.java <<EOF package com.test; public class Main { public static void main(String args[]) { Test.sayHi(); } } EOF $ cat > src/main/java/com/test/Test.java <<EOF package com.test; public class Test { public static void sayHi() { System.out.println("Hello World!"); } } EOF
Bazel通過工作區中所有名為
BUILD
的檔案來解析需要構建的專案資訊,因此,我們需要先在~/gitroot/my-project
目錄建立一個BUILD
構建檔案。下面是BUILD構建檔案的內容:# ~/demo/BUILD java_binary( name = "test", srcs = glob(["**/*.java"]), main_class = "com.test.Main", )
BUILD檔案採用類似Python的語法。雖然不能包含任意的Python語法,但是BUILD檔案中的每個構建規則看起來都象是一個Python函式呼叫,而且你也可以用
"#"
開頭來新增單行註釋。java_binary
是一個構建規則。其中name
對應一個構建目標的識別符號,可用用它來向Bazel指定構建哪個專案。srcs
對應一個原始檔列表,Bazel需要將這些原始檔編譯為二進位制檔案。其中glob(["**/*.java"])
表示遞迴包含每個子目錄中以每個.java
為字尾名的檔案。com.test.Main
指定包含main方法的類。 -
執行構建命令
$ bazel build //:test INFO: Analysed target //:test (0 packages loaded). INFO: Found 1 target... Target //:test up-to-date: bazel-bin/test.jar bazel-bin/test INFO: Elapsed time: 0.458s, Critical Path: 0.01s INFO: 0 processes. INFO: Build completed successfully, 1 total action $ bazel-bin/test Hello World!
Bazel和Android
構建Android應用程式
-
設定
ANDROID_HOME
變數將其設定為Android SDK的位置,預設為
$HOME/Android/Sdk/
。例如:
export ANDROID_HOME=$HOME/Android/Sdk/
為方便起見,請將以上語句新增到您的
~/.bashrc
檔案中。 -
獲取示例專案
需要從GitHub獲取示例專案。有兩個分支:
source-only
和master
。source-only
分支只包含對專案的原始檔。master
分支包含原始檔和完成的BazelWORKSPACE
和BUILD
檔案。獲取
source-only
分支中的檔案:cd ~/Desktop git clone -b source-only https://github.com/bazelbuild/examples
-
設定工作區
一個 工作空間 是包含一個或多個軟體專案中的原始檔,以及一個目錄
WORKSPACE
檔案,BUILD
是Bazel用來構建軟體的說明檔案。工作空間還可以包含指向輸出目錄的符號連結。Bazel本身對您在工作區中組織原始檔的方式沒有任何要求。
-
建立一個
WORKSPACE
檔案每個工作空間必須具有一個名為
WORKSPACE
位於頂級工作空間目錄中的文字檔案。此檔案可能為空,也可能包含對構建軟體所需的 外部依賴項 引用。 -
更新
WORKSPACE
檔案Bazel需要執行Android SDK 構建工具 並使用SDK庫來構建應用程式。這意味著您需要向
WORKSPACE
檔案中新增一些資訊,以便Bazel知道在哪裡找到它們。為其他平臺構建時,不需要執行此步驟。Bazel會自動從您環境中的設定中檢測Java,C ++和Objective-C編譯器的位置。將以下行新增到您的
WORKSPACE
檔案中:android_sdk_repository( name = "androidsdk" )
這將使用
ANDROID_HOME
環境變數引用的Android SDK ,並自動檢測安裝在該位置的最高API級別和最新版本的構建工具。或者,你可以明確地指定了Android SDK的位置,API級別,以及構建工具的版本通過包括使用
path
,api_level
和build_tools_version
屬性。您可以指定這些屬性的任何子集:android_sdk_repository( name = "androidsdk", path = "~/Android/sdk", api_level = 25, build_tools_version = "26.0.1" )
如果使用ndk還需要通過在
WORKSPACE
檔案中新增以下規則告訴Bazel在哪裡找到它:android_ndk_repository( name = "androidndk" )
-
建立一個
BUILD
檔案一個
BUILD
檔案 是描述一組輸入輸出之間的關係的文字檔案,新增android_library規則
一個
BUILD
檔案包含Bazel的幾種不同型別的指令。最重要的型別是 構建規則 ,它告訴Bazel如何從一組原始檔或其他依賴項構建最終軟體輸出。Bazel提供了兩種生成規則,
android_library
並且android_binary
,首先使用android_library
規則告訴Bazel如何從應用程式原始碼和資原始檔構建 Android庫模組 。然後,您將使用android_binary
規則告訴它如何構建Android應用程式包。將以下內容新增到您的
BUILD
檔案中:android_library( name = "activities", srcs = glob(["src/main/java/com/google/bazel/example/android/activities/*.java"]), custom_package = "com.google.bazel.example.android.activities", manifest = "src/main/java/com/google/bazel/example/android/activities/AndroidManifest.xml", resource_files = glob(["src/main/java/com/google/bazel/example/android/activities/res/**"]), )
,
android_library
構建規則包含一組屬性,這些屬性指定Bazel從原始檔構建庫模組所需的資訊。另請注意,規則的名稱是activities
。您將使用此名稱作為規則的依賴項被android_binary
引用。新增android_binary規則
該
android_binary
規則.apk
為您的應用構建Android應用程式包(檔案)。將以下內容新增到構建檔案中:
android_binary( name = "android", custom_package = "com.google.bazel.example.android", manifest = "src/main/java/com/google/bazel/example/android/AndroidManifest.xml", resource_files = glob(["src/main/java/com/google/bazel/example/android/res/**"]), deps = [":activities"], )
此處,該
deps
屬性引用activities
您新增到上述BUILD
檔案的規則的輸出。這意味著,當Bazel構建此規則的輸出時,它首先檢查activities
庫規則的輸出是否已構建並且是最新的。如果沒有,它會構建它,然後使用該輸出來構建應用程式包檔案。 -
構建應用程式
輸入以下內容來構建示例應用程式:
bazel build //android:android
該
build
子命令指示巴澤勒構建跟蹤目標。目標被指定為BUILD
檔案內部的構建規則的名稱,以及相對於工作區目錄的程式包路徑。請注意,有時可以省略包路徑或目標名稱,具體取決於命令列中的當前工作目錄和目標名稱。Bazel現在啟動並構建示例應用程式。在構建過程中,其輸出將顯示類似於以下內容:
INFO: Found 1 target... Target //android:android up-to-date: bazel-bin/android/android_deploy.jar bazel-bin/android/android_unsigned.apk bazel-bin/android/android.apk INFO: Elapsed time: 7.237s, Critical Path: 5.81s
-
執行該應用程式
bazel mobile-install
命令從命令列將應用程式部署到連線的Android裝置或模擬器 。此命令使用Android Debug Bridge(adb
)與裝置通訊。您必須將裝置設定為在部署之前adb
按照 Android Debug Bridge中 的說明 使用。您還可以選擇在Android Studio中包含的Android模擬器上安裝該應用。在執行以下命令之前,請確保模擬器正在執行。輸入以下內容:
bazel mobile-install //android:android
Android規則
描述了可用於使用Bazel構建和測試Android應用程式的規則
android_binary
屬性 | 描述 |
---|---|
name | 規則的唯一名稱 |
deps | 要連結到二進位制目標的其他庫的列表。允許庫型別是: android_library , java_library 與 .so |
srcs | 原始檔列表 |
aapt_version | aapt版本。 aapt_version = "aapt" :使用aapt預設值;aapt_version = "aapt2":使用aapt2。這是新的資源打包系統,可提供改進的增量資源處理,更小的apks等。 |
assets | 要打包的資產列表 |
custom_package | 包名 |
debug_key | apk簽名檔案 |
dex_shards | dex的分片數。這使得dex的速度更快,但代價是應用安裝和啟動時間。二進位制檔案越大,應使用的分片越多。25是開始試驗的好價值。 |
dexopts | 生成classes.dex時dx工具的附加命令列標誌 |
main_dex_list | 這些類檔案定義的類放在主classes.dex中 |
manifest | Android清單檔案的名稱 AndroidManifest.xml |
multidex | 是否將程式碼拆分為多個dex檔案 |
proguard_specs | 用作Proguard規範的檔案 |
shrink_resources | 是否執行資源縮減。二進位制檔案未使用的資源將從APK中刪除。 |
aar_import
屬性 | 描述 |
---|---|
name | 此規則的唯一名稱。 |
aar | aar檔案 |
例子:
aar_import( name =“google-vr-sdk”, aar =“gvr-android-sdk / libraries / sdk-common-1.10.0.aar”, ) android_binary( name =“app”, manifest =“AndroidManifest.xml”, srcs = glob([“**。java”]), deps = [“:google-vr-sdk”], )
android_library
主要規則同android_binary
android_ndk_repository
配置Bazel使用Android NDK。目前支援NDK版本10到16。
還需要配置 android_sdk_repository
到您的 WORKSPACE
檔案中
例子
android_ndk_repository( name =“androidndk”, )
上面的示例將從您的Android NDK中找到 $ANDROID_NDK_HOME
並檢測它支援的最高API級別。
android_ndk_repository( name =“androidndk”, path =“./android-ndk-r12b”, api_level = 24, )
上面的示例將使用位於工作區內的 ./android-ndk-r12b
#BUILD cc_library( name =“jni”, srcs = [“jni.cc”], deps = [“@androidndk //:cpufeatures”], )
android_sdk_repository
配置Bazel使用本地Android SDK來支援構建Android目標。
為Bazel設定Android SDK的最低要求是
android_sdk_repository
在
WORKSPACE
檔案中新增名為“androidsdk” 的規則,並將
$ANDROID_HOME
環境變數設定為Android SDK的路徑。預設情況下,Bazel將使用安裝在Android SDK中的最高Android API級別和構建工具版本。
android_sdk_repository( name =“androidsdk”, )
為了確保重現建立的 path
, api_level
並且 build_tools_version
屬性可以設定為特定值。如果Android SDK沒有安裝指定的API級別或構建工具版本,則構建將失敗。
android_sdk_repository( name =“androidsdk”, path =“./ sdk”, api_level = 19, build_tools_version =“25.0.0”, )
Mobile-install
用於構建.apk的傳統Android工具鏈需要許多單片,順序步驟,所有這些都必須完成才能構建Android應用程式。在大型專案中,等待五分鐘建立單線改變並不罕見。
bazel mobile-install
通過結合使用更改修剪,工作分片和Android內部的巧妙操作,可以更快地為Android進行迭代開發,所有這些都不會更改任何應用程式的程式碼。
傳統應用安裝的問題
我們發現了構建Android應用程式的以下瓶頸:
- 預設情況下,“dx”在構建中,並不知道如何重用以前構建的工作:它會再次重新dex每個方法,即使只更改了一個方法。
- 將資料上傳到裝置。adb不使用USB 2.0連線的全部頻寬,較大的應用程式可能需要花費大量時間上傳。整個應用程式上傳,即使只有小部分發生了變化,例如資源或單個方法,因此這是一個主要的瓶頸。
bazel mobile-install
做出以下改進:
- Sharded dexing。在構建應用程式的Java程式碼之後,Bazel將類檔案分片為大致相等大小的部分,並
dx
在它們上單獨呼叫。dx
在自上次構建後未更改的分片上未呼叫。 - 增量檔案傳輸。Android資源,.dex檔案和本機庫將從主.apk中刪除,並存儲在單獨的移動安裝目錄下。這使得可以獨立更新程式碼和Android資源,而無需重新安裝整個應用程式。因此,傳輸檔案所花費的時間更少,只有已更改的.dex檔案才會在裝置上重新編譯。
- 從.apk外部載入應用程式的部分內容。一個小的存根應用程式放入.apk中,從裝置上的移動安裝目錄載入Android資源,Java程式碼和本機程式碼,然後將控制權轉移到實際的應用程式
Sharded dexing
Sharded dexing相當簡單:一旦構建了.jar檔案, 工具 會將它們分割成大小相等的單獨.jar檔案,然後呼叫 dx
自上一次構建以來更改的檔案。確定dex的哪些分片不是特定於Android的邏輯:它只使用Bazel的一般更改修剪演算法。
第一個版本的分片演算法只是按字母順序排序.class檔案,然後將列表切割成相等大小的部分,但事實證明這是次優的:如果新增或刪除了一個類(甚至是巢狀的或匿名的),它會導致所有類按字母順序移動一個,從而導致再次刪除這些分片。因此,我們決定不分割單個類,而是使用Java包。當然,如果新增或刪除新包,這仍然會導致許多分片變形,但這比新增或刪除單個類要少得多。
分片數由BUILD檔案控制(使用 android_binary.dex_shards
屬性)。在一個理想的世界中,Bazel會自動確定有多少分片是最好的,但Bazel目前必須知道在執行任何分片之前的動作集(即在構建期間要執行的命令),因此它無法確定最佳分片數,因為它不知道應用程式中最終會有多少Java類。一般來說,分片越多,構建和安裝就越快,但app啟動速度變慢,因為動態連結器必須做更多的工作。通常在10到50個碎片之間。
增量檔案傳輸
構建應用程式後,下一步是安裝它,最好儘可能少。安裝包括以下步驟:
adb install
第一步沒有太多增量:應用程式是否已安裝。Bazel目前依賴於使用者來指示它是否應該通過 --incremental
命令列選項執行此步驟,因為它無法在所有情況下確定是否有必要。
在第二步中,將構建中的應用程式檔案與裝置上清單檔案進行比較,該檔案列出裝置上的應用程式檔案及其校驗和。將任何新檔案上載到裝置,更新任何已更改的檔案,並從裝置中刪除已刪除的所有檔案。如果清單不存在,則假定需要上載每個檔案。
請注意,可以通過更改裝置上的檔案來欺騙增量安裝演算法,但不能清除清單中的校驗和。我們可以通過計算裝置上檔案的校驗和來防範這種情況,但這被認為不值得增加安裝時間。
效能
通常, bazel mobile-install
只需稍加更改即可構建和安裝大型應用程式,速度提高4倍到10倍。我們為一些Google產品計算了以下數字:
[圖片上傳失敗...(image-62a112-1539661819363)]
AndroidStudio整合
無
NDK
要為Android構建C ++,只需將 cc_library
依賴項新增到您的 android_binary
或 android_library
規則中。
給定Android應用程式的以下BUILD檔案:
# In <project>/app/src/main/BUILD.bazel cc_library( name = "jni_lib", srcs = ["cpp/native-lib.cpp"], ) android_library( name = "lib", srcs = ["java/com/example/android/bazel/MainActivity.java"], resource_files = glob(["res/**/*"]), custom_package = "com.example.android.bazel", manifest = "LibraryManifest.xml", deps = [":jni_lib"], ) android_binary( name = "app", deps = [":lib"], manifest = "AndroidManifest.xml", )
此BUILD檔案生成以下目標圖:

image
如何工作
Bazel 在構建目標時經歷了 三個步驟 :
- 在 載入 階段,Bazel會解析
BUILD
正在構建的目標BUILD
檔案以及檔案傳遞依賴的所有檔案。 - 在 分析 階段,Bazel構建了構建指定目標所需的操作圖。
- 在 執行 階段,Bazel執行這些操作。
在分析過程中,Bazel為每個正在構建的目標及其傳遞依賴性執行規則。每個規則都會生成並記錄它依賴的所有操作。
Android資源
Android庫構建過程與普通Java構建過程的不同之處是Android 資源 。資源是任何不是程式碼的東西 - 字串,影象,佈局 等等 。
Bazel生成 R.java 檔案(以及相關 檔案 R.class
和 R.txt
檔案)以包含對可用資源的引用。這些R檔案包含開發人員可用於引用其資源的整數 資源ID 。在應用程式中,每個資源ID都指向一個唯一資源。
用 aapt
和 aapt2
處理資源

image
Bazel支援使用原始Android資源處理器 aapt
或新版本處理資源 aapt2
。這兩種方法基本相似,但有一些重要的區別。
Bazel經歷了三個步驟來構建資源。
首先,Bazel序列化定義資源的檔案。在 aapt
管道中, 解析 操作將有關資源的資訊序列化為 symbols.bin
檔案。在 aapt2
管道中,動作呼叫 aapt2 編譯 命令,該命令將資訊序列化為 aapt2
使用的格式。
接下來,序列化資源與從依賴項繼承的類似序列化資源 合併 。識別具有相同名稱的資源之間的衝突,並且如果可能,在此合併期間解決。 values
資原始檔的內容通常是顯式合併的。對於其他檔案,如果來自目標或其依賴項的資源具有相同的名稱和限定符,則會比較檔案的內容,如果它們不同,則會生成警告,並選擇使用最後提供的資源。
最後,Bazel檢查目標的資源是否合理並將其打包。在 aapt
中呼叫 aapt
package 命令,在 aapt2
中呼叫 aapt2link 命令。任何格式錯誤的資源或對不可用資源的引用都會導致失敗,如果未遇到任何故障,生成 R.java
檔案和資源APK。
Android庫

image
一個 android_library
規則是一個非常簡單的規則,建立並組織一個Android庫在另一個Android的目標使用。在分析階段,基本上生成了三組操作:
首先,Bazel處理庫的資源, 如上所述 。
接下來是庫的實際編譯。這主要是使用常規的Bazel Java編譯路徑。最大的區別是 R.class
資源處理中生成的 檔案也包含在編譯路徑中(但不會被使用者繼承,因為需要為每個目標重新生成R檔案)。
最後,Bazel對編譯的程式碼做了一些額外的工作:
-
編譯後的
.class
替換隻有java8才支援的屬性。 -
處理後的
.class
檔案轉換.dex
-
hjar
使用.java
原始檔生成一個jar
檔案。方法體和私有欄位將被刪除,依賴時將依賴於此庫.jar
檔案。由於這些jar只包含庫的介面,因此當私有欄位或方法實現發生更改時,不需要重新編譯依賴庫(只有在庫的介面更改時才需要重新編譯它們),這樣可以加快構建速度。
Android二進位制檔案

image
對於二進位制檔案,三個主要的資源處理操作(解析,合併和驗證)都合併為一個大型操作。在庫中,Java編譯可以在驗證仍在進行時啟動,但在二進位制檔案中,由於我們需要驗證的最終資源ID,因此我們無法利用類似的並行化。由於建立更多操作總是會帶來很小的成本,並且沒有可用的並行化來彌補它,因此單個資源處理操作實際上更有效。
在二進位制檔案中,Java程式碼被編譯,刪除和dexed,就像在庫中一樣。但是,之後, .dex
二進位制 .dex
檔案與依賴項中的檔案合併在一起。
Bazel還將來自依賴項的已編譯 C
和 C++
本機程式碼連結到 .so
合併的 .dex
檔案, .so
檔案和資源APK都組合在一起構建一個初始的二進位制APK,然後進行 zipaligned 以生成一個未簽名的APK。最後,使用二進位制檔案的除錯金鑰對未簽名的APK進行簽名,以生成簽名的APK。
合併的 .dex
檔案與資源APK組合以構建初始二進位制APK,然後將其 壓縮 以生成未簽名的APK。最後,使用二進位制檔案的除錯金鑰對未簽名的APK進行簽名,以生成簽名的APK。
ProGuarded Android二進位制檔案

image
Bazel支援 針對目標執行 ProGuard android_binary
以 優化它們並減小其尺寸 。
ProGuarding使用一個 deploy.jar
檔案,一個 .jar
包含所有二進位制Java位元組碼的檔案,由二進位制檔案的desugared(但不是dexed) .class
檔案以及二進位制檔案的傳遞執行時 .jar
檔案建立。(此 deploy.jar
檔案是所有 android_binary
目標的輸出,但在沒有ProGuarding的構建中它不起重要作用。)
基於一系列Proguard規範(來自二進位制及其傳遞依賴性)的資訊,ProGuard進行了多次傳遞 deploy.jar
,以優化程式碼,刪除未使用的方法和欄位,並縮短和混淆方法和欄位的名稱剩下的。除了生成的proguarded .jar
檔案之外,ProGuard還會輸出從舊名稱到新名稱的方法和欄位的對映。
外部依賴
Bazel專案
想使用bazel專案,您可以使用 local_repository
, git_repository
或 http_archive
從本地檔案系統中,一個Git倉庫或下載。
例如,假設您正在處理一個專案, my-project/
並且您希望依賴同事的專案 coworkers-project
。這兩個專案都使用Bazel,因此您可以將同事的專案新增為外部依賴項,然後使用您的同事從您自己的BUILD檔案中定義的任何目標。您可以將以下內容新增到 my_project/WORKSPACE
:
local_repository( name = "coworkers_project", path = "/path/to/coworkers-project", )
如果您的同事有目標 //foo:bar
,您的專案可以將其稱為 @coworkers_project//foo:bar
。
非Bazel專案
字首 new_
(例如 new_local_repository
, new_git_repository
和 new_http_archive
)允許您建立不使用Bazel的目標。
例如,假設您正在處理一個專案 my-project/
,並且您希望依賴於您的同事的專案, coworkers-project/
。您的同事的專案用於 make
構建,但您希望依賴於它生成的.so檔案之一。為此,請將以下內容新增到 my_project/WORKSPACE
:
new_local_repository( name = "coworkers_project", path = "/path/to/coworkers-project", build_file = "coworker.BUILD", )
build_file
指定要覆蓋現有專案的BUILD檔案,例如:
cc_library( name = "some-lib", srcs = glob(["**"]), visibility = ["//visibility:public"], )
然後,您可以依賴 @coworkers_project//:some-lib
專案的BUILD檔案。
外部包裝
使用規則 maven_jar
(以及可選的規則 maven_server
)從Maven儲存庫下載jar並使其可用作Java依賴項。
maven_jar(name,artifact,repository,server,sha1,sha1_src)
從Maven下載jar並使其可用作Java依賴項。請注意,maven_jar名稱用作儲存庫名稱,因此受限於管理工作空間名稱的規則:它不能包含破折號和點(有關確切規範,請參閱 有關工作空間名稱的文件 )。按照慣例,maven_jar名稱應該與工件名稱匹配,用下劃線替換非法字元並且不使用版本。例如, artifact = "org.apache.commons:commons-lang3:3.4"
應該具有 的規則 name = "org_apache_commons_commons_lang3"
。
例子
假設當前的repostory包含一個需要依賴Guava的java_library目標。使用Maven,這個依賴項將在pom.xml檔案中定義為:
<依賴性> <的groupId> com.google.guava </的groupId> <artifactId的>番石榴</ artifactId的> <版本> 18.0 </版本> </依賴性>
使用Bazel,將以下行新增到WORKSPACE檔案中:
maven_jar( name =“com_google_guava_guava”, artifact =“com.google.guava:guava:18.0”, sha1 =“cce0823396aa693798f8882e64213b1772032b09”, sha1_src =“ad97fe8faaf01a3d3faacecd58e8fa6e78a973ca”, )
目標可以指定 @com_google_guava_guava//jar
依賴於此jar的依賴項。
引數
屬性 | |
---|---|
name |
Name; required 此規則的唯一名稱。 |
artifact |
String; optional 使用 Maven座標 描述Maven工件 。這些描述的形式為<groupId>:<artifactId>:<version>,請參閱 下面的文件 以獲取示例。 |
repository |
String; optional 用於從中獲取jar的Maven儲存庫的URL。這個或者 server 可以指定。預設為Maven Central(“central.maven.org”)。 |
server |
String; optional 用於此工件的maven_server。這個或者 repository 可以指定。 |
sha1 |
String; optional 所需jar的SHA-1雜湊。如果下載的jar與此雜湊不匹配,則Bazel將出錯。 由於遠端檔案可以更改,因此省略SHA-1是一種安全風險。 最多省略此欄位將使您的構建非密封。可以選擇使開發更容易,但應在發貨前進行設定。 |
sha1_src |
String; optional 所需jar原始檔的SHA-1雜湊。 |
maven_server
maven_server(name,settings_file,url)
如何訪問Maven儲存庫。
這是來自pom.xml檔案的<repository>定義和settings.xml檔案中的<server>定義的組合。
運用 maven_server
maven_jar
規則可以 maven_server
在其 server
欄位中指定a的名稱。例如,假設我們有以下WORKSPACE檔案:
maven_jar( name =“junit”, artifact =“junit:junit-dep:4.10”, server =“my_server”, ) maven_server( name =“my_server”, url =“http://intranet.mycorp.net” )
這指定應使用〜/ .m2 / settings.xml中的身份驗證資訊(具體地說,具有id的伺服器的設定)從 http://intranet.mycorp.net 下載junit my_server
指定預設伺服器
如果 maven_server
使用 name
“預設” 建立一個,它將用於任何 maven_jar
未指定 server
nor的 repository
。如果沒有 maven_server
命名預設值,則預設將從Maven Central獲取而不啟用身份驗證。
引數
屬性 | |
---|---|
name |
Name; required 此規則的唯一名稱。 |
settings_file |
String; optional settings.xml檔案的路徑。用於測試。如果未指定,則預設使用 $M2_HOME/conf/settings.xml 全域性設定和 $HOME/.m2/settings.xml 使用者設定。 |
url |
String; optional 用於訪問伺服器的URL。例如,Maven Central(預設情況下,不需要定義)將被指定為 url = "http://central.maven.org/maven2/" 。 |