라벨

문제 신고하기 소스 보기

라벨은 대상의 식별자입니다. 완전한 표준 형식의 일반적인 라벨은 다음과 같습니다.

@@myrepo//my/app/main:app_binary

라벨의 첫 번째 부분은 저장소 이름 @@myrepo입니다. 이중 @ 문법은 작업공간 내에서 고유한 표준 저장소 이름을 나타냅니다. 표준 저장소 이름을 갖는 라벨은 라벨이 지정된 컨텍스트와 상관없이 대상을 명확하게 식별합니다.

표준 저장소 이름은 @@rules_java~7.1.0~toolchains~local_jdk처럼 보이는 신비로운 문자열인 경우가 많습니다. 훨씬 더 일반적으로 볼 수 있는 것은 다음과 같이 명확한 저장소 이름이 있는 라벨입니다.

@myrepo//my/app/main:app_binary

유일한 차이점은 저장소 이름에 두 개가 아닌 하나의 @가 접두사로 붙는다는 것입니다. 이는 이름이 myrepo인 저장소를 의미하며 이 라벨이 표시되는 컨텍스트에 따라 다를 수 있습니다.

일반적으로 라벨이 사용된 저장소와 동일한 저장소를 참조하는 경우 저장소 이름 부분이 생략될 수 있습니다. 따라서 @@myrepo 내에서 첫 번째 라벨은 일반적으로 다음과 같이 작성됩니다.

//my/app/main:app_binary

라벨의 두 번째 부분은 자격이 없는 패키지 이름 my/app/main이며 저장소 루트를 기준으로 한 패키지의 경로입니다. 저장소 이름과 정규화되지 않은 패키지 이름은 정규화된 패키지 이름 @@myrepo//my/app/main를 형성합니다. 라벨이 사용된 것과 동일한 패키지를 참조하면 패키지 이름 (및 선택적으로 콜론)을 생략할 수 있습니다. 따라서 @@myrepo//my/app/main 내에서 이 라벨을 다음 중 한 가지 방법으로 작성할 수 있습니다.

app_binary
:app_binary

파일에서는 콜론이 생략되지만 규칙에서는 유지되는 것이 일반적이지만 그 외의 경우에는 중요하지 않습니다.

콜론 다음에 있는 라벨의 부분인 app_binary은 자격이 없는 타겟 이름입니다. 패키지 경로의 마지막 구성요소와 일치하는 경우 패키지 및 콜론은 생략할 수 있습니다. 따라서 이 두 라벨은 동일합니다.

//my/app/lib
//my/app/lib:lib

패키지의 하위 디렉터리에 있는 파일 대상의 이름은 패키지 루트 (BUILD 파일을 포함하는 디렉터리)를 기준으로 한 파일의 경로입니다. 따라서 이 파일은 저장소의 my/app/main/testdata 하위 디렉터리에 있습니다.

//my/app/main:testdata/input.txt

//my/app@@some_repo//my/app 같은 문자열은 사용되는 컨텍스트에 따라 두 가지 의미가 있습니다. Bazel이 라벨을 예상할 때 각각 //my/app:app@@some_repo//my/app:app를 의미합니다. 그러나 Bazel이 패키지를 예상하면 (예: package_group 사양에서) Bazel은 이 라벨을 포함하는 패키지를 참조합니다.

BUILD 파일에서 흔히 발생하는 실수는 //my/app를 사용하여 패키지를 참조하거나 패키지의 모든 타겟을 참조하는 것입니다. //my/app:app와 동일하므로 현재 저장소의 my/app 패키지에 있는 app 대상의 이름을 지정합니다.

하지만 package_group 또는 .bzl 파일의 사양에서 패키지를 참조하는 데 //my/app를 사용하는 것이 좋습니다. 패키지 이름이 절대적이며 작업공간의 최상위 디렉터리에 루팅된다는 사실을 명확하게 전달하기 때문입니다.

상대 라벨은 다른 패키지의 대상을 참조하는 데 사용할 수 없습니다. 이 경우 항상 저장소 식별자와 패키지 이름을 지정해야 합니다. 예를 들어 소스 트리에 my/app 패키지와 my/app/testdata 패키지가 둘 다 포함되어 있다면 (이 두 디렉터리 각각에 자체 BUILD 파일이 있음) 후자의 패키지에는 testdepot.zip라는 파일이 포함됩니다. //my/app:BUILD 내에서 이 파일을 참조하는 방법에는 두 가지가 있습니다 (하나는 틀림, 하나는 정답).

잘못됨testdata는 다른 패키지이므로 상대 경로를 사용할 수 없습니다.

testdata/testdepot.zip

올바른 예 — 전체 경로와 함께 testdata 참조

//my/app/testdata:testdepot.zip

@@//로 시작하는 라벨은 기본 저장소를 참조하며, 외부 저장소에서도 계속 작동합니다. 따라서 @@//a/b/c는 외부 저장소에서 참조될 때 //a/b/c와 다릅니다. 전자는 기본 저장소를 다시 참조하고 후자는 외부 저장소 자체에서 //a/b/c를 찾습니다. 이는 특히 기본 저장소의 대상을 참조하는 규칙을 기본 저장소에서 작성할 때 관련이 있으며 외부 저장소에서 사용됩니다.

대상을 참조할 수 있는 다양한 방법에 대한 자세한 내용은 대상 패턴을 참조하세요.

라벨의 어휘 사양

라벨 구문은 셸에 특별한 의미를 갖는 메타 문자를 사용하지 않도록 합니다. 이렇게 하면 의도치 않은 따옴표 문제를 방지하는 데 도움이 되며 Bazel 쿼리 언어와 같이 라벨을 조작하는 도구와 스크립트를 더 쉽게 만들 수 있습니다.

허용되는 대상 이름에 대한 정확한 세부정보는 다음과 같습니다.

대상 이름 - package-name:target-name

target-name은 패키지 내의 타겟 이름입니다. 규칙 이름은 BUILD 파일의 규칙 선언에 있는 name 속성 값입니다. 파일 이름은 BUILD 파일이 포함된 디렉터리의 상대 경로 이름입니다.

타겟 이름은 a~z, A~Z, 0~9, 구두점 기호 !%-@^_"#$&'()*-+,;<=>?[]{|}~/.에서 가져온 문자로만 구성되어야 합니다.

파일 이름은 일반적인 형식의 상대 경로 이름이어야 합니다. 즉, 슬래시로 시작하거나 끝나지 않아야 하며 (예: /foofoo/는 금지됨), 경로 구분자로 여러 개의 연속 슬래시를 포함해야 합니다(예: foo//bar). 마찬가지로 상위 수준 참조 (..) 및 현재 디렉터리 참조 (./)도 금지됩니다.

잘못됨 — 다른 패키지의 파일을 참조하는 데 ..를 사용하지 마세요.

올바름//package-name:filename를 사용합니다.

파일 타겟 이름에 /를 사용하는 것이 일반적이지만 규칙 이름에 /를 사용하지 마세요. 특히 라벨의 축약형을 사용하면 독자가 혼란스러울 수 있습니다 //foo/bar/wiz 라벨은 이러한 패키지 foo/bar/wiz가 없더라도 항상 //foo/bar/wiz:wiz의 약식 표현입니다. 이는 타겟이 존재하더라도 //foo:bar/wiz를 참조하지 않습니다.

하지만 슬래시 사용이 편리하거나 경우에 따라 필요한 상황도 있습니다. 예를 들어 특정 규칙의 이름은 패키지의 하위 디렉터리에 상주할 수 있는 주 소스 파일과 일치해야 합니다.

패키지 이름 - //package-name:target-name

패키지 이름은 BUILD 파일이 포함된 디렉터리의 이름으로, 포함된 저장소의 최상위 디렉터리를 기준으로 합니다. 예를 들면 my/app입니다.

기술적 수준에서 Bazel은 다음을 적용합니다.

  • 패키지 이름에 허용되는 문자는 소문자 a~z, 대문자 A~Z, 숫자 0~9, ! \"#$%&'()*+,-.;<=>?@[]^_`{|} 문자 (공백 문자가 있음) 및 슬래시 / (디렉터리 구분자이므로)입니다.
  • 패키지 이름은 슬래시 문자(/)로 시작하거나 끝날 수 없습니다.
  • 패키지 이름에는 하위 문자열(//)을 포함할 수 없습니다. 이 방법은 이해가 되지 않습니다. 해당 디렉터리 경로는 무엇일까요?
  • 패키지 이름에는 하위 문자열 /./, /../ 또는 /.../ 등을 포함할 수 없습니다. 이러한 시행은 경로 문자열에서 점 문자의 의미론적 의미를 고려하여 논리적 패키지 이름과 실제 디렉터리 이름 간 변환 시 혼동을 피하기 위해 시행됩니다.

실용적인 면에서 다음과 같습니다.

  • 디렉터리 구조가 모듈 시스템에 중요한 언어 (예: Java)의 경우 언어에서 유효한 식별자인 디렉터리 이름을 선택하는 것이 중요합니다. 예를 들어 맨 앞의 숫자로 시작하지 말고 특수 문자(특히 밑줄 및 하이픈)를 사용하지 마세요.
  • Bazel이 작업공간의 루트 패키지 (예: //:foo)에 있는 대상을 지원하지만, 의미 있는 모든 패키지에 설명이 포함된 이름을 갖도록 이 패키지를 비워 두는 것이 가장 좋습니다.

규칙

규칙은 입력과 출력 간의 관계, 그리고 출력을 빌드하는 단계를 지정합니다. 규칙은 빌드 백과사전에 설명된 대로 컴파일된 실행 파일 및 라이브러리, 테스트 실행 파일 및 기타 지원되는 출력을 생성하는 다양한 종류 (규칙 클래스라고도 함) 중 하나일 수 있습니다.

BUILD 파일은 rules를 호출하여 대상을 선언합니다.

아래 예에서는 cc_binary 규칙을 사용하는 타겟 my_app의 선언을 볼 수 있습니다.

cc_binary(
    name = "my_app",
    srcs = ["my_app.cc"],
    deps = [
        "//absl/base",
        "//absl/strings",
    ],
)

모든 규칙 호출에는 BUILD 파일의 패키지 내에 대상을 선언하는 name 속성 (유효한 대상 이름이어야 함)이 있습니다.

모든 규칙에는 일련의 속성이 있습니다. 지정된 규칙의 적용 가능한 속성, 각 속성의 중요도와 의미는 규칙 종류의 기능입니다. 규칙 및 해당 속성의 목록은 빌드 백과사전을 참고하세요. 각 속성에는 이름과 유형이 있습니다. 속성에는 정수, 라벨, 라벨 목록, 문자열, 문자열 목록, 출력 라벨, 출력 라벨 목록이 있습니다. 모든 규칙에 모든 속성을 지정할 필요는 없습니다. 따라서 속성은 키 (이름)에서 선택적인 입력 값까지 사전을 형성합니다.

여러 규칙에 있는 srcs 속성은 '라벨 목록' 유형이며, 값이 있는 경우 값은 라벨 목록으로, 각 값은 이 규칙의 입력인 대상의 이름입니다.

경우에 따라 규칙 종류의 이름이 다소 임의적이며, 규칙에서 생성된 파일의 이름이 더 흥미롭습니다. 이는 genrule에도 적용됩니다. 자세한 내용은 일반 규칙: genrule을 참조하세요.

다른 경우에는 이름이 중요합니다. 예를 들어 *_binary*_test 규칙의 경우 규칙 이름이 빌드에 의해 생성된 실행 파일의 이름을 결정합니다.

대상에 대한 방향성 비순환 그래프를 대상 그래프 또는 빌드 종속 항목 그래프라고 하며, 이 도메인이 Bazel 쿼리 도구가 작동하는 도메인입니다.

대상 빌드 파일