모듈 확장 프로그램

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

모듈 확장 프로그램을 사용하면 사용자가 입력 데이터를 읽어 모듈 시스템을 확장할 수 있습니다. 종속 항목 그래프 전반의 모듈에서 마지막으로 저장소 규칙을 호출하여 저장소를 만듭니다. 이 광고 확장 저장소 규칙과 유사한 기능이 있습니다. 이 기능을 사용하면 파일 I/O, 네트워크 요청을 보내는 등의 작업을 수행합니다. 무엇보다도 Bazel은 이를 통해 다른 패키지 관리 시스템과 상호 작용하면서 Bazel 모듈로 빌드된 종속 항목 그래프

저장소 규칙과 마찬가지로 .bzl 파일에서 모듈 확장 프로그램을 정의할 수 있습니다. 그들은 직접 호출되지 않습니다. 각 모듈은 태그라고 하는 데이터 조각을 지정합니다. 확장 프로그램이 읽을 수 있도록 지원합니다 Bazel이 모듈을 평가하기 전에 확장 프로그램 확장 프로그램은 전체 시스템 전반에서 여기에 속한 모든 태그를 읽습니다. 종속 항목 그래프입니다.

확장 프로그램 사용

확장 프로그램은 Bazel 모듈 자체에서 호스팅됩니다. 확장 프로그램에서 먼저 확장 프로그램을 호스팅하는 모듈에 bazel_dep를 추가한 후 use_extension 기본 제공 함수 호출 살펴봤습니다 다음 예를 살펴보겠습니다. 'maven'을 사용하기 위한 MODULE.bazel 파일 확장자가 rules_jvm_external 모듈:

bazel_dep(name = "rules_jvm_external", version = "4.5")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

이렇게 하면 use_extension의 반환 값이 변수에 결합되어 사용자는 점 문법을 사용하여 확장 프로그램의 태그를 지정할 수 있습니다. 태그는 지정된 해당 태그 클래스에 의해 정의된 스키마가 확장 프로그램 정의를 참고하세요. 예를 들어 maven.installmaven.artifact 태그:

maven.install(artifacts = ["org.junit:junit:4.13.2"])
maven.artifact(group = "com.google.guava",
               artifact = "guava",
               version = "27.0-jre",
               exclusions = ["com.google.j2objc:j2objc-annotations"])

use_repo 지시어를 사용하여 저장소 가져오기 현재 모듈의 범위로 가져옵니다.

use_repo(maven, "maven")

확장 프로그램에서 생성된 저장소는 API의 일부입니다. 이 예에서 'maven' 모듈 확장 프로그램이 maven라는 저장소를 생성하도록 약속합니다. 선언하면 확장 프로그램이 @maven//:org_junit_junit: 'maven'에서 생성된 저장소를 가리킴 확장자가 포함됩니다.

확장 프로그램 정의

다음과 같이 저장소 규칙과 유사하게 모듈 확장 프로그램을 정의할 수 있습니다. module_extension 함수 하지만 저장소 규칙에는 여러 속성이 있지만 모듈 확장에는 tag_class: 각각에는 여러 개의 속성 태그 클래스는 이 확장 프로그램에서 사용하는 태그의 스키마를 정의합니다. 대상 예를 들어 'maven'은 확장자는 다음과 같이 정의될 수 있습니다.

# @rules_jvm_external//:extensions.bzl

_install = tag_class(attrs = {"artifacts": attr.string_list(), ...})
_artifact = tag_class(attrs = {"group": attr.string(), "artifact": attr.string(), ...})
maven = module_extension(
  implementation = _maven_impl,
  tag_classes = {"install": _install, "artifact": _artifact},
)

이러한 선언은 maven.installmaven.artifact 태그가 지정된 속성 스키마를 사용하여 지정됩니다.

모듈 확장 프로그램의 구현 함수는 repo와 유사함 module_ctx 객체를 가져오는 것을 제외하고 확장 프로그램 및 모든 관련 태그를 사용하는 모든 모듈에 대한 액세스 권한을 부여합니다. 그런 다음 구현 함수는 저장소 규칙을 호출하여 저장소를 생성합니다.

# @rules_jvm_external//:extensions.bzl

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")  # a repo rule
def _maven_impl(ctx):
  # This is a fake implementation for demonstration purposes only

  # collect artifacts from across the dependency graph
  artifacts = []
  for mod in ctx.modules:
    for install in mod.tags.install:
      artifacts += install.artifacts
    artifacts += [_to_artifact(artifact) for artifact in mod.tags.artifact]

  # call out to the coursier CLI tool to resolve dependencies
  output = ctx.execute(["coursier", "resolve", artifacts])
  repo_attrs = _process_coursier_output(output)

  # call repo rules to generate repos
  for attrs in repo_attrs:
    http_file(**attrs)
  _generate_hub_repo(name = "maven", repo_attrs)

확장 프로그램 ID

모듈 확장은 이름과 표시되는 .bzl 파일로 식별됩니다. (use_extension 호출에서) 다음 예에서 확장 프로그램 maven.bzl 파일 @rules_jvm_external//:extension.bzl로 식별되며 이름 maven:

maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")

다른 .bzl 파일에서 확장 프로그램을 다시 내보내면 새 ID가 부여됩니다. 두 버전의 확장 프로그램이 전이 모듈 그래프에서 모두 사용되는 경우 그러면 별도로 평가되며 연결된 태그만 볼 수 있습니다. 정보를 공유할 수 있습니다.

확장 프로그램 작성자는 사용자가 모듈 확장을 지원합니다..bzl

저장소 이름 및 공개 상태

확장 프로그램에서 생성된 저장소에는 module_repo_canonical_name~extension_name~repo_name 형태의 표준 이름이 있습니다. 루트 모듈의 module_repo_canonical_name 부분은 _main 문자열로 대체됩니다. 표준 이름 형식은 API를 참조해야 하며 언제든지 변경될 수 있습니다.

이 이름 지정 정책은 각 확장 프로그램에 자체 '저장소 네임스페이스'가 있음을 의미합니다. 이 고유한 확장 프로그램이 각각 동일한 이름의 저장소를 정의하거나 막을 수 있습니다. 또한 repository_ctx.name이 표준 이름을 보고한다는 의미입니다. (저장소 규칙에 지정된 이름과 동일하지 않음) 있습니다.

모듈 확장 프로그램에서 생성한 저장소를 고려할 때 여러 저장소 공개 상태 규칙을 적용할 수 있습니다.

  • Bazel 모듈 저장소는 MODULE.bazel 파일에 도입된 모든 저장소를 볼 수 있습니다. bazel_depuse_repo입니다.
  • 모듈 확장 프로그램이 생성한 저장소는 모듈 확장 프로그램에서 생성한 다른 모든 저장소 동일한 모듈 확장 프로그램 (저장소 규칙 호출에 지정된 이름 사용 합니다.
    • 이로 인해 충돌이 발생할 수 있습니다. 모듈 저장소가 foo로 표시되고 확장 프로그램은 지정된 이름 foo - 이 확장 프로그램으로 생성된 모든 저장소 foo는 전자를 나타냅니다.

권장사항

이 섹션에서는 확장 프로그램을 작성할 때의 권장사항을 설명합니다. 사용하기 쉽고 유지관리가 쉬우며 시간 경과에 따른 변화에 잘 적응할 수 있습니다.

각 확장 프로그램을 별도의 파일에 배치

확장자가 다른 파일에 있는 경우 하나의 확장 프로그램이 저장소가 생성됩니다 이 기능을 사용하지 않더라도 필요한 경우에 대비하여 별도의 파일에 저장하는 것이 좋습니다. 확인할 수 있습니다 이는 확장 프로그램의 ID가 파일을 기반으로 하기 때문입니다. 따라서 확장자가 나중에 공개 API를 변경하고 사용자에게 호환되지 않는 변경사항을 적용할 수 있습니다

운영체제 및 아키텍처 지정

확장 프로그램이 운영체제나 아키텍처 유형을 사용하는 경우 os_dependent를 사용하여 확장 프로그램 정의에 이를 나타내야 합니다. 및 arch_dependent 부울 속성이 있습니다. 이렇게 하면 Bazel이 둘 중 하나라도 변경사항이 있는 경우 재평가가 필요합니다.

루트 모듈만 저장소 이름에 직접 영향을 미쳐야 합니다.

확장 프로그램이 저장소를 만들면 확장 프로그램의 네임스페이스입니다. 즉, 서로 다른 위치에 있는 경우 충돌이 발생할 수 있으며 모듈은 동일한 확장자를 사용하며 결국 동일한 확장 프로그램을 사용하여 있습니다. 이는 모듈 확장 프로그램의 tag_classname이 있는 것으로 나타납니다. 인수의 name 값으로 전달됩니다.

예를 들어 루트 모듈인 A가 모듈 B에 종속된다고 가정해 보겠습니다. 두 모듈 모두 모듈 mylang에 종속됩니다. AB가 모두 호출되는 경우 mylang.toolchain(name="foo"), 둘 다 foo를 호출하면 오류가 발생합니다.mylang

이를 방지하려면 저장소 이름을 직접 설정하는 기능을 삭제하거나 또는 루트 모듈에서만 이렇게 할 수 있습니다. 루트 모듈이 이 작업을 아무것도 좌우하지 않으므로 대부분 충돌이 발생하는 다른 모듈이 있을 수 있습니다.