遷移至平台

回報問題 查看來源 Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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 建構作業使用平台 API (例如,以 Apple 規則和純 C++ 混合建構時),方法是使用平台對應

其他語言

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

背景

我們導入了「平台」和「工具鍊」,以標準化軟體專案指定不同架構和交叉編譯的方式。

我們發現語言維護人員已採用不相容的臨時方式執行這項操作,因此受到啟發,舉例來說,C++ 規則會使用 --cpu--crosstool_top 宣告目標 CPU 和工具鍊。這兩者都無法正確模擬「平台」。這導致建構結果不正確,而且很奇怪。

Java、Android 和其他語言都為了類似用途發展出自己的旗標,但這些旗標互不相容。這使得跨語言建構變得複雜難懂。

Bazel 適用於大型、多語言、多平台專案。因此需要更完善地支援這些概念,包括明確的標準 API。

遷移需求

升級至新版 API 需要兩項作業:發布 API,以及升級規則邏輯以使用該 API。

第一個已完成,但第二個仍在進行中。這包括確保定義語言專屬平台和工具鍊、語言邏輯透過新 API (而非 --crosstool_top 等舊旗標) 讀取工具鍊,以及 config_settings 選取新 API (而非舊旗標)。

這項工作很簡單,但每種語言都需要付出不同的心力,而且專案擁有者必須先測試即將發生的變更,才能做好準備。

因此這項遷移作業會持續進行。

目標

當所有專案都使用表單建構時,遷移作業即完成:

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

這表示:

  1. 專案的規則會為 //:myplatform 選擇合適的工具鍊。
  2. 專案的依附元件會為 //:myplatform 選擇合適的工具鍊。
  3. //:myplatform 參照 常見宣告CPUOS 和其他與語言無關的通用屬性
  4. 所有相關 select()s 都正確符合 //:myplatform
  5. //:myplatform 定義在清楚易懂的位置:如果平台是專案專屬,則定義在專案的存放區中;如果平台是所有使用專案都能找到的通用位置,則定義在該位置

舊版旗標 (例如 --cpu--crosstool_top--fat_apk_cpu) 會在安全無虞時淘汰並移除。

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

遷移專案

如果您使用支援平台的語言建構,建構作業應該已可透過下列呼叫方式運作:

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

如需詳細資訊,請參閱「狀態」和您所用語言的說明文件。

如果啟用平台支援需要設定旗標,您也必須設定該旗標。詳情請參閱「狀態」

如要建構專案,請檢查下列項目:

  1. //:myplatform」必須存在。一般而言,專案擁有者有責任定義平台,因為不同專案的目標機器不同。請參閱「預設平台」。

  2. 您要使用的工具鍊必須存在。如果使用現成工具鍊,語言擁有者應加入註冊說明。如果您要編寫自己的自訂工具鍊,則必須在 WORKSPACE--extra_toolchains註冊

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

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

如果仍有問題,請與支援團隊聯絡

預設平台

專案擁有者應定義明確的平台,說明要建構的架構。然後使用 --platforms 觸發這些事件。

如果未設定 --platforms,Bazel 會預設為代表本機建構機器的 platform。這項屬性會在 @platforms//host 自動產生 (別名為 @bazel_tools//tools:host_platform),因此不必明確定義。這個項目會將本機的 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",
    },
)

詳情請參閱這篇文章

select--cpu--crosstool_top 等等,都無法解讀 --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

平台對應

平台對應是暫時性 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 審查

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",
)

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

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

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

您可以在 WORKSPACE 中使用 register_toolchains 註冊可用的工具鍊組合,也可以在指令列中使用 --extra_toolchains 註冊。

詳情請參閱本文

問題

如需一般支援服務,或對遷移時間表有任何疑問,請與 bazel-discuss 或適當規則的擁有者聯絡。

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

另請參閱