プラットフォーム

<ph type="x-smartling-placeholder"></ph> 問題を報告する ソースを表示 夜間 · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bazel では、さまざまなハードウェア、オペレーティング システム、OS などでコードをビルドおよびテストできます。 さまざまなバージョンのビルドツールを使用します。たとえば、 リンクやコンパイラが含まれますこのような複雑さを管理できるように、Bazel には 制約プラットフォーム。制約は、ビルドまたは実行が 異なる場合があります。たとえば、CPU アーキテクチャ、プレゼンス、 またはシステムにインストールされているコンパイラのバージョンなどです。プラットフォームとは 選択肢の名前付きコレクションであり、特定の制約を表す リソースを定義できます。

環境をプラットフォームとしてモデル化すると、Bazel が自動的に 適切 ツールチェーン 使用できます。プラットフォームは、 config_setting 構成可能な属性を書き込むルールです。

Bazel では、プラットフォームが提供できる次の 3 つのロールが認識されます。

  • ホスト - Bazel 自体が動作するプラットフォーム。
  • Execution - ビルドツールがビルド アクションを実行するプラットフォーム 中間出力と最終出力を生成できます
  • ターゲット - 最終出力が存在し、実行されるプラットフォーム。

Bazel は、プラットフォームに関する次のビルドシナリオをサポートしています。

  • 単一プラットフォーム ビルド(デフォルト)- ホスト、実行、ターゲット プラットフォーム 同じです。たとえば、Compute Engine で実行されている Ubuntu で Linux 実行可能ファイルを Intel x64 CPU です

  • クロスコンパイル ビルド - ホスト プラットフォームと実行プラットフォームは同じですが、 ターゲット プラットフォームが異なるためです。たとえば、macOS で iOS アプリをビルドする場合、 搭載しています。

  • マルチプラットフォーム ビルド - ホスト、実行、ターゲットのプラットフォームがすべて 異なります

制約とプラットフォームの定義

選択できるプラットフォームの幅は、 constraint_settingBUILD ファイル内の constraint_value ルール。 constraint_setting は新しいディメンションを作成し、 constraint_value は、指定されたディメンションの新しい値を作成します。連携して 列挙型とその有効な値を効果的に定義します。たとえば、次のようになります。 BUILD ファイルのスニペットにより、システムの glibc バージョンの制約が導入されている 指定できる値は 2 つです。

constraint_setting(name = "glibc_version")

constraint_value(
    name = "glibc_2_25",
    constraint_setting = ":glibc_version",
)

constraint_value(
    name = "glibc_2_26",
    constraint_setting = ":glibc_version",
)

制約とその値は、同じモジュール内の異なるパッケージに 見てみましょう。これらはラベルで参照され、通常の公開の対象となります できます。公開設定が許可されている場合、次の方法で既存の制約設定を拡張できます。 独自の価値を定義します。

platform ルールは、 制約値の特定の選択肢に応じて異なります。「 次のコマンドでは、linux_x86 という名前のプラットフォームが作成され、任意のプラットフォーム Linux オペレーティング システムを x86_64 アーキテクチャで動作し、 glibc バージョン 2.25 です。(Bazel の組み込み制約について詳しくは、以下をご覧ください)。

platform(
    name = "linux_x86",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:x86_64",
        ":glibc_2_25",
    ],
)

一般的に有用な制約とプラットフォーム

エコシステムの一貫性を保つために、Bazel チームは よく利用される CPU アーキテクチャとオペレーティング システムの制約を 支援しますこれらはすべて https://github.com/bazelbuild/platforms.

Bazel には、次の特別なプラットフォーム定義が付属しています。 @platforms//host(別名 @bazel_tools//tools:host_platform)。これが 自動検出されたホスト プラットフォームの値 - Bazel が実行されているシステムで、自動検出されたプラットフォームを表します。

ビルドのプラットフォームの指定

以下を使用して、ビルドのホスト プラットフォームとターゲット プラットフォームを指定できます。 コマンドライン フラグ:

  • --host_platform - デフォルトは @bazel_tools//tools:host_platform です。 <ph type="x-smartling-placeholder">
      </ph>
    • このターゲットは、リポジトリを基盤とする @platforms//host にエイリアスされます。 ホストの OS と CPU を検出し、プラットフォーム ターゲットを書き込むルールです。
    • また、@platforms//host:constraints.bzl があります。これは、 HOST_CONSTRAINTS という配列。この配列は、他の BUILD や Starlark ファイル。
  • --platforms - デフォルトはホスト プラットフォームです。
    • つまり、他のフラグが設定されていない場合、 @platforms//host は、ターゲット プラットフォームです。
    • --host_platform が設定され、--platforms でない場合、次の値 --host_platform はホストとターゲットの両方のプラットフォームです。

互換性のないターゲットのスキップ

特定のターゲット プラットフォーム向けにビルドする場合は、通常は ターゲットにできます。たとえば、Windows デバイスが ドライバは、SDK を使用してビルドするときに多くのコンパイラ エラーを //... が指定された Linux マシン。こちらの target_compatible_with 属性を使用して、コードのターゲット プラットフォームの制約を Bazel に伝えます。

この属性の最も簡単な使用方法は、ターゲットを 1 つのプラットフォームに制限することです。 以下の条件をすべて満たしていないプラットフォームにはターゲットが構築されません。 必要があります。次の例では、win_driver_lib.cc を 64 ビットに制限しています Windows。

cc_library(
    name = "win_driver_lib",
    srcs = ["win_driver_lib.cc"],
    target_compatible_with = [
        "@platforms//cpu:x86_64",
        "@platforms//os:windows",
    ],
)

:win_driver_lib は、64 ビット Windows でのビルドにのみ互換性があります。 使用しないでください。非互換性は推移的です。すべてのターゲット 互換性のないターゲットに推移的に依存する場合、 非対応です

ターゲットがスキップされるのはどのような場合ですか?

互換性がないと見なされ、ターゲットに含まれる場合、ターゲットはスキップされます ターゲット パターンの拡張の一部としてビルドできます。たとえば、次の 2 つの例では 呼び出しでは、ターゲット パターンの展開で見つかった互換性のないターゲットがスキップされます。

$ bazel build --platforms=//:myplatform //...
$ bazel build --platforms=//:myplatform //:all

test_suite 内の互換性のないテストは次のとおりです。 同様に、コマンドラインで test_suite--expand_test_suites。 つまり、コマンドラインの test_suite ターゲットは :all のように動作し、 ...--noexpand_test_suites を使用すると拡張が妨げられ、 互換性のないテストがある test_suite ターゲットも互換性がありません。

コマンドラインで互換性のないターゲットを明示的に指定すると、 エラー メッセージと失敗したビルドが表示されます。

$ bazel build --platforms=//:myplatform //:target_incompatible_with_myplatform
...
ERROR: Target //:target_incompatible_with_myplatform is incompatible and cannot be built, but was explicitly requested.
...
FAILED: Build did NOT complete successfully

互換性のない明示的ターゲットは、次の場合に通知なくスキップされます。 --skip_incompatible_explicit_targets は有効になっています。

表現力の高い制約

制約をより柔軟に表現するには、 @platforms//:incompatible constraint_value どのプラットフォームも対応できません

select() は次のオプションと組み合わせて使用します。 @platforms//:incompatible で、より複雑な制限を表現します。対象 基本的な OR ロジックの実装に使用します。以下は、ライブラリをマークします。 macOS と Linux には対応していますが、他のプラットフォームには対応していません。

cc_library(
    name = "unixish_lib",
    srcs = ["unixish_lib.cc"],
    target_compatible_with = select({
        "@platforms//os:osx": [],
        "@platforms//os:linux": [],
        "//conditions:default": ["@platforms//:incompatible"],
    }),
)

上記は次のように解釈できます。

  1. macOS をターゲットとする場合、ターゲットに制約はありません。
  2. Linux をターゲットにしている場合、ターゲットに制約はありません。
  3. それ以外の場合、ターゲットには @platforms//:incompatible 制約が適用されます。なぜなら、 @platforms//:incompatible はどのプラットフォームにも属していません。ターゲットは次のとおりです。 配信されません。

制約を読みやすくするには、次のコマンドを使用します。 skylib selects.with_or()

逆互換性も同様の方法で表現できます。次の例をご覧ください。 ARM を除くすべてと互換性のあるライブラリについて説明しています。

cc_library(
    name = "non_arm_lib",
    srcs = ["non_arm_lib.cc"],
    target_compatible_with = select({
        "@platforms//cpu:arm": ["@platforms//:incompatible"],
        "//conditions:default": [],
    }),
)

bazel cquery を使用した互換性のないターゲットの検出

こちらの IncompatiblePlatformProvider bazel cqueryStarlark 出力内 形式で識別し、 互換性のないターゲットを互換性のあるターゲットから外します。

これを使用して、互換性のないターゲットを除外できます。以下の例では、 互換性のあるターゲットのラベルのみを出力します。互換性のないターゲットは 出力されません。

$ cat example.cquery

def format(target):
  if "IncompatiblePlatformProvider" not in providers(target):
    return target.label
  return ""


$ bazel cquery //... --output=starlark --starlark:file=example.cquery

既知の問題

互換性のないターゲットは公開設定を無視 制限します