라벨은 타겟의 식별자입니다. 일반적인 라벨의 전체 표준 형식은 다음과 같습니다.
@@myrepo//my/app/main:app_binary
라벨의 첫 번째 부분은 저장소 이름인 @@myrepo
입니다. 이중 @
구문은 작업공간 내에서 고유한 표준 저장소 이름임을 나타냅니다. 표준 저장소 이름이 있는 라벨은 표시되는 컨텍스트와 관계없이 타겟을 명확하게 식별합니다.
표준 저장소 이름은 @@rules_java++toolchains+local_jdk
와 같은 난해한 문자열인 경우가 많습니다. 훨씬 더 일반적으로 보이는 것은 명백한 저장소 이름이 있는 라벨입니다. 이는 다음과 같습니다.
@myrepo//my/app/main:app_binary
유일한 차이점은 저장소 이름에 @
가 2개가 아닌 1개만 접두사로 붙는다는 것입니다.
이 라벨이 표시되는 컨텍스트에 따라 다를 수 있는 명시적 이름이 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
사양) 해당 라벨이 포함된 패키지를 참조합니다.
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
집합과 구두점 기호 !%-@^_"#$&'()*-+,;<=>?[]{|}~/.
에서 가져온 문자로만 구성되어야 합니다.
파일 이름은 일반 형식의 상대 경로 이름이어야 합니다. 즉, 슬래시로 시작하거나 끝나서는 안 되며 (예: /foo
및 foo/
은 금지됨) 경로 구분 기호로 연속된 슬래시가 여러 개 포함되어서도 안 됩니다(예: 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
파일은 규칙을 호출하여 타겟을 선언합니다.
아래 예에서는 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 쿼리 도구가 작동하는 도메인입니다.
대상 | BUILD 파일 |