外部依存関係の操作

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

Bazel は他のプロジェクトのターゲットに依存できます。他のインフラストラクチャからの依存関係は 外部依存関係と呼ばれます。

WORKSPACE ファイル(または WORKSPACE.bazel ファイル)は、 workspace ディレクトリ 他のプロジェクトを取得する方法を Bazel に指示しますあります。これらの他のプロジェクトは、 独自のターゲットを持つ 1 つ以上の BUILD ファイルを含む。次のフォルダ内の BUILD 個のファイル メイン プロジェクトは、これらの外部ターゲットの名前を使用して、 WORKSPACE ファイル。

たとえば、システムに 2 つのプロジェクトがあるとします。

/
  home/
    user/
      project1/
        WORKSPACE
        BUILD
        srcs/
          ...
      project2/
        WORKSPACE
        BUILD
        my-libs/

project1 がターゲット :foo に依存する場合、 「/home/user/project2/BUILD」という名前のリポジトリを 「project2」は /home/user/project2 にあります。次に、 /home/user/project1/BUILD@project2//:foo に依存している可能性があります。

WORKSPACE ファイルを使用すると、ユーザーはモジュールの他の部分のターゲットに依存できます。 インターネットからダウンロードしたファイルです。BUILD と同じ構文を使用します。 リポジトリ ルールと呼ばれる別のルールセットを使用できます(場合によっては、 Workspace のルールとも呼ばれます)。Bazel にはいくつかの組み込みリポジトリが付属 一連のStarlark リポジトリが組み込まれ ルールをご覧ください。ユーザーはカスタム リポジトリを作成して ルールを使用して動作を複雑なものにします。

サポートされている外部依存関係のタイプ

次のような基本的な種類の外部依存関係を使用できます。

他の Bazel プロジェクトに依存する

2 つ目の Bazel プロジェクトのターゲットを使用する場合は、次のようにします。 local_repository git_repository または http_archive ローカル ファイル システムからシンボリック リンクするか、Git リポジトリを参照するか、 できます。

たとえば、プロジェクト my-project/ で作業していて、 同僚のプロジェクト coworkers-project/ のターゲットに依存するようにできます。両方 Bazel を使用しているプロジェクトで、同僚のプロジェクトを外部 次に、同僚が独自に定義したターゲットを BUILD ファイル。my_project/WORKSPACE に以下を追加します。

local_repository(
    name = "coworkers_project",
    path = "/path/to/coworkers-project",
)

同僚にターゲット //foo:bar がある場合、プロジェクトではこれを次のように参照できます。 @coworkers_project//foo:bar。外部プロジェクト名は 有効なワークスペース名

Bazel 以外のプロジェクトに依存する

次のように、接頭辞が new_ のルール new_local_repository Bazel を使用していないプロジェクトからターゲットを作成できます。

たとえば、プロジェクト my-project/ で作業していて、 同僚のプロジェクト coworkers-project/ に依存することになります。同僚の プロジェクトで make を使用してビルドしているが、.so ファイルのいずれかを使用したい 必要があります。これを行うには、my_project/WORKSPACE に次の行を追加します。

new_local_repository(
    name = "coworkers_project",
    path = "/path/to/coworkers-project",
    build_file = "coworker.BUILD",
)

build_file は、既存のプロジェクトにオーバーレイする BUILD ファイルを指定します。 例:

cc_library(
    name = "some-lib",
    srcs = glob(["**"]),
    visibility = ["//visibility:public"],
)

これにより、プロジェクトの@coworkers_project//:some-libから BUILD ファイル。

外部パッケージへの依存

Maven アーティファクトとリポジトリ

ルールセット rules_jvm_external を使用する Maven リポジトリからアーティファクトをダウンロードし、Java として利用できるようにします。 確認します。

依存関係をフェッチする

デフォルトでは、外部依存関係は bazel build 中に必要に応じて取得されます。条件 特定のターゲット セットに必要な依存関係をプリフェッチする場合は、 bazel fetch。 すべての外部依存関係を無条件にフェッチするには、次のコマンドを使用します。 bazel sync。 フェッチされたリポジトリは出力ベースに格納されるため、 自動的に適用されます

依存関係のシャドーイング

可能な限り、バージョン ポリシーは 1 つだけに できます。コンパイルする依存関係に必要であり、最終的に 確認できます。ただし、正しくないケースでは、 説明します。次のシナリオを考えてみます。

自分のプロジェクト/WORKSPACE

workspace(name = "myproject")

local_repository(
    name = "A",
    path = "../A",
)
local_repository(
    name = "B",
    path = "../B",
)

A/ワークスペース

workspace(name = "A")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "testrunner",
    urls = ["https://github.com/testrunner/v1.zip"],
    sha256 = "...",
)

B/Workspace

workspace(name = "B")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "testrunner",
    urls = ["https://github.com/testrunner/v2.zip"],
    sha256 = "..."
)

依存関係 AB はどちらも testrunner に依存しているが、依存している 異なるバージョンの testrunner を使用します。これらのテストランナーが myproject 内に平和に共存しませんが、それぞれが競合します 名前が同じであるためです両方の依存関係を宣言するには、 myproject/WORKSPACE を更新します。

workspace(name = "myproject")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "testrunner-v1",
    urls = ["https://github.com/testrunner/v1.zip"],
    sha256 = "..."
)
http_archive(
    name = "testrunner-v2",
    urls = ["https://github.com/testrunner/v2.zip"],
    sha256 = "..."
)
local_repository(
    name = "A",
    path = "../A",
    repo_mapping = {"@testrunner" : "@testrunner-v1"}
)
local_repository(
    name = "B",
    path = "../B",
    repo_mapping = {"@testrunner" : "@testrunner-v2"}
)

この機構はダイヤモンドの結合にも使用できます。たとえば、AB の場合です。 同じ依存関係を持っていても別の名前で呼び出すと、それらの依存関係は myproject/WORKSPACE で追加する必要があります。

コマンドラインからリポジトリをオーバーライドする

コマンドラインから、宣言されたリポジトリをローカル リポジトリでオーバーライドするには、 使用 --override_repository 設定されます。このフラグを使用すると、外部リポジトリのコンテンツに ソースコードの変更が不要です

たとえば、@foo をオーバーライドしてローカル ディレクトリ /path/to/local/foo にするには、次のようにします。 --override_repository=foo=/path/to/local/foo フラグを渡します。

ユースケースの一部を示します。

  • 問題のデバッグ。たとえば、http_archive リポジトリをオーバーライドできます。 ローカル ディレクトリに移動すると、変更を加えるのが簡単になります。
  • ベンダリング。ネットワーク通話ができない環境では ローカル ディレクトリを指すようにネットワーク ベースのリポジトリ ルールをオーバーライドする してください。

プロキシの使用

Bazel は HTTPS_PROXYHTTP_PROXY からプロキシ アドレスを取得します。 使用して HTTP/HTTPS ファイルをダウンロードします(指定されている場合)。

IPv6 のサポート

IPv6 のみのマシンでは、Bazel は以下を使用して依存関係をダウンロードできます。 変更はありません。ただし、IPv4/IPv6 デュアルスタック マシンでは、Bazel は同じ Java と同じようになります。IPv4 が有効な場合は IPv4 が優先されます。場合によっては たとえば、IPv4 ネットワークで外部アドレスを解決/到達できない場合、 これにより、Network unreachable 例外やビルドエラーが発生する可能性があります。 このような場合は、Bazel の動作をオーバーライドして IPv6 を優先させることができます。 java.net.preferIPv6Addresses=true システム プロパティを使用します。 詳細は以下のとおりです。

  • --host_jvm_args=-Djava.net.preferIPv6Addresses=true を使用する 起動オプション たとえば、次の行を .bazelrc ファイル:

    startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true

  • インターネットに接続する必要がある Java ビルド ターゲットを実行している場合 (統合テストで必要になる場合があります) --jvmopt=-Djava.net.preferIPv6Addresses=true ツールフラグを設定します。たとえば、 .bazelrc ファイルに次の行を追加します。

    build --jvmopt=-Djava.net.preferIPv6Addresses

  • 以下を使用している場合: rules_jvm_external, たとえば、依存関係のバージョンを解決する場合は、 -Djava.net.preferIPv6Addresses=trueまでCOURSIER_OPTS 環境変数を使用して、Coursier 用の JVM オプションを指定します。

推移的依存関係

Bazel は、WORKSPACE ファイルにリストされている依存関係のみを読み取ります。プロジェクトで (A)は別のプロジェクト(B)に依存しており、そのプロジェクトは 3 つ目のプロジェクトの依存関係をリストしています プロジェクト(C)を WORKSPACE ファイルに追加する場合は、BC をプロジェクトの WORKSPACE ファイルに追加します。この要件により ファイルサイズは WORKSPACE ですが、ライブラリが 1 つになる可能性は低くなります バージョン 1.0 の C と 2.0 の C のインクルードがあります。

外部依存関係のキャッシュ保存

デフォルトでは、Bazel は外部依存関係が再ダウンロードされるのは、 あります。定義で参照されているファイルに対する変更(パッチなど) BUILD ファイルなど)も bazel で考慮されます。

強制的に再ダウンロードするには、bazel sync を使用します。

レイアウト

外部依存関係はすべて、サブディレクトリの下のディレクトリにダウンロードされます。 出力ベースexternal。たとえば、 ローカル リポジトリでは、シンボリック リンクが作成されます。 新しいディレクトリを作成する代わりに、 次のコマンドを実行すると、external ディレクトリが表示されます。

ls $(bazel info output_base)/external

なお、bazel clean を実行しても、外部 されます。すべての外部アーティファクトを削除するには、bazel clean --expunge を使用します。

オフライン ビルド

オフライン方式でビルドを実行することが望ましい場合や、必要な場合もあります。対象 シンプルなユースケースの場合 prefetching bazel fetch または bazel sync を使用したリポジトリで十分です。さらに、 --nofetch オプションを使用すると、追加のリポジトリのフェッチを無効にできます。 おすすめします。

必要なファイルを提供する真のオフライン ビルドの場合 場合は、bazel はオプションの --distdir。リポジトリ ルールが ctx.download または ctx.download_and_extract ファイルのハッシュサムと 必要な場合、bazel はまずそのオプションで指定されたディレクトリを 指定された最初の URL のベース名と一致するファイルを作成し、そのローカルコピーを使用します。 照合されます。

Bazel 自体もこの手法を使用して、ディストリビューションからオフラインでブートストラップします。 アーティファクトです。 そのために、必要な外部リソースをすべて収集し、 依存関係 内部で distdir_tar

ただし、Bazel では、リポジトリ ルールで任意のコマンドを実行できます。 ネットワークの呼び出しの有無はわかりませんしたがって、bazel に ビルドを完全にオフラインにする必要があります。そのため、ビルドが正しく動作するかどうかを オフラインには、Bazel が行うように、ネットワークの外部ブロックが必要です。 ブートストラップ テストを実行します。

ベスト プラクティス

リポジトリ ルール

通常、リポジトリ ルールは次のことを行います。

  • システム設定を検出してファイルに書き込む。
  • システム上の他の場所でリソースを見つける。
  • URL からリソースをダウンロードする。
  • BUILD ファイルを生成するか、外部リポジトリ ディレクトリにシンボリック リンクする。

可能な限り repository_ctx.execute の使用は避けてください。たとえば、Bazel 以外の C++ を使用している場合 含まれている場合は、repository_ctx.download() を使用することをおすすめします。その後、 ctx.execute(["make"]) を実行する代わりに、そのビルド用の BUILD ファイルを作成します。

git_repository よりも http_archive を優先する new_git_repository。その理由は次のとおりです。

  • Git リポジトリ ルールはシステムの git(1) に依存しますが、HTTP ダウンローダーはビルドされます Bazel に移行し、システムの依存関係がないことを確認します。
  • http_archive はミラーとして urls のリストをサポートし、git_repository はミラーとして 単一の remote
  • http_archiveリポジトリ キャッシュでは機能しますが、 git_repository。詳しくは、 #5116 をご覧ください。

bind() を使用しない。詳しくは bind」を選択します。長期間 議論が交わされます。