遷移至平台

回報問題 查看來源

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 規則不支援平台,且尚未排定支援時程。

您仍可透過平台對應,將平台 API 與 Apple 版本搭配使用 (例如同時使用 Apple 規則和純 C++ 建構時)。

其他語言

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

背景

我們推出平台工具鍊,將軟體專案鎖定不同架構及跨編譯的方式標準化。

這個觀察結果是,語言維護人員曾以不相容且不相容的方式執行此作業,因此產生了這個現象。舉例來說,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. 您要使用的工具鍊必須存在。如果使用圖庫鏈,語言擁有者應提供註冊操作說明。如要編寫自己的自訂工具鍊,您必須在 WORKSPACEregister,或使用 --extra_toolchains

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

  4. 如果您的版本混合了支援及不支援平台的語言,您可能需要建立平台對應,才能讓舊版語言與新的 API 搭配運作。詳情請參閱平台對應

如果問題仍無法解決,請聯絡支援團隊。

預設平台

專案擁有者應明確定義平台,說明想要為其建構的架構。然後透過 --platforms 觸發這些動作。

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

select()

專案可以select()針對目標constraint_value目標完成,但無法針對整個平台。這是刻意的設定,因此 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,則應在規則的存放區與 @platforms 中宣告這些 OS。

平台對應

平台對應是暫時性的 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",
)

toolchain星形規則。其屬性會宣告語言工具 (例如 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 聯絡。

另請參閱