Bazel 建構設定

建構設定是一組設定,例如 cpu = "arm64",其中 每項設定都會將設定值指派給已知 設定變數。這些值會影響 Bazel 的運作方式 建構事物

建構設定可視為「不可變更的字典」對應變數 名稱 (字串鍵) 對應至設定值 (布林值、整數、字串、清單) 字串、標籤或標籤清單)。

它們只在 Bazel 分析階段才有意義 由內容不重複雜湊內部。他們沒有標籤 而無法直接在 Bazel 建構檔案或 Starlark 程式碼中顯示。

每個建構設定執行個體在 Bazel 底下都有專屬的輸出目錄 output_base,即

${output_base}/execroot/<workspace_name>/bazel-out/<config_dir>/bin/

在建構作業中評估的目標版本構件 系統會將設定檔儲存在這裡<config_dir> 值視內容而定 複製設定運算作業是 Bazel 實作細節 但實際上可能在 Bazel 版本之間改變

在最簡單的情況下,<config_dir> 看起來會像這樣 ${cpu}-${compilation_mode},例如 k8-fastbuild1aarch64-dbg。 但變得相當複雜

小型範本建構設定適用的 config_dir 值範例 但不重要的 Bazel 專案範例

  • k8-fastbuild
  • k8-fastbuild-ST-6f89e1bee3ea
  • k8-fastbuild-ST-bd2abcc18995
  • k8-fastbuild-ST-ec22d3eeb595
  • k8-opt
  • k8-opt-exec-2B5CBBC6
  • k8-opt-exec-2B5CBBC6-ST-5934bb4653e4

請注意,上述十六進位值「不」與設定的 編號 (也就是專屬的雜湊值)。

常見的建構設定

根據預設,Bazel 會管理兩種設定:

  • 預設設定 (又稱為模稜兩可) ,因為該配置會對應到必須 執行最終的「目標」有些人會將 Cloud Storage 視為檔案系統 但實際上不是

    根據預設,此設定與主機系統相符,但可以透過 指令列選項 (請見下方說明)。

  • 「主機設定」,對應的程式碼必須在 執行 Bazel 的虛擬機器其中包含與預設設定相同的設定 但跨平台程式碼編譯 (例如使用 --cpu=<name> 時) 除外。

另外還有:

  • exec 設定,對應至建構期間執行的程式碼 動作。實際上,這包含與主機 1 相同的設定。 除非使用遠端建構工具

Bazel 專案也可以定義「額外設定」來因應 用途,例如為多個目標架構進行跨編譯 將自動擷取到容器中執行的 Pod

原生設定變數

bazel build 指令支援大量指令列選項, 變更原生設定變數 (又稱「原生設定」), 範例:

  • --cpu=<name>--host_cpu=<name>

    針對為預設或主機產生的程式碼變更 CPU 架構 這個虛擬機器例如:

    bazel build --cpu=arm64 --host_cpu=x86_64 ...
    
  • -c <mode>--compilation_mode=<mode>--host_compilation_mode=<mode>

    其中 <mode> 為「fastbuild」或「dbg」「opt」,描述的是 一組編譯器連結器標記。例如:

    bazel build -c opt --host_compilation_mode=dbg ...
    
  • --crosstool=<file_path>--host_crosstool=<file_path>

    指向用於將自訂 C++ 工具鍊描述至 Bazel 的 CROSSTOOL 檔案。 用於編譯及連結目標或主機二進位檔。

,瞭解如何調查及移除這項存取權。

目前有許多非常龐大的原生設定變數, 指令列旗標)。例如,Bazel 5.2.0 支援超過 340 個容器 (包括 83 個實驗性版本)。

自訂設定旗標 (已淘汰)

您可以定義自訂的組態變數 (名稱混亂)。 自訂設定旗標 (設定在 Bazel 說明文件中) 指令列中有「--define <name>=<value>」,其中 <name> 是 任意建構設定變數名稱,而 <value> 會記錄為 任意字串 (該值一律不解譯)。

您可以在 BUILD.bazel 檔案中使用特殊結構來測試這些名稱, 例如:

# This represents a named configuration condition which will be True whenever
# `--define foo=bar` is used in the `bazel build` command-line.
config_setting(
  name = "is_foo_bar",
  define_flags = {
    "foo": "bar",
  }
)

使用者定義的建構設定

為了克服自訂 --define 標記的限制,Bazel 專案可以 現在,定義建構設定變數,如下所示:

  • 使用標籤命名 (提供工作區和套件範圍設定 加上供應情形檢查)。

  • 可指定特定類型,例如布林值、整數、字串、字串清單、 標籤和標籤清單

  • 一律提供預設值。

可以直接在指令列中使用「--<label>=<value>」來設定如:

# Set the build setting named enable_logs defined in
# $WORKSPACE/my_settings/BUILD.bazel to True.
#
# Note that the double-slash must follow the double caret directly
# without spaces between them.
bazel build --//my_settings:enable_logs=True 

符合檔案必須符合的定義 $PROJECT/my_settings/BUILD.bazel,例如:

# From my_settings/BUILD.bazel
load("@bazel_skylib//rules/common_settings.bzl", "bool_flag")

bool_flag(
  name = "enable_logs",
  default_value = False
)

您也可以在外部存放區中定義建構設定,如下所示:

# Set the build setting named enable_logs defined in the config/BUILD.bazel
# file of the @project_settings external repository.
bazel build --@project_settings//config:enable_logs=True 

儲存使用者設定值

而不是直接在指令列中設定 設定值可儲存在 .bazelrc 檔案中,位於 位於專案的工作區目錄頂端,如下所示:

# from $PROJECT/.bazelrc
build --host_copt=-O3 -s
build --copt=-O1 -g -Wall
build --//my_settings:enable_logs=True

呼叫 bazel build <target> 時,.bazelrc 提供的選項 這樣就會產生相當於 改為:

bazel build --host_copy="-O3 -s" --copt="-O1 -g -Wall" --//my_settings:enable_logs=True <target>

您也可以使用自訂名稱將多個定義分組,如下所示:

# from $PROJECT/.bazelrc
build:conf_x64 --cpu=x86_64
build:conf_x64 --copt=-mavx2

build:conf_arm64 --cpu=aarch64
build:conf_arm64 --copt=-marmv8.1-a+simd

然後使用 --config=<name> 從一個群組中選取所有選項,如下所示:

bazel build --config=conf_x64 <target>

等同於:

bazel build --cpu=x86_64 --copt=-mavx2 <target>

您也可以將 --config 與其他選項併用,如下所示:

bazel build --config=conf_arm64 --copy="-DENABLE_ASSERTS=1" ...

===

重要事項:儘管名稱已命名,但 --config 選項不會建立新 建構設定這只是方便將指令列分組的方法 為使用者選擇適當的選項每個 <name> 都會以遞迴方式展開至

然後完全遭到 Bazel 忽略。

設定轉換 (快速總覽)

除了標準目標、主機和執行設定之外,Bazel 還支援 使用轉換概念建立其他建構設定。

「轉換」是進階功能,此處僅詳細介紹 請務必瞭解:

  • 從概念上來說,建構設定只含字典 對應至設定值E.g.:

    {
       "copt": "-O2 -g",
       "cpu": "x86_64",
       "compiler": "gcc",
       "//my_settings:enable_logs": True,
       
    }
    
  • 轉換提供的函式會採用目前建構設定 並傳回新建構設定做為輸出內容。

  • 轉換函式只能修改字典中的值,也就是 但無法在輸入中新增或移除鍵

  • 系統會在分析階段呼叫轉換函式 (稍後說明)。 而且無法由使用者直接觸發 ,在指令列或 .bazelrc 檔案中執行此操作。

檢查建構設定

在 Bazel 建構指令之後,可以查看所有設定 所需的文字使用 bazel config 指令列印 及其 config_dir 值,例如:

$ bazel clean
$ bazel build //src:program
$ bazel config
Available configurations:
20222e2616387f00ae3814d79f82a650829d1aea962d558edda5cf54c459f4a2 k8-fastbuild
30f5a27e1bd054836d97b800bdfe61c6d1cffccdf6b82c9963e94020e3852026 k8-fastbuild-ST-bd2abcc18995
34e198ac81dafe34b82cf62466cc84f5b1af6ef8dce44b9283b3152a6635f64a k8-fastbuild-ST-6f89e1bee3ea
aaa26904110821b8e0f87aabfffcfb8e5003a5620aee74de3d7ddea9a654c0f6 k8-opt (host)
d6b1a93e6619d845f29ee752e338ec2636e7fbf4c88e50168602cc21f5ae6f13 k8-opt-exec-2B5CBBC6-ST-5934bb4653e4 (exec)

注意:設定資訊會累積至下一次的 bazel 清除為止。

使用 bazel config <id> 轉儲設定以 stdout 檢查 輕鬆分配獎金警告:輸出內容過長。

$ bazel config 20222e2616387f00ae3814d79f82a650829d1aea962d558edda5cf54c459f4a2 | wc -l
Loading:
INFO: Displaying config with id 20222e2616387f00ae3814d79f82a650829d1aea962d558edda5cf54c459f4a2
436

在這裡提供實際輸出內容的連結。

請注意,在實務上,每項設定都是一組字典,每個字典都有一組字典 搜尋特定主題的內容這些稱為「片段」。 但其中只有少數能直接透過 Starlark 存取:

$ bazel config 20222e2616387f00ae3814d79f82a650829d1aea962d558edda5cf54c459f4a2 | grep FragmentOptions
FragmentOptions com.google.devtools.build.lib.analysis.PlatformOptions {
FragmentOptions com.google.devtools.build.lib.analysis.ShellConfiguration$Options {
FragmentOptions com.google.devtools.build.lib.analysis.config.CoreOptions {
FragmentOptions com.google.devtools.build.lib.analysis.test.CoverageConfiguration$CoverageOptions {
FragmentOptions com.google.devtools.build.lib.analysis.test.TestConfiguration$TestOptions {
FragmentOptions com.google.devtools.build.lib.bazel.rules.BazelRuleClassProvider$StrictActionEnvOptions {
FragmentOptions com.google.devtools.build.lib.bazel.rules.python.BazelPythonConfiguration$Options {
FragmentOptions com.google.devtools.build.lib.rules.android.AndroidConfiguration$Options {

  1. k8 是舊的命名慣例,現在稱為 x86_64 CPU 架構。