Bazel では、さまざまなハードウェア、オペレーティング システム、OS などでコードをビルドおよびテストできます。 さまざまなバージョンのビルドツールを使用します。たとえば、 リンクやコンパイラが含まれますこのような複雑さを管理できるように、Bazel には 制約とプラットフォーム。制約は、ビルドまたは実行が 異なる場合があります。たとえば、CPU アーキテクチャ、プレゼンス、 またはシステムにインストールされているコンパイラのバージョンなどです。プラットフォームとは 選択肢の名前付きコレクションであり、特定の制約を表す リソースを定義できます。
環境をプラットフォームとしてモデル化すると、Bazel が自動的に 適切 ツールチェーン 使用できます。プラットフォームは、 config_setting 構成可能な属性を書き込むルールです。
Bazel では、プラットフォームが提供できる次の 3 つのロールが認識されます。
- ホスト - Bazel 自体が動作するプラットフォーム。
- Execution - ビルドツールがビルド アクションを実行するプラットフォーム 中間出力と最終出力を生成できます
- ターゲット - 最終出力が存在し、実行されるプラットフォーム。
Bazel は、プラットフォームに関する次のビルドシナリオをサポートしています。
単一プラットフォーム ビルド(デフォルト)- ホスト、実行、ターゲット プラットフォーム 同じです。たとえば、Compute Engine で実行されている Ubuntu で Linux 実行可能ファイルを Intel x64 CPU です
クロスコンパイル ビルド - ホスト プラットフォームと実行プラットフォームは同じですが、 ターゲット プラットフォームが異なるためです。たとえば、macOS で iOS アプリをビルドする場合、 搭載しています。
マルチプラットフォーム ビルド - ホスト、実行、ターゲットのプラットフォームがすべて 異なります
制約とプラットフォームの定義
選択できるプラットフォームの幅は、
constraint_setting
、
BUILD
ファイル内の 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
- デフォルトはホスト プラットフォームです。 <ph type="x-smartling-placeholder">- </ph>
- つまり、他のフラグが設定されていない場合、
@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"],
}),
)
上記は次のように解釈できます。
- macOS をターゲットとする場合、ターゲットに制約はありません。
- Linux をターゲットにしている場合、ターゲットに制約はありません。
- それ以外の場合、ターゲットには
@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 cquery
の Starlark 出力内
形式で識別し、
互換性のないターゲットを互換性のあるターゲットから外します。
これを使用して、互換性のないターゲットを除外できます。以下の例では、 互換性のあるターゲットのラベルのみを出力します。互換性のないターゲットは 出力されません。
$ cat example.cquery
def format(target):
if "IncompatiblePlatformProvider" not in providers(target):
return target.label
return ""
$ bazel cquery //... --output=starlark --starlark:file=example.cquery
既知の問題
互換性のないターゲットは公開設定を無視 制限します。