외부 종속 항목 개요

Bazel은 작업공간에 없는 빌드에 사용되는 소스 파일 (텍스트 및 바이너리)인 외부 종속 항목을 지원합니다. 예를 들어 GitHub 저장소에 호스팅된 규칙 집합, Maven 아티팩트 또는 현재 작업공간 외부의 로컬 머신에 있는 디렉터리일 수 있습니다.

이 문서에서는 일부 개념을 자세히 살펴보기 전에 시스템의 개요를 제공합니다.

시스템 개요

Bazel의 외부 종속 항목 시스템은 버전이 지정된 Bazel 프로젝트인 Bazel 모듈과 소스 파일이 포함된 디렉터리 트리인 저장소 (또는 저장소)를 기반으로 작동합니다.

Bazel은 루트 모듈, 즉 작업 중인 프로젝트에서 시작합니다. 모든 모듈과 마찬가지로 디렉터리 루트에 기본 메타데이터와 직접 종속 항목을 선언하는 MODULE.bazel 파일이 있어야 합니다. 다음은 기본적인 예입니다.

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

bazel_dep(name = "rules_cc", version = "0.1.1")
bazel_dep(name = "platforms", version = "0.0.11")

여기에서 Bazel은 기본적으로 Bazel Central RegistryBazel 레지스트리에서 모든 전이 종속 항목 모듈을 조회합니다. 레지스트리는 종속 항목의 MODULE.bazel 파일을 제공하므로 Bazel은 버전 확인을 실행하기 전에 전체 전이 종속 항목 그래프를 검색할 수 있습니다.

각 모듈에 대해 하나의 버전이 선택되는 버전 확인 후 Bazel은 레지스트리를 다시 참조하여 각 모듈의 저장소를 정의하는 방법 즉 각 종속 항목 모듈의 소스를 가져오는 방법을 알아냅니다. 대부분의 경우 인터넷에서 다운로드하여 압축을 푼 보관 파일입니다.

모듈은 모듈 확인 후 모듈 확장 프로그램에서 소비하여 추가 저장소를 정의하는 태그라는 맞춤설정된 데이터 조각을 지정할 수도 있습니다. 이러한 확장 프로그램은 파일 I/O 및 네트워크 요청 전송과 같은 작업을 실행할 수 있습니다. 무엇보다도 Bazel 모듈로 빌드된 종속 항목 그래프를 준수하면서 Bazel이 다른 패키지 관리 시스템과 상호작용할 수 있도록 합니다.

세 가지 종류의 저장소 (작업 중인 소스 트리인 기본 저장소, 전이 종속 항목 모듈을 나타내는 저장소, 모듈 확장 프로그램으로 만든 저장소)가 함께 작업공간을 구성합니다. 외부 저장소 (기본이 아닌 저장소)는 BUILD 파일의 라벨 (예: @repo//pkg:target)에서 참조될 때와 같이 필요할 때 가져옵니다.

이점

Bazel의 외부 종속 항목 시스템은 다양한 이점을 제공합니다.

자동 종속 항목 해결

  • 결정적 버전 확인: Bazel은 결정적 MVS 버전 확인 알고리즘을 채택하여 충돌을 최소화하고 다이아몬드 종속 항목 문제를 해결합니다.
  • 간소화된 종속 항목 관리: MODULE.bazel은 직접 종속 항목만 선언하는 반면 전이 종속 항목은 자동으로 해결되어 프로젝트의 종속 항목에 대한 더 명확한 개요를 제공합니다.
  • 엄격한 종속 항목 공개 상태: 직접 종속 항목만 표시되어 정확성과 예측 가능성을 보장합니다.

생태계 통합

고급 기능

개념

이 섹션에서는 외부 종속 항목과 관련된 개념을 자세히 설명합니다.

모듈

여러 버전을 가질 수 있는 Bazel 프로젝트로, 각 버전은 다른 모듈에 종속될 수 있습니다.

로컬 Bazel 작업공간에서 모듈은 저장소로 표시됩니다.

자세한 내용은 Bazel 모듈을 참조하세요.

저장소

루트에 경계 마커 파일이 있고 Bazel 빌드에 사용할 수 있는 소스 파일이 포함된 디렉터리 트리입니다. 종종 저장소 로 줄여서 사용됩니다.

저장소 경계 마커 파일은 MODULE.bazel (이 저장소가 Bazel 모듈을 나타냄) , REPO.bazel (아래 참고) 또는 기존 컨텍스트의 WORKSPACE 또는 WORKSPACE.bazel일 수 있습니다. 저장소 경계 마커 파일 은 저장소의 경계를 나타냅니다. 이러한 파일은 여러 개가 디렉터리에 공존할 수 있습니다.

기본 저장소

현재 Bazel 명령어가 실행 중인 저장소입니다.

기본 저장소의 루트는 작업공간 루트 라고도 합니다.

작업공간

동일한 기본 저장소에서 실행되는 모든 Bazel 명령어에서 공유하는 환경입니다. 기본 저장소와 정의된 모든 외부 저장소 집합을 포함합니다.

이전에는 '저장소'와 '작업공간'의 개념이 혼동되었으며 '작업공간'이라는 용어가 기본 저장소를 지칭하는 데 자주 사용되었고 때로는 '저장소'의 동의어로 사용되기도 했습니다.

표준 저장소 이름

저장소를 항상 주소 지정할 수 있는 이름입니다. 작업공간 컨텍스트 내에서 각 저장소에는 하나의 표준 이름이 있습니다. 표준 이름이 canonical_name인 저장소 내의 대상은 라벨 @@canonical_name//package:target (이중 @에 유의)으로 주소 지정할 수 있습니다.

기본 저장소의 표준 이름은 항상 빈 문자열입니다.

표시되는 저장소 이름

특정 다른 저장소의 컨텍스트에서 저장소를 주소 지정할 수 있는 이름입니다. 저장소의 "닉네임"으로 생각할 수 있습니다. 표준 이름 michael인 저장소는 alice 저장소의 컨텍스트에서 표시되는 이름이 mike일 수 있지만 bob 저장소의 컨텍스트에서는 표시되는 이름이 mickey일 수 있습니다. 이 경우 michael 내의 대상은 alice 컨텍스트에서 라벨 @mike//package:target (단일 @에 유의)으로 주소 지정할 수 있습니다.

반대로 '표시되는 저장소 이름'에서 '표준 저장소 이름'으로의 매핑을 유지하는 각 저장소인 저장소 매핑으로 이해할 수 있습니다.

저장소 규칙

Bazel에 저장소를 구체화하는 방법을 알려주는 저장소 정의의 스키마입니다. 예를 들어 '특정 URL에서 zip 보관 파일을 다운로드하고 압축을 풉니다' 또는 '특정 Maven 아티팩트를 가져와서 java_import 대상으로 사용할 수 있도록 합니다' 또는 단순히 '로컬 디렉터리를 심볼릭 링크합니다'일 수 있습니다. 모든 저장소는 정의 됩니다 적절한 수의 인수로 저장소 규칙을 호출하여.

자체 저장소 규칙을 작성하는 방법에 관한 자세한 내용은 저장소 규칙을 참조하세요.

가장 일반적인 저장소 규칙은 http_archive URL에서 보관 파일을 다운로드하고 압축을 푸는 것과 이미 Bazel 저장소인 로컬 디렉터리를 심볼릭 링크하는 local_repository 것입니다.

저장소 가져오기

연결된 저장소 규칙을 실행하여 로컬 디스크에서 저장소를 사용할 수 있도록 하는 작업입니다. 작업공간에 정의된 저장소는 가져오기 전에 로컬 디스크에서 사용할 수 없습니다.

일반적으로 Bazel은 저장소에서 무언가가 필요하고 저장소가 아직 가져오지 않은 경우에만 저장소를 가져옵니다. 저장소가 이전에 가져온 경우 Bazel은 정의가 변경된 경우에만 다시 가져옵니다.

fetch 명령어를 사용하여 빌드를 실행하는 데 필요한 저장소, 대상 또는 모든 저장소의 미리 가져오기를 시작할 수 있습니다. 이 기능을 사용하면 --nofetch 옵션을 사용하여 오프라인 빌드를 실행할 수 있습니다.

--fetch 옵션은 네트워크 액세스를 관리하는 데 사용됩니다. 기본값은 true입니다. 하지만 false (--nofetch)로 설정하면 명령어는 종속 항목의 캐시된 버전을 사용하고, 캐시된 버전이 없으면 명령어는 실패합니다.

가져오기 제어에 관한 자세한 내용은 가져오기 옵션을(를) 참조하세요.

디렉터리 레이아웃

가져온 후 저장소는 표준 이름 아래 출력 기본의 external 하위 디렉터리에서 찾을 수 있습니다.

다음 명령어를 실행하여 표준 이름이 canonical_name인 저장소의 콘텐츠를 확인할 수 있습니다.

ls $(bazel info output_base)/external/ canonical_name 

REPO.bazel 파일

REPO.bazel 파일은 저장소를 구성하는 디렉터리 트리의 최상위 경계를 표시하는 데 사용됩니다. 저장소 경계 파일 역할을 하기 위해 아무것도 포함할 필요는 없지만 저장소 내의 모든 빌드 대상에 대한 몇 가지 일반적인 속성을 지정하는 데 사용할 수도 있습니다.

REPO.bazel 파일의 문법은 BUILD 파일과 유사하며, load 구문은 지원되지 않습니다. repo() 함수는 BUILD 파일의 package() 함수와 동일한 인수를 사용합니다. package() 는 패키지 내의 모든 빌드 대상에 대한 일반적인 속성을 지정하는 반면 repo() 는 저장소 내의 모든 빌드 대상에 대해 유사하게 실행합니다.

예를 들어 다음 REPO.bazel 파일을 사용하여 저장소의 모든 대상에 대한 일반적인 라이선스를 지정할 수 있습니다.

repo(
    default_package_metadata = ["//:my_license"],
)

기존 WORKSPACE 시스템

이전 Bazel 버전 (9.0 이전)에서는 WORKSPACE (또는 WORKSPACE.bazel) 파일에서 저장소를 정의하여 외부 종속 항목을 도입했습니다. 이 파일은 빌드 규칙 대신 저장소 규칙을 사용하는 BUILD 파일과 유사한 문법을 가지고 있습니다.

다음 스니펫은 http_archive 저장소 규칙을 WORKSPACE 파일에서 사용하는 예입니다.

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

이 스니펫은 표준 이름이 foo인 저장소를 정의합니다. WORKSPACE 시스템에서 기본적으로 저장소의 표준 이름은 다른 모든 저장소에 표시되는 이름이기도 합니다.

전체 함수 목록을(를) 참고하세요. WORKSPACE 파일에서 사용할 수 있습니다.

WORKSPACE 시스템의 단점

WORKSPACE 시스템이 도입된 후 사용자는 다음과 같은 여러 가지 문제점을 보고했습니다.

  • Bazel은 종속 항목의 WORKSPACE 파일을 평가하지 않으므로 모든 전이 종속 항목은 직접 종속 항목 외에도 기본 저장소의 WORKSPACE 파일에 정의해야 합니다.
  • 이 문제를 해결하기 위해 프로젝트는 여러 저장소를 정의하는 매크로를 정의하고 사용자에게 WORKSPACE 파일에서 이 매크로를 호출하도록 요청하는 "deps.bzl" 패턴을 채택했습니다.
    • 여기에는 자체 문제가 있습니다. 매크로는 다른 .bzl 파일을 load할 수 없으므로 이러한 프로젝트는 이 "deps" 매크로에서 전이 종속 항목을 정의하거나 사용자가 여러 계층화된 "deps" 매크로를 호출하도록 하여 이 문제를 해결해야 합니다.
    • Bazel은 WORKSPACE 파일을 순차적으로 평가합니다. 또한 종속 항목은 URL과 함께 http_archive을 사용하여 지정되며 버전 정보는 없습니다. 즉, 다이아몬드 종속 항목 (ABC에 종속됨, BC는 모두 D의 다른 버전에 종속됨)의 경우 버전 확인을 실행하는 안정적인 방법이 없습니다.

WORKSPACE의 단점으로 인해 새로운 모듈 기반 시스템('Bzlmod'라는 코드명 )이 Bazel 6과 9 사이에서 기존 WORKSPACE 시스템을 점차 대체했습니다. Bzlmod로 마이그레이션하는 방법은 Bzlmod 마이그레이션 가이드를 참고하세요.