저장소 규칙

문제 신고 소스 보기

이 페이지에서는 저장소 규칙을 정의하는 방법을 설명하고 자세한 예를 제공합니다.

외부 저장소는 Bazel 빌드에서 사용할 수 있는 소스 파일이 포함된 디렉터리 트리로, 해당 repo 규칙을 실행하여 요청 시 생성됩니다. 저장소는 다양한 방법으로 정의할 수 있지만, 빌드 대상을 빌드 규칙 호출로 정의하는 것처럼 최종적으로 저장소 규칙을 호출하여 각 저장소를 정의합니다. 이러한 라이브러리는 서드 파티 라이브러리 (예: Maven 패키지 라이브러리)에 의존하는 데 사용될 수 있고 Bazel이 실행되는 호스트와 관련된 BUILD 파일을 생성하기 위해서도 사용할 수 있습니다.

저장소 규칙 정의

.bzl 파일에서 repository_rule 함수를 사용하여 새 저장소 규칙을 정의하고 전역 변수에 저장합니다. 저장소 규칙을 정의한 후 이를 함수로 호출하여 저장소를 정의할 수 있습니다. 일반적으로 이 호출은 모듈 확장 구현 함수 내에서 실행됩니다.

저장소 규칙 정의의 두 가지 주요 구성요소는 속성 스키마와 구현 기능입니다. 속성 스키마는 저장소 규칙 호출에 전달되는 속성의 이름과 유형을 결정하며, 저장소를 가져와야 할 때 구현 함수가 실행됩니다.

특성

속성은 저장소 규칙 호출에 전달되는 인수입니다. 저장소 규칙에서 허용하는 속성 스키마는 repository_rule 호출로 저장소 규칙이 정의된 경우 attrs 인수를 사용하여 지정됩니다. 다음은 urlsha256 속성을 문자열로 정의하는 예입니다.

http_archive = repository_rule(
    implementation=_impl,
    local=True,
    attrs={
        "url": attr.string(mandatory=True)
        "sha256": attr.string(mandatory=True)
    }
)

구현 함수 내의 속성에 액세스하려면 repository_ctx.attr.<attribute_name>를 사용합니다.

def _impl(repository_ctx):
    url = repository_ctx.attr.url
    checksum = repository_ctx.attr.sha256

모든 repository_rule에는 암시적으로 정의된 속성 name가 있습니다. 이 속성은 마법처럼 작동하는 문자열 속성입니다. 저장소 규칙 호출에 대한 입력으로 지정되면 저장소 이름이 그대로 사용됩니다. 하지만 repository_ctx.attr.name를 사용하여 저장소 규칙의 구현 함수에서 읽으면 표준 저장소 이름이 반환됩니다.

구현 함수

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

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

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

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

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

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

저장소 규칙의 구현 함수는 Bazel이 해당 저장소의 대상이 필요할 때 (예: 다른 저장소의 다른 대상이 종속될 때 또는 명령줄에서 언급되는 경우) 실행됩니다. 그러면 구현 함수가 파일 시스템에 저장소를 만들어야 합니다. 이를 저장소 '가져오기'라고 합니다.

일반 대상과 달리 저장소가 다른 결과를 야기하는 변경사항이 있을 때 저장소를 반드시 다시 가져오지는 않습니다. Bazel이 변경사항을 감지할 수 없거나 모든 빌드 (예: 네트워크에서 가져온 항목)에 너무 많은 오버헤드가 발생하기 때문입니다. 따라서 다음 중 하나가 변경되는 경우에만 저장소를 다시 가져옵니다.

  • 저장소 규칙 호출에 전달되는 속성입니다.
  • 저장소 규칙의 구현을 구성하는 Starlark 코드
  • repository_ctxgetenv() 메서드에 전달되거나 repository_ruleenviron 속성으로 선언된 환경 변수의 값입니다. 이러한 환경 변수의 값은 --repo_env 플래그를 사용하여 명령줄에서 직접 지정할 수 있습니다.
  • read(), execute() 및 라벨에 의해 참조되는 repository_ctx의 유사한 메서드에 전달된 모든 파일의 콘텐츠 (예: mypkg/label.txt가 아닌 //mypkg:label.txt)
  • bazel fetch --force가 실행될 때

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

  • configure 플래그가 설정되면 --configure 매개변수가 전달될 때만 bazel fetch에서 저장소를 다시 가져옵니다. 속성이 설정되어 있지 않으면 이 명령어로 인해 다시 가져오기가 실행되지 않습니다.
  • 위의 사례 외에도 local 플래그를 설정하면 Bazel 서버가 다시 시작될 때 저장소를 다시 가져옵니다.

구현 함수 다시 시작

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

외부 저장소 강제 다시 가져오기

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

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

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

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

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