날짜 비워 두기: BazelCon 2023이 10월 24~25일에 Google 뮌헨에서 열립니다. 자세히 알아보기

저장소 규칙

문제 신고 소스 보기

이 페이지에서는 저장소 규칙을 만드는 방법을 다루며 자세한 예를 제공합니다.

외부 저장소WORKSPACE 파일에서만 사용할 수 있는 규칙으로, Bazel의 로드 단계에서 기본 제공되지 않는 작업을 사용 설정합니다. 각 외부 저장소 규칙은 자체 BUILD 파일과 아티팩트가 있는 자체 작업공간을 만듭니다. 또한 서드 파티 라이브러리 (예: Maven 패키지 라이브러리)를 사용하는 데 사용할 수도 있지만 Bazel이 실행 중인 호스트와 관련된 BUILD 파일을 생성할 수도 있습니다.

저장소 규칙 생성

.bzl 파일에서 repository_rule 함수를 사용하여 새 저장소 규칙을 만들고 전역 변수에 저장합니다.

맞춤 저장소 규칙은 기본 저장소 규칙과 마찬가지로 사용할 수 있습니다. 필수 name 속성이 있으며 빌드 파일에 있는 모든 타겟을 @<name>//package:target로 참조할 수 있습니다. 여기서 <name>name 속성의 값입니다.

이 규칙은 명시적으로 빌드하거나 빌드의 종속 항목인 경우 로드됩니다. 이 경우 Bazel은 implementation 함수를 실행합니다. 이 함수는 저장소, 저장소 콘텐츠, BUILD 파일을 만드는 방법을 설명합니다.

속성

속성은 url 또는 sha256와 같은 규칙 인수입니다. 저장소 규칙을 정의할 때는 속성 및 유형을 나열해야 합니다.

local_repository = repository_rule(
    implementation=_impl,
    local=True,
    attrs={"path": attr.string(mandatory=True)})

속성에 액세스하려면 repository_ctx.attr.<attribute_name>를 사용하세요.

모든 repository_rule에는 빌드 규칙과 마찬가지로 암시적으로 정의된 속성이 있습니다. 두 암시적 속성은 name (빌드 규칙과 동일) 및 repo_mapping입니다. 저장소 규칙의 이름은 repository_ctx.name로 액세스할 수 있습니다. repo_mapping의 의미는 네이티브 저장소 규칙 local_repositorynew_local_repository의 경우와 동일합니다.

속성 이름이 _로 시작하는 경우 비공개이며 사용자가 설정할 수 없습니다.

구현 함수

모든 저장소 규칙에는 implementation 함수가 필요합니다. 이 규칙은 규칙의 실제 로직을 포함하며 로드 단계에서 엄격하게 실행됩니다.

이 함수에는 정확히 하나의 입력 매개변수인 repository_ctx이 있습니다. 이 함수는 지정된 매개변수를 사용하여 규칙을 재현할 수 있음을 나타내기 위해 None를 반환하거나, 해당 규칙을 동일한 저장소를 생성하는 재현 가능한 규칙으로 변환하는 매개변수의 매개변수 집합이 있는 dict를 반환합니다. 예를 들어 원래 지정한 플로팅 브랜치 대신 특정 커밋 식별자를 반환하는 git 저장소를 추적하는 규칙의 경우

입력 매개변수 repository_ctx는 속성 값 및 기본 제공되지 않는 함수 (바이너리 찾기, 바이너리 실행, 저장소에서 파일 만들기, 인터넷에서 파일 다운로드)에 액세스하는 데 사용할 수 있습니다. 자세한 내용은 라이브러리를 참고하세요. 예:

def _impl(repository_ctx):
  repository_ctx.symlink(repository_ctx.attr.path, "")

local_repository = repository_rule(
    implementation=_impl,
    ...)

구현 함수는 언제 실행되나요?

저장소의 구현 함수는 Bazel이 해당 저장소에서 타겟을 필요로 할 때 실행됩니다. 예를 들어 다른 저장소에 있는 다른 대상이 종속되거나 대상이 현재 명령줄에서 언급되는 경우입니다. 그러면 구현 함수가 파일 시스템에 저장소를 만들 것으로 예상됩니다. 이를 저장소 '가져오기'라고 합니다.

일반적인 대상과 달리 저장소가 달라질 수 있는 변경사항이 있을 때 저장소를 다시 가져오지 않아도 됩니다. 이는 Bazel이 변경사항을 감지할 수 없거나 모든 빌드에 과도한 오버헤드를 유발하기 때문입니다 (예: 네트워크에서 가져오는 항목). 따라서 다음 중 하나가 변경되는 경우에만 저장소를 다시 가져옵니다.

  • WORKSPACE 파일의 저장소 선언에 전달된 매개변수입니다.
  • 저장소 구현을 구성하는 Starlark 코드
  • repository_ruleenviron 속성으로 선언된 모든 환경 변수의 값입니다. 이러한 환경 변수의 값은 명령줄에서 --action_env 플래그를 사용하여 하드웨어에 직접 연결할 수 있습니다. 하지만 이 플래그는 빌드의 모든 작업을 무효화합니다.
  • 라벨에서 참조하는 read(), execute() 및 유사한 repository_ctx 메서드에 전달된 모든 파일의 콘텐츠 (예: //mypkg:label.txt, mypkg/label.txt 아님)
  • bazel sync가 실행되는 경우

저장소를 다시 가져오는 시점을 제어하는 repository_rule 매개변수는 다음과 같이 두 가지가 있습니다.

  • configure 플래그가 설정되면 --configure 매개변수가 저장소에 전달될 때만 저장소가 bazel sync에 다시 가져옵니다. 이 속성이 설정되지 않은 경우 이 명령어로 인해 다시 가져오기가 발생하지 않습니다.
  • local 플래그가 설정된 경우 위의 변경사항 외에도 저장소 선언에 영향을 미치는 파일이 변경되는 경우 (예: WORKSPACE 파일 또는 로드하는 파일) 저장소 또는 코드 선언의 변경 여부와 관계없이 저장소를 다시 가져옵니다.

    이 경우 로컬이 아닌 저장소는 다시 가져오지 않습니다. 이러한 저장소는 네트워크와 통신하거나 비용이 많이 들기 때문입니다.

구현 함수 다시 시작

요청하는 종속 항목이 누락되면 저장소를 가져오는 동안 구현 함수를 다시 시작할 수 있습니다. 이 경우 구현 함수의 실행이 중지되고 누락된 종속 항목이 결정되며 종속 항목이 해결된 후 함수가 다시 실행됩니다. 네트워크 액세스를 반복해야 할 수 있으므로 불필요한 다시 시작을 방지하기 위해 모든 라벨 인수를 기존 파일로 확인할 수 있는 경우 라벨 인수를 미리 가져옵니다. 함수를 실행하는 동안에만 구성된 문자열이나 라벨의 경로를 확인하면 다시 시작될 수 있습니다.

외부 저장소 강제 가져오기

외부 저장소가 정의 또는 종속 항목을 변경하지 않으면 오래된 상태가 될 수 있습니다. 예를 들어 소스를 가져오는 저장소는 서드 파티 저장소의 특정 브랜치를 따를 수 있고 이 브랜치에서 새 커밋을 사용할 수 있습니다. 이 경우 bazel sync를 호출하여 bazel에 모든 외부 저장소를 무조건 다시 가져오도록 요청할 수 있습니다.

또한 일부 규칙은 로컬 머신을 검사하며 로컬 머신이 업그레이드되면 오래된 상태가 될 수 있습니다. 여기서 repository_rule 정의에 configure 속성이 설정된 외부 저장소만 다시 가져오도록 bazel에 요청할 수 있습니다. bazel sync --configure를 사용하세요.

  • C++ 자동 구성 도구 모음: 저장소 규칙을 사용하여 로컬 C++ 컴파일러, 환경, C++ 컴파일러에서 지원하는 플래그를 찾아 Bazel용 C++ 구성 파일을 자동으로 만듭니다.

  • Go 저장소는 여러 repository_rule를 사용하여 Go 규칙을 사용하는 데 필요한 종속 항목 목록을 정의합니다.

  • rules_jvm_external은 전이 종속 항목 트리에 있는 모든 Maven 아티팩트의 빌드 타겟을 생성하는 기본적으로 @maven라는 외부 저장소를 만듭니다.