可視性

問題を報告する ソースを表示 夜間 7.4 をタップします。 7.3 · 7.2 · 7.1 · 7.0 · 6.5

このページでは、Bazel の 2 つの可視性システム(ターゲット可視性読み込み可視性)について説明します。

どちらの公開設定も、他のデベロッパーがライブラリのパブリック API とその実装の詳細を区別し、ワークスペースの増大に応じて構造を適用するのに役立ちます。また、一般公開を非推奨にするときに公開設定を使用することもできます。 現在のユーザーを許可し、新規ユーザーは拒否する API。

ターゲットの可視性

ターゲットの公開設定では、ターゲットに依存するユーザー、つまり、 deps などの属性内でターゲットのラベルを使用する。

ターゲット A は、同じパッケージ内にある場合、または AB のパッケージへの可視性を付与している場合に、ターゲット B に可視になります。したがって、アクセスを許可するかどうかを決定する粒度の単位はパッケージです。BA に依存している場合 AB からは見えませんが、B のビルドを試みると失敗します。 分析

パッケージに可視性を付与しても、パッケージに可視性が付与されるわけではないことに注意してください。 サブパッケージに追加します。パッケージとサブパッケージの詳細については、以下をご覧ください。 コンセプトと用語

プロトタイピングでは、ターゲットの公開設定の適用を フラグ --check_visibility=false。送信されたコードで本番環境で使用する場合、これは行わないでください。

公開設定を制御する主な方法は、 visibility 属性がオン 指定します。このセクションでは、この属性の形式と、ターゲットの公開設定を決定する方法について説明します。

公開設定の仕様

すべてのルール ターゲットには、ラベルのリストを受け取る visibility 属性があります。各 次のいずれかの形式になります。最後のフォームを除いて 実際のターゲットに対応しない構文上のプレースホルダです。

  • "//visibility:public": すべてのパッケージへのアクセス権を付与します。(組み合わせることはできない) 使用しないでください)。

  • "//visibility:private": 追加のアクセス権を付与しません。ターゲットのみ このターゲットを使用できます。(他の仕様と組み合わせることはできません)。

  • "//foo/bar:__pkg__": //foo/bar へのアクセスを許可します(ただし、 使用しないでください。

  • "//foo/bar:__subpackages__": //foo/bar とその直接サブパッケージと間接サブパッケージへのアクセス権を付与します。

  • "//some_pkg:my_package_group": 指定された package_group に含まれるすべてのパッケージへのアクセスを許可します。

    • パッケージ グループでは、パッケージの指定に異なる構文が使用されます。パッケージ グループ内では、フォーム "//foo/bar:__pkg__""//foo/bar:__subpackages__" はそれぞれ "//foo/bar""//foo/bar/..." に置き換えられます。同様に、"//visibility:public""//visibility:private""public""private" です。

たとえば、//some/package:mytargetvisibility[":__subpackages__", "//tests:__pkg__"] の場合は、どのターゲットでも使用できます。 (//some/package/... ソースツリーの一部)と、定義されたターゲット //tests/BUILD には格納されますが、//tests/integration/BUILD で定義されたターゲットによるものではありません。

ベスト プラクティス: 複数のターゲットを同じパッケージセットに表示するには、各ターゲットの visibility 属性でリストを繰り返すのではなく、package_group を使用します。これにより、可読性が向上し、リストの同期がずれるのを防ぐことができます。

ルールのターゲットの公開設定

ルール ターゲットの公開設定は次のとおりです。

  1. visibility 属性の値(設定されている場合)。その他

  2. ターゲットの BUILD ファイル内の package ステートメントの default_visibility 引数の値(そのような宣言が存在する場合)。存在しない場合は、

  3. //visibility:private

ベスト プラクティス: default_visibility を公開に設定しないでください。プロトタイピングや小規模なコードベースでは便利ですが、コードベースのサイズが大きくなるにつれて、誤って公開ターゲットを作成するリスクが高まります。自分の役割を パッケージの公開インターフェースに含まれるターゲットを明示します。

ファイル //frobber/bin/BUILD:

# This target is visible to everyone
cc_binary(
    name = "executable",
    visibility = ["//visibility:public"],
    deps = [":library"],
)

# This target is visible only to targets declared in the same package
cc_library(
    name = "library",
    # No visibility -- defaults to private since no
    # package(default_visibility = ...) was used.
)

# This target is visible to targets in package //object and //noun
cc_library(
    name = "subject",
    visibility = [
        "//noun:__pkg__",
        "//object:__pkg__",
    ],
)

# See package group "//frobber:friends" (below) for who can
# access this target.
cc_library(
    name = "thingy",
    visibility = ["//frobber:friends"],
)

ファイル //frobber/BUILD:

# This is the package group declaration to which target
# //frobber/bin:thingy refers.
#
# Our friends are packages //frobber, //fribber and any
# subpackage of //fribber.
package_group(
    name = "friends",
    packages = [
        "//fribber/...",
        "//frobber",
    ],
)

生成されたファイル ターゲットの公開設定

生成されたファイル ターゲットは、そのファイル ターゲットと同じ公開設定になります。 生成します。

ソースファイル ターゲットの公開設定

ソースファイル ターゲットの公開設定を明示的に設定するには、 exports_filesvisibility がない場合 exports_files に渡されると、公開設定が公開されるようになります。 exports_files を使用して、生成されたファイルの公開設定をオーバーライドすることはできません。

exports_files の呼び出しに表示されないソースファイル ターゲットの場合、公開設定はフラグ --incompatible_no_implicit_file_export の値によって異なります。

  • フラグが設定されている場合、公開設定は非公開になります。

  • それ以外の場合は、従来の動作が適用されます。公開設定は BUILD ファイルの default_visibility。デフォルトの公開設定が次の場合は非公開です。 指定されていません。

従来の動作に依存しないでください。ソースファイル ターゲットで非公開以外の公開設定が必要な場合は、必ず exports_files 宣言を記述します。

ベスト プラクティス: 可能であれば、ソースファイルではなくルール ターゲットを公開します。たとえば、.java ファイルで exports_files を呼び出すのではなく、非公開以外の java_library ターゲットでファイルをラップします。一般的に、ルールのターゲットは 直接参照するのは、同じパッケージ内にあるソースファイルのみです。

ファイル //frobber/data/BUILD:

exports_files(["readme.txt"])

ファイル //frobber/bin/BUILD:

cc_binary(
  name = "my-program",
  data = ["//frobber/data:readme.txt"],
)

設定の公開設定

これまで、Bazel では select() のキーで参照される config_setting ターゲットの可視性が適用されていませんでした。この以前の動作を削除するフラグは 2 つあります。

  • --incompatible_enforce_config_setting_visibility を使用すると、これらのターゲットの公開設定の確認が有効になります。移行を支援するために また、visibility を指定していない config_setting も 公開と見なされます(パッケージ レベルの default_visibility は関係ありません)。

  • --incompatible_config_setting_private_default_visibility visibility を指定していない config_setting は、 パッケージの default_visibility を使用し、非公開の公開設定にフォールバックできます。 他のルール ターゲットと同じように使用できます。次の場合は NoOps である --incompatible_enforce_config_setting_visibility は設定されていません。

以前の動作に依存しないでください。現在のパッケージの外部で使用することを目的とした config_setting には、パッケージで適切な default_visibility がまだ指定されていない場合は、明示的な visibility が必要です。

パッケージ グループ ターゲットの公開設定

package_group ターゲットには visibility 属性がありません。常に一般公開されます。

暗黙的な依存関係の可視性

一部のルールには暗黙的な依存関係があります。 BUILD ファイルに記述されていないものの本質的に依存関係があり、 表示されます。たとえば、cc_library ルールにより、 各ルール ターゲットから実行可能なターゲットへの暗黙的な依存関係 C++ コンパイラを表します。

現在、可視性のために、これらの暗黙的な依存関係は他の依存関係と同様に扱われます。つまり、依存するターゲット(例: C++ コンパイラなど)は、ルールのすべてのインスタンスから参照できる必要があります。実際には、通常、ターゲットは一般公開されている必要があります。

この動作は、--incompatible_visibility_private_attributes_at_definition を設定することで変更できます。有効にすると、 そのターゲットを暗黙的に宣言するルールからのみ 確認します。つまり、.bzl を含むパッケージから参照できる必要があります。 ルールが定義されているファイル。この例では、C++ コンパイラは、cc_library ルールの定義と同じパッケージに存在する限り、非公開にできます。

読み込みの可視性

読み込みの公開設定は、.bzl ファイルを他の BUILD ファイルまたは .bzl ファイルから読み込むことができるかどうかを制御します。

ターゲット ビジュアリゼーションがターゲットによってカプセル化されたソースコードを保護するのと同様に、読み込みビジュアリゼーションは .bzl ファイルによってカプセル化されたビルドロジックを保護します。たとえば、BUILD ファイルの作成者は、繰り返し発生するターゲット定義を .bzl ファイルのマクロに分割できます。読み込みの可視性を保護しないと、同じワークスペース内の他の共同編集者によってマクロが再利用され、マクロを変更すると他のチームのビルドが破損する可能性があります。

.bzl ファイルには、対応するソースファイル ターゲットが存在する場合と存在しない場合もあります。含まれている場合、負荷の可視性とターゲットが 表示されます。つまり、同じ BUILD ファイルで .bzl ファイルですが、filegroupsrcs にリストされていない場合、 といったことができますこれにより、ドキュメントの生成やテストなど、.bzl ファイルをソースコードとして使用するルールで問題が発生することがあります。

プロトタイプ作成の場合は、--check_bzl_visibility=false を設定することで、読み込みの可視性の適用を無効にできます。--check_visibility=false と同様に、この処理は 提出されたコードの処理は行われません。

負荷の可視性は、Bazel 6.0 以降で利用できます。

読み込みの公開設定を宣言する

.bzl ファイルの読み込みの公開設定を設定するには、ファイル内から visibility() 関数を呼び出します。visibility() の引数は、次のようなパッケージ仕様のリストです。 次の packages 属性: package_group。ただし、visibility() は負のパッケージ仕様を受け入れません。

visibility() の呼び出しは、ファイルごとに 1 回だけトップレベルで行う必要があります。 load() ステートメントの直後に置くのが理想的です。

ターゲットの公開設定とは異なり、デフォルトの負荷の公開設定は常に公開です。visibility() を呼び出さないファイルは、ワークスペースのどこからでも常に読み込むことができます。パッケージの外部で使用することを特に意図していない新しい .bzl ファイルの先頭に visibility("private") を追加することをおすすめします。

# //mylib/internal_defs.bzl

# Available to subpackages and to mylib's tests.
visibility(["//mylib/...", "//tests/mylib/..."])

def helper(...):
    ...
# //mylib/rules.bzl

load(":internal_defs.bzl", "helper")
# Set visibility explicitly, even though public is the default.
# Note the [] can be omitted when there's only one entry.
visibility("public")

myrule = rule(
    ...
)
# //someclient/BUILD

load("//mylib:rules.bzl", "myrule")          # ok
load("//mylib:internal_defs.bzl", "helper")  # error

...

読み込みの可視化のベスト プラクティス

このセクションでは、負荷の可視性の宣言を管理するためのヒントについて説明します。

因数分解の公開設定

複数の .bzl ファイルに同じ公開設定を適用する場合は、パッケージ仕様を共通のリストにまとめると便利です。例:

# //mylib/internal_defs.bzl

visibility("private")

clients = [
    "//foo",
    "//bar/baz/...",
    ...
]
# //mylib/feature_A.bzl

load(":internal_defs.bzl", "clients")
visibility(clients)

...
# //mylib/feature_B.bzl

load(":internal_defs.bzl", "clients")
visibility(clients)

...

これにより、さまざまな .bzl ファイル間の意図しない歪みを防ぐことができます。 示します。また、clients リストが大きい場合にも読みやすくなります。

可視性の合成

場合によっては、許可リストに登録された許可リストに .bzl ファイルを 複数の小さな許可リストで構成されますこれも package_group は、次を介して他の package_group を組み込むことができます。 includes 属性。

広く使用されているマクロを廃止するとします。表示のみ可能にしたい 自分のチームが所有するパッケージに公開されます。次のように記述します。

# //mylib/macros.bzl

load(":internal_defs.bzl", "our_packages")
load("//some_big_client:defs.bzl", "their_remaining_uses)

# List concatenation. Duplicates are fine.
visibility(our_packages + their_remaining_uses)

パッケージ グループによる重複除去

ターゲット ビジュアリゼーションとは異なり、読み込みビジュアリゼーションを package_group で定義することはできません。ターゲットの公開設定と読み込みの公開設定の両方で同じ許可リストを再利用する場合は、パッケージ仕様のリストを .bzl ファイルに移動することをおすすめします。このファイルでは、両方の宣言でリストを参照できます。上記の公開設定の分類の例を基に、次のように記述できます。

# //mylib/BUILD

load(":internal_defs", "clients")

package_group(
    name = "my_pkg_grp",
    packages = clients,
)

これは、リストにネガティブなパッケージ仕様が含まれていない場合にのみ機能します。

個々のシンボルの保護

名前がアンダースコアで始まる Starlark シンボルは、 作成します。これにより、非公開シンボルを簡単に作成できますが、 これらのシンボルを、信頼できる一部のファイルと共有できます。反対側 負荷の可視性により、他のパッケージが何を認識するかを .bzl file。ただし、アンダースコア以外の記号を 表示されます。

これら 2 つの機能を組み合わせることで、きめ細かい管理が可能です。

# //mylib/internal_defs.bzl

# Can't be public, because internal_helper shouldn't be exposed to the world.
visibility("private")

# Can't be underscore-prefixed, because this is
# needed by other .bzl files in mylib.
def internal_helper(...):
    ...

def public_util(...):
    ...
# //mylib/defs.bzl

load(":internal_defs", "internal_helper", _public_util="public_util")
visibility("public")

# internal_helper, as a loaded symbol, is available for use in this file but
# can't be imported by clients who load this file.
...

# Re-export public_util from this file by assigning it to a global variable.
# We needed to import it under a different name ("_public_util") in order for
# this assignment to be legal.
public_util = _public_util

bzl-visibility Buildifier lint

Buildifier lint が存在します。 ユーザーが internal という名前のディレクトリからファイルを読み込むと警告を表示する または private(ユーザーのファイル自体がその親の下位にない場合) されます。この lint は読み込みの可視性機能より前から存在するため、 .bzl ファイルで公開設定を宣言するワークスペース