공개 상태

문제 신고 소스 보기 1박 · 7.2 · 7.1 · 7.0 · 6.5 · 6.4

이 페이지에서는 Bazel의 두 가지 가시성 시스템을 다룹니다. 타겟 공개 상태로드 가시성입니다.

이 두 가지 공개 유형은 다른 개발자가 공개 API 및 구현 세부정보, 구조 강제 적용 지원 관리할 수 있습니다 공개를 지원 중단할 때 공개 상태를 사용할 수도 있습니다. 현재 사용자는 허용하고 신규 사용자를 거부하는 API.

대상 공개 상태

타겟 공개 상태는 타겟을 신뢰할 수 있는 사용자, 즉 deps와 같은 속성 안에 타겟의 라벨을 사용하세요.

타겟 A는 동일한 패키지에 있거나 타겟 B에 표시되는 경우 AB의 패키지에 대한 가시성을 부여합니다. 따라서 패키지는 액세스 허용 여부를 결정할 수 있습니다. BA에 의존하는 경우 AB에 표시되지 않으면 B 빌드 시도가 실패합니다. 분석입니다.

패키지에 공개 상태를 부여하는 것만으로는 공개 상태가 부여되지 않습니다. 추가해야 합니다 패키지 및 하위 패키지에 대한 자세한 내용은 개념 및 용어.

프로토타입 제작의 경우 플래그 --check_visibility=false 프로덕션 환경에서 확인할 수 있습니다

공개 상태를 제어하는 기본 방법은 visibility 속성 사용 규칙 대상입니다. 이 섹션에서는 이 속성의 형식과 타겟의 가시성을 결정합니다

공개 상태 사양

모든 규칙 대상에는 라벨 목록을 사용하는 visibility 속성이 있습니다. 각 라벨의 형식은 다음 중 하나입니다. 마지막 형식을 제외하고 는 실제 타겟과 일치하지 않는 구문적 자리표시자일 뿐입니다.

  • "//visibility:public": 모든 패키지에 대한 액세스 권한을 부여합니다. (조합되지 않을 수 있음) 사용할 수 있습니다.)

  • "//visibility:private": 추가 액세스 권한을 부여하지 않습니다. 대상만 이 타겟을 사용할 수 있습니다. (다른 솔루션과 함께 사용할 수 없음 specification.)

  • "//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에 정의된 타겟으로 지정되지 않음

권장사항: 여러 타겟을 동일한 세트에 표시하려면 각 패키지에서 목록을 반복하는 대신 package_group 사용 대상의 visibility 속성 이렇게 하면 가독성이 높아지고 목록이 동기화되지 않게 할 수 있습니다.

규칙 대상 공개 상태

규칙 대상의 공개 상태는 다음과 같습니다.

  1. visibility 속성 값(설정된 경우) 또는 기타

  2. default_visibility 드림 인수 package 대상의 BUILD 파일(선언이 있는 경우) 또는 기타

  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_files visibility이(가) 없는 경우 인수가 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은 config_setting 대상 select()의 키에서 참조됩니다. 거기 는 이 기존 동작을 제거하는 두 개의 플래그입니다.

  • --incompatible_enforce_config_setting_visibility 드림 를 사용하면 이러한 대상에 대한 가시성 확인을 사용할 수 있습니다. 마이그레이션을 지원하기 위해 또한 visibility를 지정하지 않는 모든 config_setting가 패키지 수준 default_visibility과 관계없이 공개로 간주됩니다.

  • --incompatible_config_setting_private_default_visibility 드림 visibility를 지정하지 않는 config_setting가 비공개로 대체하고 default_visibility 다른 규칙 대상처럼 말이죠 다음 경우에는 노옵스(no-ops)입니다. --incompatible_enforce_config_setting_visibility가 설정되지 않았습니다.

기존 동작에 의존하지 마세요. 의도된 모든 config_setting 현재 패키지 외부에서 사용하려면 명시적인 visibility가 있어야 합니다. 패키지가 아직 적절한 default_visibility를 지정하지 않았습니다.

패키지 그룹 타겟 공개 상태

package_group 타겟에는 visibility 속성이 없습니다. 그들은 항상 볼 수 있습니다.

암시적 종속 항목의 공개 상태

일부 규칙에는 암시적 종속 항목이 있습니다. 종속 항목은 BUILD 파일에 명시되어 있지 않지만 해당 규칙의 모든 인스턴스 예를 들어 cc_library 규칙은 실행 가능한 대상에 대한 암시적 종속 항목을 설치합니다. C++ 컴파일러를 나타냅니다.

이러한 암시적 종속성의 표시 여부는 규칙 (또는 관점)이 정의된 .bzl 파일이 포함된 패키지입니다. 포함 예를 들어, C++ 컴파일러가 패키지를 cc_library 규칙의 정의로 사용합니다. 대체로 암시적 종속 항목이 정의에 표시되지 않으면 cc_library 타겟 기준

이 동작을 변경하려면 --incompatible_visibility_private_attributes_at_definition 사용 중지하면 암시적 종속 항목이 다른 종속 항목과 동일하게 처리됩니다. 즉, 종속된 타겟 (예: C++ 컴파일러)은 모든 인스턴스에 표시됩니다. 실제로 이는 일반적으로 모든 사용자에게 공개됩니다.

특정 패키지로 규칙 사용을 제한하려면 다음을 사용합니다. 로드 가시성을 대신 제공합니다.

로드 공개 상태

로드 공개 상태.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() 호출은 파일당 최상위 수준에서 한 번만 발생해야 합니다( load() 문 바로 뒤에 추가하는 것이 가장 좋습니다.

대상 공개 상태와 달리 기본 로드 공개 상태는 항상 공개됩니다. 파일 visibility()를 호출하지 않는 모든 객체는 살펴보겠습니다 visibility("private")를 새 .bzl 파일을 제공합니다.

# //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 파일을 허용 목록에 추가해야 할 수 있습니다. 여러 개의 작은 허용 목록으로 구성됩니다. 이것은 Kubernetes가 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에서 밑줄이 아닌 기호가 포함되지 않도록 할 수는 없습니다. 있습니다

다행히 이 두 기능을 결합하여 세밀하게 제어할 수 있습니다.

# //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 린트

Buildifier 린트가 있음 - 사용자가 internal 디렉터리에서 파일을 로드할 경우 경고를 표시합니다. 또는 private: 사용자의 파일 자체가 상위 파일 아래에 있지 않은 경우 를 참조하세요. 이 린트는 로드 공개 상태 기능보다 먼저 존재하며 .bzl 파일이 공개 상태를 선언하는 작업공간