遷移至平台

回報問題 查看來源

Bazel 提供精細的支援,可用於建立多架構和跨編譯建構作業的平台工具鍊

本頁面摘要說明這項支援的狀態。

另請參閱:

狀態

C++

設定 --incompatible_enable_cc_toolchain_resolution 時,C++ 規則會使用平台選取工具鍊。

也就是說,您可以使用以下項目設定 C++ 專案:

bazel build //:my_cpp_project --platforms=//:myplatform

而不是舊版:

bazel build //:my_cpp_project` --cpu=... --crosstool_top=...  --compiler=...

根據預設,Bazel 7.0 會啟用這項功能 (#7260)。

如要使用平台測試 C++ 專案,請參閱遷移專案設定 C++ 工具鍊

Java

Java 規則會使用平台選取工具鍊。

這會取代舊版旗標 --java_toolchain--host_java_toolchain--javabase--host_javabase

詳情請參閱 Java 和 Bazel

Android

設定 --incompatible_enable_android_toolchain_resolution 時,Android 規則會使用平台選取工具鍊。

也就是說,您可以使用下列資訊設定 Android 專案:

bazel build //:my_android_project --android_platforms=//:my_android_platform

而不是使用 --android_crosstool_top--android_cpu--fat_apk_cpu 等舊版旗標。

根據預設,Bazel 7.0 會啟用這項功能 (#16285)。

如要使用平台測試 Android 專案,請參閱遷移專案

蘋果

Apple 規則不支援平台,且尚未排定支援時間。

您仍可透過平台對應對 Apple 版本 (例如混用 Apple 規則和純 C++ 進行建構) 使用平台 API。

其他語言

如果您擁有語言規則集,請參閱遷移規則集,瞭解如何新增支援。

背景

導入平台工具鍊,以標準化軟體專案指定不同架構和跨編譯的方式。

上述觀察結果是我們觀察到,語言維護人員以臨時、不相容的方式這麼做。舉例來說,C++ 規則會使用 --cpu--crosstool_top 宣告目標 CPU 和工具鍊。這兩種方式都未正確建立「平台」模型。這會造成尷尬及錯誤的版本。

Java、Android 和其他語言會為了類似目的而發展出各自的標記,且不會彼此互動。這使得跨語言建構令人困惑和複雜。

Bazel 適用於大型、多語言、多平台的專案。這些概念需要更周全的支援服務,包括明確的標準 API。

需要遷移

升級至新的 API 需要進行兩項操作:發布 API,以及升級規則邏輯才能使用該 API。

第一種作業是完成,第二項則是持續進行。這包括確認已定義語言特定平台和工具鍊、語言邏輯透過新 API 讀取工具鍊,而非透過 --crosstool_top 等舊標記,並且選擇 config_setting 選擇新的 API,而非舊標記。

這項工作相當簡單,但需要為每種語言分別花費不同的心力,並對專案擁有者發出公平警示,測試即將實施的變更。

因此,我們目前正在進行遷移作業。

目標

只要所有使用下列表單建構的專案,即表示這項遷移作業已完成:

bazel build //:myproject --platforms=//:myplatform

這意味著:

  1. 專案規則會為「//:myplatform」選擇合適的工具鍊。
  2. 您的專案依附元件會為 //:myplatform 選擇合適的工具鍊。
  3. //:myplatform 會參照 CPUOS 以及其他與語言無關的一般屬性的常見宣告
  4. 所有相關 select() 都與 //:myplatform 相符。
  5. //:myplatform 是在清楚且易於存取的位置定義:如果平台專屬於您的專案,或是所有專案的使用者,可在專案的存放區中找到該平台

--cpu--crosstool_top--fat_apk_cpu 等舊標記會在安全的情況下立即淘汰並移除。

最終,這將成為設定架構的「唯一」方法。

遷移專案

如果您使用支援平台的語言進行建構,您的版本應可使用如下叫用:

bazel build //:myproject --platforms=//:myplatform

如要瞭解精確的詳細資料,請參閱「狀態」和所用語言的說明文件。

如果語言需要旗標才能啟用平台支援,您還需要設定該標記。詳情請參閱「狀態」一節。

建立專案時,您必須檢查下列項目:

  1. //:myplatform」必須存在。由於不同的專案會指定不同的機器,因此專案擁有者通常有責任定義平台。請參閱「預設平台」一節。

  2. 要使用的工具鍊必須存在。如果使用圖庫工具鍊,語言擁有者應提供註冊方式的操作說明。編寫自己的自訂工具鍊時,您必須在 WORKSPACE--extra_toolchainsregister

  3. select()設定轉換必須正確解析。請參閱 select()轉換

  4. 如果您的版本混用支援和不支援平台的語言,您可能需要平台對應,才能協助舊版語言與新的 API 搭配使用。詳情請參閱「平台對應」一文。

如果問題仍無法解決,請聯絡我們尋求協助。

預設平台

專案擁有者應定義明確的平台,描述要做為建構目標的架構。接著,這類動作會透過 --platforms 觸發。

如未設定 --platforms,Bazel 會預設為代表本機建構機器的 platform。這是在 @local_config_platform//:host 自動產生,因此不需要明確定義。這會將本機電腦的 OSCPU 對應至 @platforms 中宣告的 constraint_value

select()

專案可以針對 constraint_value 目標進行 select(),但無法完成平台。這是刻意設計,因此 select() 會盡可能支援各種機器。具有 ARM 特定來源的程式庫應支援「所有」採用 ARM 的機器,除非系統沒有明確限制。

如要選取一或多個 constraint_value,請使用:

config_setting(
    name = "is_arm",
    constraint_values = [
        "@platforms//cpu:arm",
    ],
)

這相當於在 --cpu 上傳統選取的方式:

config_setting(
    name = "is_arm",
    values = {
        "cpu": "arm",
    },
)

詳情請參閱這篇文章

--cpu--crosstool_top 等上的 select 無法理解 --platforms。將專案遷移至平台時,您必須將專案轉換為 constraint_values,或使用平台對應在遷移期間支援這兩種樣式。

轉場

Starlark 轉場效果會變更建構圖中部分的旗標。如果專案使用的轉換設定了 --cpu--crossstool_top 或其他舊版旗標,讀取 --platforms 的規則不會看到這些變更。

將專案遷移至平台時,您必須將 return { "//command_line_option:cpu": "arm" } 等變更轉換為 return { "//command_line_option:platforms": "//:my_arm_platform" },或使用平台對應,才能在遷移期間同時支援這兩種樣式。

遷移規則組合

如果您擁有規則集,並想支援平台,請按照下列步驟操作:

  1. 使用工具鍊 API 讓規則邏輯解析工具鍊。請參閱工具鍊 API (ctx.toolchains)。

  2. 選用:定義 --incompatible_enable_platforms_for_my_language 旗標,讓規則邏輯在遷移測試期間透過新 API 或 --crosstool_top 等舊標記以替代方式解析工具鍊。

  3. 定義組成平台元件的相關屬性。請參閱常見平台屬性

  4. 定義標準工具鍊,並讓使用者透過規則的註冊操作說明存取這些工具 (詳細資料)

  5. 確保 select()設定轉換支援平台。這是最大的挑戰。多語言專案特別具有挑戰性 (如果所有語言無法讀取 --platforms,就可能失敗)。

如果您需要搭配不支援平台的規則,可能會需要平台對應來消除差異。

常見平台屬性

OSCPU 等常見的跨語言平台屬性應在 @platforms 中宣告。這樣有助於促進共用、標準化和跨語言相容性。

您的規則專屬的屬性應在規則的存放區中宣告。如此可讓您清楚掌握規則負責的特定概念。

如果您的規則使用自訂用途 OS 或 CPU,則應在規則存放區中宣告這些 OS 或 CPU,而非使用 @platforms

平台對應

「平台對應」是一項臨時 API,可讓平台感知邏輯在相同的版本中混合使用舊版邏輯。這是一項鈍器工具,只是目的是讓不同遷移時間範圍能夠順利相容。

平台對應是 platform() 與一組對應舊版標記 (或反向標記) 的對應。例如:

platforms:
  # Maps "--platforms=//platforms:ios" to "--cpu=ios_x86_64 --apple_platform_type=ios".
  //platforms:ios
    --cpu=ios_x86_64
    --apple_platform_type=ios

flags:
  # Maps "--cpu=ios_x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
  --cpu=ios_x86_64
  --apple_platform_type=ios
    //platforms:ios

  # Maps "--cpu=darwin_x86_64 --apple_platform_type=macos" to "//platform:macos".
  --cpu=darwin_x86_64
  --apple_platform_type=macos
    //platforms:macos

Bazel 用來確保所有設定 (平台式和舊版) 都能在整個建構作業中一致套用,包括透過轉換

根據預設,Bazel 會讀取工作區根目錄中 platform_mappings 檔案的對應內容。您也可以設定 --platform_mappings=//:my_custom_mapping

詳情請參閱平台對應設計

API 審查

platform 是一組 constraint_value 目標

platform(
    name = "myplatform",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:arm",
    ],
)

constraint_value 屬於機器屬性。相同「種類」的值會歸入共同的 constraint_setting 底下:

constraint_setting(name = "os")
constraint_value(
    name = "linux",
    constraint_setting = ":os",
)
constraint_value(
    name = "mac",
    constraint_setting = ":os",
)

toolchainStarlark 規則。其屬性可宣告語言的工具 (例如 compiler = "//mytoolchain:custom_gcc")。其提供者會將這項資訊傳送至需要使用這些工具建構的規則。

工具鍊會宣告可指定 (target_compatible_with = ["@platforms//os:linux"]) 的機器 constraint_value,以及其工具可執行的機器 (exec_compatible_with = ["@platforms//os:mac"])。

建構 $ bazel build //:myproject --platforms=//:myplatform 時,Bazel 會自動選取可在建構機器上執行的工具鍊,並為 //:myplatform 建構二進位檔。這就是所謂的「工具鍊解析」

您可以透過 register_toolchainsWORKSPACE 中註冊可用的工具鍊組合,或是使用 --extra_toolchains 在指令列註冊。

詳情請參閱這裡的說明。

問題

如需關於遷移時間軸的一般支援和問題,請聯絡 bazel-discuss 或適當規則的擁有者。

如要討論平台/工具鍊 API 的設計和發展,請與 bazel-dev 聯絡。

另請參閱