목차
패키지
package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)
이 함수는 패키지의 모든 규칙에 적용되는 메타데이터를 선언합니다. 패키지 (BUILD 파일) 내에서 최대 한 번 사용됩니다.
전체 저장소의 모든 규칙에 적용되는 메타데이터를 선언하는 대응 항목의 경우 저장소의 루트에 있는 REPO.bazel 파일에서 repo() 함수를 사용하세요.
repo() 함수는 package()와 정확히 동일한 인수를 사용합니다.
package() 함수는 파일 상단의 모든 load() 문 바로 뒤에 규칙 전에 호출해야 합니다.
인수
| 속성 | 설명 |
|---|---|
default_applicable_licenses |
|
default_visibility |
라벨 목록입니다. 기본값은 이 패키지의 최상위 규칙 타겟과 심볼릭 매크로의 기본 공개 상태입니다. 즉, 심볼릭 매크로 내에 선언되지 않은 타겟과 심볼릭 매크로입니다. 타겟 또는 매크로가 이 속성의 구문에 관한 자세한 내용은 공개 상태 문서를 참고하세요. 패키지 기본 공개 상태는 기본적으로 공개 상태인 exports_files에는 적용되지 않습니다. |
default_deprecation |
문자열, 기본값은 이 패키지에 있는 모든 규칙의 기본
|
default_package_metadata |
라벨 목록입니다. 기본값은 패키지의 다른 모든 타겟에 적용되는 기본 메타데이터 타겟 목록을 설정합니다. 일반적으로 OSS 패키지 및 라이선스 선언과 관련된 타겟입니다. 예시는 rules_license를 참고하세요. |
default_testonly |
불리언, 명시된 경우를 제외하고 기본값은 이 패키지에 있는 모든 규칙의 기본
|
features |
문자열 목록입니다. 기본값은 이 BUILD 파일의 의미에 영향을 미치는 다양한 플래그를 설정합니다. 이 기능은 빌드 시스템에서 작업하는 사람이 특별한 처리가 필요한 패키지에 태그를 지정하는 데 주로 사용됩니다. 빌드 시스템을 담당하는 사람이 명시적으로 요청하지 않는 한 사용하지 마세요. |
예
아래 선언은 이 패키지의 규칙이 패키지 그룹//foo:target의 구성원에게만 표시된다고 선언합니다. 규칙에 개별 공개 상태 선언이 있는 경우 이 사양보다 우선합니다.
package(default_visibility = ["//foo:target"])
package_group
package_group(name, packages, includes)
이 함수는 패키지 집합을 정의하고 라벨을 집합과 연결합니다. 라벨은 visibility 속성에서 참조할 수 있습니다.
패키지 그룹은 주로 공개 상태 제어에 사용됩니다. 공개적으로 표시되는 타겟은 소스 트리의 모든 패키지에서 참조할 수 있습니다. 비공개로 표시되는 타겟은 자체 패키지 (하위 패키지 아님) 내에서만 참조할 수 있습니다. 이러한 극단적인 경우 사이에서 타겟은 자체 패키지뿐만 아니라 하나 이상의 패키지 그룹으로 설명된 패키지에도 액세스할 수 있습니다. 공개 상태 시스템에 관한 자세한 설명은 공개 상태 속성을 참고하세요.
지정된 패키지가 packages 속성과 일치하거나 includes 속성에 언급된 다른 패키지 그룹 중 하나에 이미 포함되어 있으면 해당 패키지가 그룹에 있는 것으로 간주됩니다.
패키지 그룹은 기술적으로 타겟이지만 규칙에 의해 생성되지 않으며 자체적으로는 가시성 보호가 없습니다.
인수
| 속성 | 설명 |
|---|---|
name |
이름: 필수 이 타겟의 고유한 이름입니다. |
packages |
문자열 목록입니다. 기본값은 0개 이상의 패키지 사양 목록입니다. 각 패키지 사양 문자열은 다음 형식 중 하나를 가질 수 있습니다.
또한 처음 두 종류의 패키지 사양에는 부정되었음을 나타내는 패키지 그룹에는 하나 이상의 긍정 사양과 일치하고 부정 사양과 일치하지 않는 패키지가 포함됩니다. 예를 들어 값 공개 상태 외에는 현재 저장소 외부의 패키지를 직접 지정할 방법이 없습니다. 이 속성이 누락되면 빈 목록으로 설정하는 것과 동일하며, 이는 참고: Bazel 6.0 이전에는 사양 참고: Bazel 6.0 이전에는 이 속성이 |
includes |
라벨 목록입니다. 기본값은 이 패키지에 포함된 다른 패키지 그룹입니다. 이 속성의 라벨은 다른 패키지 그룹을 참조해야 합니다.
참조된 패키지 그룹의 패키지는 이 패키지 그룹의 일부로 간주됩니다. 이는 전이적입니다. 패키지 그룹 부정된 패키지 사양과 함께 사용되는 경우 각 그룹의 패키지 집합이 먼저 독립적으로 계산되고 결과가 통합됩니다. 즉, 한 그룹의 부정된 사양은 다른 그룹의 사양에 영향을 미치지 않습니다. |
예
다음 package_group 선언은 열대 과일을 포함하는 'tropical'이라는 패키지 그룹을 지정합니다.
package_group(
name = "tropical",
packages = [
"//fruits/mango",
"//fruits/orange",
"//fruits/papaya/...",
],
)
다음 선언은 가상 애플리케이션의 패키지 그룹을 지정합니다.
package_group(
name = "fooapp",
includes = [
":controller",
":model",
":view",
],
)
package_group(
name = "model",
packages = ["//fooapp/database"],
)
package_group(
name = "view",
packages = [
"//fooapp/swingui",
"//fooapp/webui",
],
)
package_group(
name = "controller",
packages = ["//fooapp/algorithm"],
)
exports_files
exports_files([label, ...], visibility, licenses)
exports_files()는 이 패키지에 속하며 다른 패키지로 내보내지는 파일 목록을 지정합니다.
패키지의 BUILD 파일은 exports_files() 문으로 명시적으로 내보낸 경우에만 다른 패키지에 속하는 소스 파일을 직접 참조할 수 있습니다. 파일 공개 상태에 관해 자세히 알아보세요.
이전 동작에 따라 규칙의 입력으로 언급된 파일도 --incompatible_no_implicit_file_export 플래그가 전환될 때까지 기본 공개 상태로 내보내집니다. 하지만 이 동작에 의존해서는 안 되며 적극적으로 이전해야 합니다.
인수
인수는 현재 패키지 내 파일 이름 목록입니다. 공개 상태 선언을 지정할 수도 있습니다. 이 경우 파일은 지정된 타겟에 표시됩니다. 공개 상태가 지정되지 않으면 package 함수에 패키지 기본 공개 상태가 지정된 경우에도 모든 패키지에 파일이 표시됩니다. 라이선스도 지정할 수 있습니다.
예
다음 예에서는 다른 패키지가 테스트의 data 속성에서와 같이 사용할 수 있도록 test_data 패키지에서 텍스트 파일인 golden.txt를 내보냅니다.
# from //test_data/BUILD exports_files(["golden.txt"])
glob
glob(include, exclude=[], exclude_directories=1, allow_empty=True)
Glob은 특정 경로 패턴과 일치하는 모든 파일을 찾아 경로의 정렬된 새 변경 가능한 목록을 반환하는 도우미 함수입니다. 글로브는 자체 패키지의 파일만 검색하고 소스 파일만 찾습니다 (생성된 파일이나 기타 타겟은 아님).
파일의 패키지 상대 경로가 include 패턴 중 하나와 일치하고 exclude 패턴과 일치하지 않으면 소스 파일의 라벨이 결과에 포함됩니다.
include 및 exclude 목록에는 현재 패키지를 기준으로 하는 경로 패턴이 포함됩니다. 모든 패턴은 하나 이상의 경로 세그먼트로 구성될 수 있습니다. Unix 경로와 마찬가지로 이러한 세그먼트는 /로 구분됩니다. 패턴의 세그먼트는 경로의 세그먼트와 일치합니다. 세그먼트에는 * 와일드 카드가 포함될 수 있습니다. 이는 디렉터리 구분자 /를 제외한 경로 세그먼트의 모든 하위 문자열 (빈 하위 문자열 포함)과 일치합니다. 이 와일드 카드는 하나의 경로 세그먼트 내에서 여러 번 사용할 수 있습니다. 또한 ** 와일드 카드는 0개 이상의 전체 경로 세그먼트와 일치할 수 있지만 독립형 경로 세그먼트로 선언해야 합니다.
foo/bar.txt은 이 패키지의foo/bar.txt파일과 정확히 일치합니다 (foo/이 하위 패키지가 아닌 경우).- 파일이
.txt로 끝나면foo/*.txt는foo/디렉터리의 모든 파일과 일치합니다 (foo/이 하위 패키지가 아닌 경우). foo/a*.htm*는a로 시작하고, 임의의 문자열 (비어 있을 수 있음)이 있으며,.htm이 있고, 다른 임의의 문자열로 끝나는foo/디렉터리의 모든 파일과 일치합니다(foo/이 하위 패키지가 아닌 경우). 예를 들어foo/axx.htm,foo/a.html,foo/axxx.html와 같습니다.foo/*는foo/디렉터리의 모든 파일과 일치합니다(foo/가 하위 패키지가 아닌 경우).exclude_directories가 0으로 설정되어 있어도foo디렉터리 자체와는 일치하지 않습니다.foo/**는 패키지의 첫 번째 수준 하위 디렉터리foo/아래에 있는 모든 비 하위 패키지 하위 디렉터리의 모든 파일과 일치합니다.exclude_directories이 0으로 설정된 경우foo디렉터리도 패턴과 일치합니다. 이 경우**은 경로 세그먼트 0개와 일치하는 것으로 간주됩니다.**/a.txt는 이 패키지의 디렉터리에 있는a.txt파일과 하위 패키지가 아닌 하위 디렉터리와 일치합니다.- 결과 경로에
bar(예:xxx/bar/yyy/zzz/a.txt또는bar/a.txt(**도 세그먼트 0개와 일치함) 또는bar/zzz/a.txt)라는 디렉터리가 하나 이상 있는 경우**/bar/**/*.txt는 이 패키지의 모든 비 하위 패키지 하위 디렉터리의 모든.txt파일과 일치합니다. **는 이 패키지의 모든 비 하위 패키지 하위 디렉터리의 모든 파일과 일치합니다.foo**/a.txt은(는) 잘못된 패턴입니다.**이(가) 세그먼트로 자체적으로 존재해야 하기 때문입니다.foo/는 잘못된 패턴입니다./뒤에 정의된 두 번째 세그먼트가 빈 문자열이기 때문입니다.
exclude_directories 인수가 사용 설정된 경우 (1로 설정) 디렉터리 유형의 파일이 결과에서 생략됩니다 (기본값 1).
allow_empty 인수가 False로 설정된 경우 결과가 빈 목록이면 glob 함수에서 오류가 발생합니다.
몇 가지 중요한 제한사항과 주의사항이 있습니다.
-
glob()는 BUILD 파일 평가 중에 실행되므로glob()는 소스 트리의 파일만 일치시키고 생성된 파일은 일치시키지 않습니다. 소스 파일과 생성된 파일이 모두 필요한 타겟을 빌드하는 경우 생성된 파일의 명시적 목록을 glob에 추가해야 합니다.:mylib및:gen_java_srcs이 포함된 아래 예를 참고하세요. -
규칙의 이름이 일치하는 소스 파일과 동일하면 규칙이 파일을 '섀도우'합니다.
이를 이해하려면
glob()는 경로 목록을 반환하므로 다른 규칙의 속성 (예:srcs = glob(["*.cc"]))에서glob()를 사용하는 것은 일치하는 경로를 명시적으로 나열하는 것과 동일한 효과가 있습니다. 예를 들어glob()가["Foo.java", "bar/Baz.java"]를 생성하지만 패키지에 'Foo.java'라는 규칙도 있는 경우(허용되지만 Bazel에서 경고함)glob()의 소비자는 'Foo.java' 파일 대신 'Foo.java' 규칙(출력)을 사용합니다. 자세한 내용은 GitHub 문제 #10395를 참고하세요. - 글롭은 하위 디렉터리의 파일과 일치할 수 있습니다. 하위 디렉터리 이름은 와일드 카드로 지정할 수 있습니다. 하지만...
-
라벨은 패키지 경계를 교차할 수 없으며 glob은 하위 패키지의 파일과 일치하지 않습니다.
예를 들어 패키지
x의 glob 표현식**/*.cc에는x/y이 패키지로 있는 경우 (x/y/BUILD또는 패키지 경로의 다른 위치)x/y/z.cc이 포함되지 않습니다. 즉, glob 표현식의 결과는 실제로 BUILD 파일의 존재에 따라 달라집니다. 즉,x/y이라는 패키지가 없거나 --deleted_packages 플래그를 사용하여 삭제된 것으로 표시된 경우 동일한 glob 표현식에x/y/z.cc이 포함됩니다. - 위의 제한사항은 사용된 와일드 카드와 관계없이 모든 glob 표현식에 적용됩니다.
-
.로 시작하는 파일 이름이 있는 숨김 파일은**및*와일드 카드 모두와 완전히 일치합니다. 복합 패턴으로 숨김 파일을 일치시키려면 패턴이.로 시작해야 합니다. 예를 들어*및.*.txt은.foo.txt과 일치하지만*.txt은 일치하지 않습니다. 숨겨진 디렉터리도 같은 방식으로 일치합니다. 숨겨진 디렉터리에는 입력으로 필요하지 않은 파일이 포함될 수 있으며 불필요하게 glob된 파일 수와 메모리 소비가 증가할 수 있습니다. 숨겨진 디렉터리를 제외하려면 'exclude' 목록 인수에 추가합니다. -
'**' 와일드 카드에는 한 가지 특이 사례가 있습니다.
"**"패턴은 패키지의 디렉터리 경로와 일치하지 않습니다. 즉,glob(["**"], exclude_directories = 0)는 현재 패키지의 디렉터리 바로 아래에 있는 모든 파일과 디렉터리를 매칭합니다(하지만 하위 패키지의 디렉터리로는 이동하지 않음 - 이에 관한 이전 참고사항 참고).
일반적으로 glob 패턴에 대해 '*'를 사용하는 대신 적절한 확장 프로그램 (예: *.html)을 제공해야 합니다. 더 명시적인 이름은 자체 문서화되어 있으며 백업 파일이나 emacs/vi/... 자동 저장 파일이 실수로 일치하지 않도록 합니다.
빌드 규칙을 작성할 때 glob의 요소를 열거할 수 있습니다. 이렇게 하면 모든 입력에 대해 개별 규칙을 생성할 수 있습니다. 아래의 확장된 glob 예시 섹션을 참고하세요.
Glob 예시
이 디렉터리의 모든 Java 파일과 :gen_java_srcs 규칙으로 생성된 모든 파일로 빌드된 Java 라이브러리를 만듭니다.
java_library(
name = "mylib",
srcs = glob(["*.java"]) + [":gen_java_srcs"],
deps = "...",
)
genrule(
name = "gen_java_srcs",
outs = [
"Foo.java",
"Bar.java",
],
...
)
experimental.txt를 제외한 testdata 디렉터리의 모든 txt 파일을 포함합니다. testdata의 하위 디렉터리에 있는 파일은 포함되지 않습니다. 이러한 파일을 포함하려면 재귀 glob (**)을 사용하세요.
sh_test(
name = "mytest",
srcs = ["mytest.sh"],
data = glob(
["testdata/*.txt"],
exclude = ["testdata/experimental.txt"],
),
)
재귀적 glob 예시
testdata 디렉터리와 그 하위 디렉터리 (및 그 하위 디렉터리 등)의 모든 txt 파일에 테스트가 종속되도록 합니다. BUILD 파일이 포함된 하위 디렉터리는 무시됩니다. (위의 제한사항 및 주의사항 참고)
sh_test(
name = "mytest",
srcs = ["mytest.sh"],
data = glob(["testdata/**/*.txt"]),
)
이 디렉터리와 모든 하위 디렉터리(경로에 testing이라는 디렉터리가 포함된 디렉터리 제외)의 모든 java 파일에서 빌드된 라이브러리를 만듭니다. 이 패턴은 빌드 증분성을 줄여 빌드 시간을 늘릴 수 있으므로 가능한 경우 피해야 합니다.
java_library(
name = "mylib",
srcs = glob(
["**/*.java"],
exclude = ["**/testing/**"],
),
)
확장된 Glob 예
파일의 줄 수를 계산하는 현재 디렉터리의 *_test.cc에 대한 개별 genrule을 만듭니다.
# Conveniently, the build language supports list comprehensions.
[genrule(
name = "count_lines_" + f[:-3], # strip ".cc"
srcs = [f],
outs = ["%s-linecount.txt" % f[:-3]],
cmd = "wc -l $< >$@",
) for f in glob(["*_test.cc"])]
위의 BUILD 파일이 //foo 패키지에 있고 패키지에 일치하는 파일 a_test.cc, b_test.cc, c_test.cc가 포함되어 있다면 bazel query '//foo:all'를 실행하면 생성된 모든 규칙이 나열됩니다.
$ bazel query '//foo:all' | sort //foo:count_lines_a_test //foo:count_lines_b_test //foo:count_lines_c_test
select
select(
{conditionA: valuesA, conditionB: valuesB, ...},
no_match_error = "custom message"
)
select()는 규칙 속성을 구성 가능하게 만드는 도우미 함수입니다.
명령줄 Bazel 플래그에 따라 값이 달라지도록 거의 모든 속성 할당의 오른쪽을 대체할 수 있습니다.
예를 들어 이를 사용하여 플랫폼별 종속 항목을 정의하거나 규칙이 '개발자' 모드에서 빌드되는지 '출시' 모드에서 빌드되는지에 따라 다른 리소스를 삽입할 수 있습니다.
기본 사용법은 다음과 같습니다.
sh_binary(
name = "mytarget",
srcs = select({
":conditionA": ["mytarget_a.sh"],
":conditionB": ["mytarget_b.sh"],
"//conditions:default": ["mytarget_default.sh"]
})
)
이렇게 하면 구성 조건을 일치하는 값에 매핑하는 select 호출로 일반 라벨 목록 할당을 대체하여 sh_binary의 srcs 속성을 구성할 수 있습니다. 각 조건은 config_setting 또는 constraint_value에 대한 라벨 참조이며, 타겟의 구성이 예상 값 집합과 일치하면 '일치'합니다. 그러면 mytarget#srcs 값이 현재 호출과 일치하는 라벨 목록이 됩니다.
참고:
- 호출 시 정확히 하나의 조건이 선택됩니다.
- 여러 조건이 일치하고 그중 하나가 다른 조건의 전문 분야인 경우 전문 분야가 우선합니다. B에 A와 동일한 플래그 및 제약 조건 값이 모두 있고 추가 플래그 또는 제약 조건 값이 있는 경우 조건 B는 조건 A의 전문화로 간주됩니다. 이는 전문화 해결이 아래 예 2에 표시된 것처럼 순서를 생성하도록 설계되지 않았다는 의미이기도 합니다.
- 여러 조건이 일치하고 하나가 다른 모든 조건의 전문화가 아닌 경우 모든 조건이 동일한 값으로 해결되지 않으면 Bazel이 오류와 함께 실패합니다.
- 다른 조건이 일치하지 않으면 특수 의사 라벨
//conditions:default이 일치하는 것으로 간주됩니다. 이 조건을 생략하면 오류를 방지하기 위해 다른 규칙이 일치해야 합니다. select는 더 큰 속성 할당 내부에 삽입할 수 있습니다. 따라서srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...})및srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]})는 유효한 표현식입니다.select는 일부 속성을 제외한 대부분의 속성과 함께 작동합니다. 호환되지 않는 속성은 문서에서nonconfigurable로 표시됩니다.하위 패키지
subpackages(include, exclude=[], allow_empty=True)
subpackages()는 파일 및 디렉터리 대신 하위 패키지를 나열하는glob()와 유사한 도우미 함수입니다.glob()와 동일한 경로 패턴을 사용하며 현재 로드 중인 BUILD 파일의 직계 하위 항목인 모든 하위 패키지와 일치할 수 있습니다. 포함 및 제외 패턴에 관한 자세한 설명과 예시는 glob을 참고하세요.반환되는 하위 패키지의 결과 목록은 정렬된 순서이며,
exclude이 아닌include의 지정된 패턴과 일치하는 현재 로드 패키지에 상대적인 경로를 포함합니다.예
다음 예시에서는
foo/BUILD패키지의 모든 직접 하위 패키지를 나열합니다.# The following BUILD files exist: # foo/BUILD # foo/bar/baz/BUILD # foo/bar/but/bad/BUILD # foo/sub/BUILD # foo/sub/deeper/BUILD # # In foo/BUILD a call to subs1 = subpackages(include = ["**"]) # results in subs1 == ["sub", "bar/baz", "bar/but/bad"] # # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of # 'foo' subs2 = subpackages(include = ["bar/*"]) # results in subs2 = ["bar/baz"] # # Since 'bar' is not a subpackage itself, this looks for any subpackages under # all first level subdirectories of 'bar'. subs3 = subpackages(include = ["bar/**"]) # results in subs3 = ["bar/baz", "bar/but/bad"] # # Since bar is not a subpackage itself, this looks for any subpackages which are # (1) under all subdirectories of 'bar' which can be at any level, (2) not a # subpackage of another subpackages. subs4 = subpackages(include = ["sub"]) subs5 = subpackages(include = ["sub/*"]) subs6 = subpackages(include = ["sub/**"]) # results in subs4 and subs6 being ["sub"] # results in subs5 = []. # # In subs4, expression "sub" checks whether 'foo/sub' is a package (i.e. is a # subpackage of 'foo'). # In subs5, "sub/*" looks for subpackages under directory 'foo/sub'. Since # 'foo/sub' is already a subpackage itself, the subdirectories will not be # traversed anymore. # In subs6, 'foo/sub' is a subpackage itself and matches pattern "sub/**", so it # is returned. But the subdirectories of 'foo/sub' will not be traversed # anymore.
일반적으로 이 함수를 직접 호출하는 대신 사용자가 skylib의 'subpackages' 모듈을 사용하는 것이 좋습니다.