遷移至平台

回報問題 查看原始碼

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 規則會使用平台來選取工具鍊。

也就是說,您可以使用:

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 (而非 --crosstool_top 等舊旗標) 讀取工具鍊,並在新 API 中選取 config_setting,而非舊旗標。

這項工作相當簡單,但需要針對每種語言投入不同的工作,並向專案擁有者測試即將實施的變更。

因此,我們進行遷移作業。

目標

所有專案均以下列格式建構時,即代表這項遷移作業已完成:

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. 您要使用的工具鍊必須存在。如果使用圖庫工具鍊,語言擁有者應提供註冊操作說明。如要編寫自己的自訂工具鍊,您必須在 MODULE.bazel 檔案中或使用 --extra_toolchains register這些工具鍊。

  3. select()設定轉換必須正確解析。請參閱「select()」和「轉場效果」。

  4. 如果您的建構混合了支援且不支援平台的語言,您可能需要平台對應,以便舊版語言支援新的 API。詳情請參閱「平台對應」。

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

預設平台

專案擁有者應定義明確的平台,說明要建構的目標架構。接著,這些變數會由 --platforms 觸發。

如未設定 --platforms,Bazel 會預設為代表本機建構機器的 platform。這項資訊是在 @platforms//host (別名為 @bazel_tools//tools:host_platform) 自動產生,因此無需明確定義。這會將本機電腦的 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,您應該在規則存放區和 @platforms 中宣告這些 OS 或 CPU。

平台對應

平台對應是暫時性的 API,可將平台感知邏輯與同一版本中的舊版邏輯混合。這項實驗性工具只會用來在不同的遷移時間範圍內順暢地不相容。

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

platforms:
  # Maps "--platforms=//platforms:ios" to "--ios_multi_cpus=x86_64 --apple_platform_type=ios".
  //platforms:ios
    --ios_multi_cpus=x86_64
    --apple_platform_type=ios

flags:
  # Maps "--ios_multi_cpus=x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
  --ios_multi_cpus=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 審查

platformconstraint_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 建構二進位檔。這就是所謂的工具鍊解析

您可以在 MODULE.bazel 檔案中使用 register_toolchains 或利用 --extra_toolchains 在指令列中註冊可用的工具鍊組合。

詳情請參閱這裡

問題

如需有關遷移時程的一般支援和疑問,請與 bazel-discuss 聯絡,或負責相應規則的擁有者。

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

另請參閱