Bazel 모듈

Bazel 모듈 은 여러 버전을 가질 수 있는 Bazel 프로젝트이며 각 버전은 종속된 다른 모듈에 관한 메타데이터를 게시합니다. 이는 Maven 아티팩트, npm 패키지, Go 모듈 또는 Cargo 크레이트와 같은 다른 종속 항목 관리 시스템의 익숙한 개념과 유사합니다.

모듈에는 저장소 루트에 MODULE.bazel 파일이 있어야 합니다. 이 파일은 모듈의 매니페스트로, 이름, 버전, 직접 종속 항목 목록 및 기타 정보를 선언합니다. 기본 예는 다음과 같습니다.

module(name = "my-module", version = "1.0")

bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")

전체 명령어 목록을 참고하세요. MODULE.bazel 파일에서 사용할 수 있습니다.

모듈 해결을 실행하기 위해 Bazel은 먼저 루트 모듈의 MODULE.bazel 파일을 읽은 다음 전체 종속 항목 그래프를 발견할 때까지 Bazel 레지스트리에서 종속 항목의 MODULE.bazel 파일을 반복적으로 요청합니다.

기본적으로 Bazel은 사용할 각 모듈의 버전을 하나 선택합니다. Bazel은 각 모듈을 저장소로 나타내고 레지스트리를 다시 참조하여 각 저장소를 정의하는 방법을 알아냅니다.

버전 형식

Bazel에는 다양한 생태계가 있으며 프로젝트는 다양한 버전 관리 체계를 사용합니다. 가장 인기 있는 것은 SemVer이지만 버전이 날짜 기반인 Abseil과 같은 다른 체계를 사용하는 유명한 프로젝트도 있습니다(예: 20210324.2).

이러한 이유로 Bazel은 SemVer 사양의 더 완화된 버전을 채택합니다. 차이점은 다음과 같습니다.

  • SemVer는 버전의 '출시' 부분이 MAJOR.MINOR.PATCH의 세그먼트 3개로 구성되어야 한다고 규정합니다. Bazel에서는 이 요구사항이 완화되어 세그먼트 수를 제한하지 않습니다.
  • SemVer에서 '출시' 부분의 각 세그먼트는 숫자만으로 구성되어야 합니다. Bazel에서는 이 요구사항이 완화되어 문자도 허용되며 비교 의미 체계는 '사전 출시' 부분의 '식별자'와 일치합니다.
  • 또한 주 버전, 부 버전, 패치 버전 증가의 의미 체계는 적용되지 않습니다.

유효한 SemVer 버전은 유효한 Bazel 모듈 버전입니다. 또한 두 SemVer 버전 ab는 Bazel 모듈 버전으로 비교할 때 동일하게 유지되는 경우에만 a < b를 비교합니다.

마지막으로 모듈 버전 관리에 관한 자세한 내용은 MODULE.bazel FAQ를 참고하세요.

버전 선택

버전 관리 종속 항목 공간의 기본 요소인 다이아몬드 종속 항목 문제를 고려해 보세요. 다음과 같은 종속 항목 그래프가 있다고 가정해 보세요.

       A 1.0
      /     \
   B 1.0    C 1.1
     |        |
   D 1.0    D 1.1

어떤 버전의 D를 사용해야 할까요? 이 질문을 해결하기 위해 Bazel은 최소 버전 선택 (MVS) 알고리즘을 사용합니다. MVS는 모듈의 모든 새 버전이 이전 버전과 호환된다고 가정하므로 종속 항목 (D 1.1은 예시)에서 지정한 가장 높은 버전을 선택합니다. D 1.1이 요구사항을 충족할 수 있는 가장 빠른 버전이므로 '최소'라고 합니다. D 1.2 이상이 있더라도 선택하지 않습니다. MVS를 사용하면 충실도 가 높고 재현 가능 한 버전 선택 프로세스가 생성됩니다.

Yanked 버전

레지스트리는 보안 취약점과 같이 피해야 하는 특정 버전을 yanked 로 선언할 수 있습니다. Bazel은 모듈의 yanked 버전을 선택할 때 오류를 발생시킵니다. 이 오류를 해결하려면 더 새로운, yanked가 아닌 버전으로 업그레이드하거나 --allow_yanked_versions 플래그를 사용하여 yanked 버전을 명시적으로 허용하세요.

재정의

MODULE.bazel 파일에서 재정의를 지정하여 Bazel 모듈 해결의 동작을 변경합니다. 루트 모듈의 재정의만 적용됩니다. 모듈이 종속 항목으로 사용되면 재정의는 무시됩니다.

각 재정의는 특정 모듈 이름에 지정되며 종속 항목 그래프의 모든 버전에 영향을 미칩니다. 루트 모듈의 재정의만 적용되지만 루트 모듈이 직접 종속되지 않는 전이 종속 항목에 적용될 수 있습니다.

단일 버전 재정의

single_version_override 는 여러 용도로 사용됩니다.

  • version 속성을 사용하면 종속 항목 그래프에서 요청된 종속 항목 버전에 관계없이 종속 항목을 특정 버전으로 고정할 수 있습니다.
  • registry 속성을 사용하면 일반 레지스트리 선택 프로세스를 따르는 대신 이 종속 항목이 특정 레지스트리에서 가져오도록 강제할 수 있습니다.
  • patch* 속성을 사용하면 다운로드한 모듈에 적용할 패치 집합을 지정할 수 있습니다.

이러한 속성은 모두 선택사항이며 서로 혼합하여 사용할 수 있습니다.

다중 버전 재정의

multiple_version_override 해결된 종속 항목 그래프에서 동일한 모듈의 여러 버전이 공존하도록 지정할 수 있습니다.

종속 항목 그래프에 동일한 모듈의 여러 버전이 남아 있는 경우 Bazel은 각 종속 항목에 대해 가장 가까운 더 높은 허용 버전을 선택합니다.

예를 들어 해결 전에 종속 항목 그래프에 버전 1.1, 1.3, 1.5, 1.7, 2.0이 있는 경우

  • 1.3, 1.7, 2.0을 허용하는 다중 버전 재정의는 1.11.3으로 업그레이드되고 1.51.7로 업그레이드되며 다른 버전은 동일하게 유지됩니다.
  • 1.92.0을 허용하는 다중 버전 재정의는 해결 전에 종속 항목 그래프에 1.9가 없으므로 오류가 발생합니다.

또한 사용자는 단일 버전 재정의와 마찬가지로 registry 속성을 사용하여 레지스트리를 재정의할 수도 있습니다.

비레지스트리 재정의

비레지스트리 재정의는 버전 해결에서 모듈을 완전히 삭제합니다. Bazel은 레지스트리에서 이러한 MODULE.bazel 파일을 요청하지 않고 저장소 자체에서 요청합니다.

Bazel은 다음과 같은 비레지스트리 재정의를 지원합니다.

모듈이 비레지스트리 재정의로 재정의될 때 소스 아카이브 MODULE.bazel에서 버전 값을 설정하면 단점이 있을 수 있습니다. 자세한 내용은 FAQ를 참고하세요.MODULE.bazel

Bazel 모듈을 나타내지 않는 저장소 정의

bazel_dep를 사용하면 다른 Bazel 모듈을 나타내는 저장소를 정의할 수 있습니다. Bazel 모듈을 나타내지 않는 저장소를 정의해야 하는 경우가 있습니다. 예를 들어 데이터로 읽을 일반 JSON 파일이 포함된 저장소입니다.

이 경우 use_repo_rule 명령어를 사용하여 저장소 규칙을 호출하여 저장소를 직접 정의할 수 있습니다. 이 저장소는 정의된 모듈에만 표시됩니다.

내부적으로 이는 모듈 확장 프로그램과 동일한 메커니즘을 사용하여 구현되므로 더 유연하게 저장소를 정의할 수 있습니다.

저장소 이름 및 엄격한 종속 항목

모듈을 직접 종속 항목에 지원하는 저장소의 표시 이름은 지시문의 repo_name 속성이 달리 지정하지 않는 한 기본적으로 모듈 이름으로 지정됩니다.bazel_dep 즉, 모듈은 직접 종속 항목만 찾을 수 있습니다. 이는 전이 종속 항목의 변경으로 인한 우발적인 손상을 방지하는 데 도움이 됩니다.

모듈을 지원하는 저장소의 표준 이름은 전체 종속 항목 그래프에 모듈의 여러 버전이 있는지에 따라 module_name+version (예: bazel_skylib+1.0.3) 또는 module_name+ (예: bazel_features+)입니다 (multiple_version_override 참고). 표준 이름 형식은 종속되어서는 안 되는 API이며 언제든지 변경될 수 있습니다. 표준 이름을 하드 코딩하는 대신 지원되는 방법을 사용하여 Bazel에서 직접 가져옵니다.

  • BUILD 및 .bzl 파일에서 저장소의 표시 이름으로 제공된 라벨 문자열에서 생성된 Label 인스턴스에서 Label.repo_name을 사용합니다(예: Label("@bazel_skylib").repo_name).
  • 실행 파일을 조회할 때는 $(rlocationpath ...) 또는 @bazel_tools//tools/{bash,cpp,java}/runfiles 또는 규칙 집합 rules_foo의 경우 @rules_foo//foo/runfiles에서 실행 파일 라이브러리 중 하나를 사용합니다.
  • IDE 또는 언어 서버와 같은 외부 도구에서 Bazel과 상호작용할 때는 bazel mod dump_repo_mapping 명령어를 사용하여 지정된 저장소 집합의 표시 이름에서 표준 이름으로의 매핑을 가져옵니다.

모듈 확장 프로그램은 모듈의 표시 범위에 추가 저장소 를 도입할 수도 있습니다.