BazelCon 2022는 11월 16~17일에 뉴욕과 온라인에서 개최됩니다.
지금 등록하기

Bazel 쿼리 참조

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

이 페이지는 bazel query을 사용하여 빌드 종속 항목을 분석할 때 사용되는 Bazel 쿼리 언어의 참조 매뉴얼입니다. bazel query에서 지원하는 출력 형식도 설명합니다.

실제 사용 사례는 Bazel 쿼리 방법을 참조하세요.

추가 쿼리 참조

로드 후 단계 대상 그래프에서 실행되는 query 외에 Bazel에는 작업 그래프 쿼리구성 가능한 쿼리가 포함되어 있습니다.

작업 그래프 쿼리

작업 그래프 쿼리(aquery)는 분석 후 구성된 타겟 그래프에서 작동하며 작업, 아티팩트, 그 관계에 대한 정보를 노출합니다. aquery는 구성된 타겟 그래프에서 생성된 작업/아티팩트의 속성에 관심이 있는 경우 유용합니다. 실제 명령과 입력, 출력, 연상 기호 등을 예로 들 수 있습니다.

자세한 내용은 쿼리 참조를 확인하세요.

구성 가능한 쿼리

기존 Bazel 쿼리는 로드 후 단계 대상 그래프에서 실행되므로 구성 및 관련 개념에 대한 개념이 없습니다. 특히, 이는 select 문을 올바르게 해결하지 않으며 대신 선택 가능한 모든 해상도를 반환합니다. 하지만 구성 가능한 쿼리 환경인 cquery가 구성을 적절하게 처리하지만 이 원본 쿼리의 모든 기능을 제공하지는 않습니다.

자세한 내용은 cquery 참조를 확인하세요.

사람들이 bazel query을(를) 어떻게 사용하나요? 다음은 일반적인 예입니다.

//foo 트리가 //bar/baz를 사용하는 이유는 무엇인가요? 경로 표시:

somepath(foo/..., //bar/baz:all)

모든 foo 테스트는 foo_bin 타겟이 종속되지 않는 항목에 따라 달라지나요?

kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo:foo_bin))

토큰: 어휘 구문

쿼리 언어의 표현식은 다음 토큰으로 구성됩니다.

  • 키워드(예: let). 키워드는 언어의 예약어이며 각 키워드는 아래에 설명되어 있습니다. 전체 키워드 세트는 다음과 같습니다.

  • 단어. 예: foo/..., .*test rule 또는 //bar/baz:all. 문자 문자가 따옴표로 묶인 경우(작은따옴표로 시작해서 끝나거나 큰따옴표로 시작해서 끝납니다). 문자 시퀀스를 따옴표로 묶지 않으면 단어로 파싱될 수 있습니다. 따옴표로 묶이지 않은 단어는 알파벳 문자 A~Za~z, 숫자 0~9, 특수 문자 */@.-_:$~[](별표, 포워드 슬래시, 앳, 마침표, 하이픈, 밑줄, 콜론, 달러 기호, 물결표, 왼쪽 정사각형 중괄호, 오른쪽 정사각형 중괄호)에서 가져온 시퀀스입니다. 그러나 상대적인 [대상 이름][(/concepts/labels#target-names)은 이러한 문자로 시작할 수 있지만 따옴표로 묶이지 않은 단어는 하이픈 - 또는 별표 *로 시작할 수 없습니다.

    또한 타겟 이름에는 따옴표로 묶지 않은 단어에 문자 및 기호(+) 또는 등호(=)를 사용할 수 없습니다. 쿼리 표현식을 생성하는 코드를 작성할 때는 대상 이름을 따옴표로 묶어야 합니다.

    사용자 제공 값에서 Bazel 쿼리 표현식을 구성하는 스크립트를 작성할 때는 인용이 필요합니다.

     //foo:bar+wiz    # WRONG: scanned as //foo:bar + wiz.
     //foo:bar=wiz    # WRONG: scanned as //foo:bar = wiz.
     "//foo:bar+wiz"  # OK.
     "//foo:bar=wiz"  # OK.
    

    이 따옴표는 셸과 같이 다음과 같은 셸에서 필요할 수 있는 따옴표에 추가로 추가됩니다.

    bazel query ' "//foo:bar=wiz" '   # single-quotes for shell, double-quotes for Bazel.
    

    인용된 키워드는 일반적인 단어로 간주됩니다. 예를 들어 some는 키워드이지만 'some'은 단어입니다. foo 및 'foo'는 모두 단어입니다.

    하지만 대상 이름에 작은 따옴표 또는 큰 따옴표를 사용할 때는 주의해야 합니다. 하나 이상의 대상 이름을 따옴표로 묶을 때는 한 가지 유형의 따옴표만 사용하세요 (모두 작은따옴표 또는 모두 큰따옴표).

    다음은 자바 쿼리 문자열의 예입니다.

      'a"'a'         # WRONG: Error message: unclosed quotation.
      "a'"a"         # WRONG: Error message: unclosed quotation.
      '"a" + 'a''    # WRONG: Error message: unexpected token 'a' after query expression '"a" + '
      "'a' + "a""    # WRONG: Error message: unexpected token 'a' after query expression ''a' + '
      "a'a"          # OK.
      'a"a'          # OK.
      '"a" + "a"'    # OK
      "'a' + 'a'"    # OK
    

    대부분의 경우 따옴표가 필요하지 않도록 이 구문을 선택했습니다. 이례적인 ".*test rule" 예에는 따옴표가 필요합니다. 마침표로 시작하고 공백을 포함합니다. "cc_library" 견적은 불필요하지만 무해합니다.

  • 구두점(예: 괄호 (), 마침표 ., 쉼표 ,) 구두점이 포함된 단어 (위에 나열된 예외 제외)는 따옴표로 묶어야 합니다.

따옴표로 묶인 단어 이외의 공백 문자는 무시됩니다.

Bazel 쿼리 언어 개념

Bazel 쿼리 언어는 표현식 언어입니다. 모든 표현식은 대상의 부분적으로 순서가 지정된 집합 또는 이에 상응하는 대상의 그래프(DAG)로 평가됩니다. 유일한 데이터 유형입니다.

세트와 그래프는 동일한 데이터 유형을 참조하지만 서로 다른 측면을 강조합니다. 예를 들면 다음과 같습니다.

  • 설정: 타겟의 부분 순서는 흥미롭지 않습니다.
  • 그래프: 일부 부분적 순서가 중요합니다.

종속 항목 그래프의 주기

빌드 종속 항목 그래프는 비순환적이어야 합니다.

쿼리 언어에서 사용하는 알고리즘은 비순환 그래프에서 사용하기 위한 것이지만 순환에 매우 유용합니다. 사이클을 처리하는 방식에 관한 세부정보는 지정되지 않으며, 의존해서는 안 됩니다.

암시적 종속 항목

BUILD 파일에 명시적으로 정의된 빌드 종속 항목 외에도 Bazel은 규칙에 암시적 종속 항목을 추가합니다. 예를 들어 모든 자바 규칙은 암시적으로 JavaBuilder에 종속됩니다. 암시적 종속 항목은 $로 시작하는 속성을 사용하여 설정되며 BUILD 파일에서 재정의할 수 없습니다.

기본적으로 bazel query는 쿼리 결과를 계산할 때 암시적 종속 항목을 고려합니다. 이 동작은 --[no]implicit_deps 옵션을 사용하여 변경할 수 있습니다. 쿼리는 구성을 고려하지 않으므로 잠재적 도구 모음은 고려되지 않습니다.

건전성

Bazel 쿼리 언어 표현식은 빌드 종속 항목 그래프를 대상으로 작동합니다. 이 그래프는 모든 BUILD 파일의 모든 규칙 선언에 암시적으로 정의된 그래프입니다. 이 그래프는 다소 추상적이며 빌드의 모든 단계를 실행하는 방법에 관한 자세한 설명이 아닙니다. 빌드를 실행하려면 구성도 필요합니다. 자세한 내용은 사용자 가이드의 구성 섹션을 참조하세요.

Bazel 쿼리 언어로 된 표현식을 평가한 결과는 모든 구성에 대해 true입니다. 즉, 표현식이 정확하지 않고 보수적인 근사치일 수 있습니다. 빌드 도구를 사용하는 동안 필요한 모든 소스 파일의 집합을 계산하기 위해 쿼리 도구를 사용할 경우, 실제로 필요한 것보다 많은 파일이 보고될 수 있습니다. 예를 들어 쿼리 도구에는 빌드에서 해당 기능을 사용할 의향이 없는 경우에도 메시지 변환을 지원하는 데 필요한 모든 파일이 포함되어 있기 때문입니다.

그래프 순서 보존

작업은 하위 표현식에서 상속된 모든 순서 제약조건을 유지합니다. 이를 부분적인 보수법이라고 생각할 수 있습니다. 예를 들어 특정 타겟의 종속 항목의 전이적 종료를 확인하기 위해 쿼리를 실행하는 경우 결과 집합이 종속 항목 그래프에 따라 정렬됩니다. file 종류의 타겟만 포함하도록 필터링하는 경우 결과 하위 집합의 모든 타겟 쌍 사이에는 동일한 전환 부분 순서 관계가 적용되지만, 이러한 쌍이 원래 그래프에서 직접 연결된 것은 아닙니다. 빌드 종속 항목 그래프에는 파일 파일 가장자리가 없습니다.

그러나 모든 연산자는 순서를 보존하지만 set 연산과 같은 일부 작업은 고유한 순서 제약 조건을 도입하지 않습니다. 다음과 같은 표현식을 생각해 보세요.

deps(x) union y

최종 결과 집합의 순서는 하위 표현식의 모든 순서 지정 제약 조건을 보존합니다. 즉, x의 모든 전이 종속 항목이 서로를 올바르게 고려하여 올바르게 정렬됩니다. 그러나 쿼리는 y의 타겟 순서를 보장하거나 y의 타겟과 관련하여 deps(x)의 타겟 순서를 보장하지 않습니다(deps(x)에 있는 y의 타겟 제외).

순서 지정 제약 조건을 도입하는 연산자로는 allpaths, deps, rdeps, somepath, 대상 패턴 와일드 카드 package:*, dir/... 등이 있습니다.

스카이 쿼리

스카이 쿼리는 지정된 전체 범위에서 작동하는 쿼리 모드입니다.

SkyQuery에서만 사용할 수 있는 특수 함수

Sky 쿼리 모드에는 추가 쿼리 함수 allrdepsrbuildfiles가 있습니다. 이러한 함수는 전체 범위로 작동하므로 일반 쿼리에 적합하지 않습니다.

범용 범위 지정

Sky 쿼리 모드는 (--universe_scope 또는 --infer_universe_scope) 및 --order_output=no의 두 플래그를 전달하여 활성화됩니다. --universe_scope=<target_pattern1>,...,<target_patternN>는 대상 패턴에서 지정된 대상 패턴의 전이적 폐쇄를 미리 로드하도록 쿼리에 알리며, 이 경우 덧셈과 뺄셈이 모두 가능합니다. 모든 쿼리는 이 "범위"에서 평가됩니다. 특히 allrdepsrbuildfiles 연산자는 이 범위의 결과만 반환합니다. --infer_universe_scope는 Bazel에게 쿼리 표현식에서 --universe_scope 값을 추론하도록 지시합니다. 이 추론된 값은 쿼리 표현식의 고유한 대상 패턴 목록이지만 이 목록이 원하는 값이 아닐 수도 있습니다. 예를 들면 다음과 같습니다.

bazel query --infer_universe_scope --order_output=no "allrdeps(//my:target)"

이 쿼리 표현식의 고유한 대상 패턴 목록은 ["//my:target"]이므로 Bazel은 이를 호출과 동일하게 취급합니다.

bazel query --universe_scope=//my:target --order_output=no "allrdeps(//my:target)"

그러나 --universe_scope가 포함된 쿼리의 결과는 //my:target일 뿐이며 //my:target의 역방향 종속 항목은 우주에 구성되어 있지 않습니다. 반면 다음과 같은 사항을 고려하세요.

bazel query --infer_universe_scope --order_output=no "tests(//a/... + b/...) intersect allrdeps(siblings(rbuildfiles(my/starlark/file.bzl)))"

이는 특정 .bzl 파일을 사용하는 대상에 전이적으로 종속되는 일부 디렉터리 아래의 타겟 tests 확장에서 테스트 대상을 계산하려는 의미 있는 쿼리 호출입니다. 여기서 --infer_universe_scope는 편리합니다. 특히 --universe_scope을 선택하려면 쿼리 표현식을 직접 파싱해야 하는 경우에 유용합니다.

따라서 allrdepsrbuildfiles와 같이 범용 범위 연산자를 사용하는 쿼리 표현식의 경우 동작이 원하는 경우에만 --infer_universe_scope을 사용해야 합니다.

Sky Query는 기본 쿼리와 비교하여 장단점이 있습니다. 주요 단점은 그래프 순서에 따라 출력을 정렬할 수 없으므로 특정 출력 형식이 금지됩니다. 이 방식의 장점은 기본 쿼리에서 사용할 수 없는 두 연산자(allrdepsrbuildfiles)를 제공한다는 것입니다. 또한 스카이 쿼리는 기본 구현에서 하는 새 그래프를 만드는 대신 스카이프레임 그래프를 자체 검사하여 작업을 실행합니다. 따라서 더 빠르고 메모리를 더 적게 사용하는 상황도 있습니다.

표현식: 문법 및 문법

다음은 EB쿼리 표기법으로 표현된 Bazel 쿼리 언어의 문법입니다.

expr ::= word
       | let name = expr in expr
       | (expr)
       | expr intersect expr
       | expr ^ expr
       | expr union expr
       | expr + expr
       | expr except expr
       | expr - expr
       | set(word *)
       | word '(' int | word | expr ... ')'

다음 섹션에서는 이 문법의 각 제작 과정을 순서대로 설명합니다.

대상 패턴

expr ::= word

대상 패턴은 말 그대로 문장입니다. (정렬되지 않은) 대상 집합으로 해석됩니다. 가장 간단한 대상 패턴은 단일 대상 (파일 또는 규칙)을 식별하는 라벨입니다. 예를 들어 대상 패턴 //foo:bar는 대상 bar 요소를 포함하는 세트를 평가합니다.

대상 패턴은 패키지 및 대상에 와일드 카드를 포함하도록 라벨을 일반화합니다. 예를 들어 foo/...:all(또는 foo/...만 해당)는 foo 디렉터리 아래에 있는 모든 패키지의 모든 규칙을 포함하는 세트로 평가되는 대상 패턴입니다. bar/baz:allbar/baz 패키지의 모든 규칙이 포함되어 있지만 하위 패키지의 규칙이 포함된 세트로 평가되는 대상 패턴입니다.

마찬가지로 foo/...:*foo 디렉터리 아래의 모든 패키지에 있는 모든 타겟 (규칙 파일)을 재귀적으로 포함하는 세트로 평가되는 대상 패턴입니다. bar/baz:*bar/baz 패키지의 모든 타겟은 포함되지만 하위 패키지는 포함하지 않는 세트로 평가됩니다.

:* 와일드 카드는 파일뿐 아니라 규칙과 일치하므로 쿼리에 :all보다 더 유용한 경우가 많습니다. 반대로 :all 와일드 카드 (foo/...와 같은 타겟 패턴에서 암시적)는 일반적으로 빌드에 더 유용합니다.

bazel query 대상 패턴은 bazel build 빌드 대상과 동일한 방식으로 작동합니다. 자세한 내용은 대상 패턴을 참조하거나 bazel help target-syntax를 입력하세요.

대상 패턴은 싱글톤 집합 (라벨의 경우)과 다수의 요소가 포함된 세트 (수천 개의 요소가 있는 foo/...의 경우) 또는 타겟 패턴이 대상과 일치하지 않는 경우 빈 세트로 평가될 수 있습니다.

대상 패턴 표현식의 결과로 나타나는 모든 노드는 종속 항목 관계에 따라 서로 상대적인 순서가 올바르게 지정됩니다. 따라서 foo:*의 결과는 패키지 foo의 타겟 집합뿐만 아니라 이러한 타겟의 그래프이기도 합니다. (결과 노드를 다른 노드에 기준으로 상대적인 순서를 보장할 수는 없습니다.) 자세한 내용은 그래프 순서 섹션을 참고하세요.

변수

expr ::= let name = expr1 in expr2
       | $name

Bazel 쿼리 언어는 변수를 정의하고 참조할 수 있게 해줍니다. let 표현식의 평가 결과는 expr2와 동일하며, name의 모든 무료 어커런스는 expr1 값으로 대체됩니다.

예를 들어 let v = foo/... in allpaths($v, //common) intersect $vallpaths(foo/...,//common) intersect foo/...와 같습니다.

둘러싸는 let name = ... 표현식이 아닌 변수 참조 name가 발생하는 경우 오류입니다. 즉, 최상위 쿼리 표현식에는 자유 변수가 있을 수 없습니다.

위의 문법 프로덕션에서 name단어와 비슷하지만, C 프로그래밍 언어의 법적 식별자라는 추가적인 제약 조건이 있습니다. 변수 참조 앞에는 ','를 추가해야 합니다.

let 표현식은 변수를 하나만 정의하지만 중첩할 수 있습니다.

대상 패턴과 변수 참조는 모두 토큰 1개, 단어 1개로만 이루어져 구문의 모호성을 만듭니다. 그러나 법적 변수 이름인 단어의 하위 집합이 법적 대상 패턴인 단어의 하위 집합과 분리되므로 의미론적 모호성이 없습니다.

엄밀히 말하면 let 표현식은 쿼리 언어의 표현성을 높이지 않습니다. 언어로 표현 가능한 모든 쿼리는 표현식 없이 표현될 수도 있습니다. 하지만 이렇게 하면 많은 쿼리가 간결해지므로 보다 효율적인 쿼리 평가가 가능할 수도 있습니다.

괄호 표현식

expr ::= (expr)

괄호는 하위 표현식을 연결해 평가 순서를 강제합니다. 괄호로 묶인 표현식은 인수 값으로 평가됩니다.

대수 세트 연산: 교집합, 유니온, 세트 차이

expr ::= expr intersect expr
       | expr ^ expr
       | expr union expr
       | expr + expr
       | expr except expr
       | expr - expr

이 세 연산자는 인수에 대해 일반적인 집합 작업을 계산합니다. 각 연산자에는 명사 형식(예: intersect)과 기호 형식(예: ^)이 있습니다. 두 양식 모두 동등합니다. 기호화된 양식은 더 빠르게 입력할 수 있습니다. 명확히 하기 위해 이 페이지의 나머지 부분에서는 명사 형태를 사용합니다.

예를 들면 다음과 같습니다.

foo/... except foo/bar/...

foo/...와 일치하지만 foo/bar/...과 일치하지 않는 타겟 집합으로 평가됩니다.

다음과 동일한 쿼리를 작성할 수 있습니다.

foo/... - foo/bar/...

intersect(^) 및 union(+) 연산자는 가환성 (대칭)이고 except(-) 작업은 비대칭입니다. 파서는 세 가지 연산자를 모두 왼쪽 연결과 동일한 우선순위로 취급하므로 괄호를 사용하는 것이 좋습니다. 예를 들어 두 표현식 중 처음 두 개는 동일하지만 세 번째는 같지 않습니다.

x intersect y union z
(x intersect y) union z
x intersect (y union z)

외부 소스에서 대상 읽기: set

expr ::= set(word *)

set(a b c ...) 연산자는 공백으로 구분된 0개 이상의 대상 패턴 집합의 공백 (쉼표 없음)을 계산합니다.

Bourne 셸의 $(...) 기능과 함께 set()은 한 쿼리 결과를 일반 텍스트 파일에 저장하고, 다른 프로그램 (예: 표준 UNIX 셸 도구)을 사용하여 해당 텍스트 파일을 조작한 다음 결과를 추가 처리를 위한 값으로 쿼리 도구에 다시 도입하는 방법을 제공합니다. 예를 들면 다음과 같습니다.

bazel query deps(//my:target) --output=label | grep ... | sed ... | awk ... > foo
bazel query "kind(cc_binary, set($(<foo)))"

다음 예에서는 awk 프로그램을 사용하여 maxrank 값을 필터링하여 kind(cc_library, deps(//some_dir/foo:main, 5))를 계산합니다.

bazel query 'deps(//some_dir/foo:main)' --output maxrank | awk '($1 < 5) { print $2;} ' > foo
bazel query "kind(cc_library, set($(<foo)))"

이 예에서 $(<foo)$(cat foo)의 약어이지만 cat 이외의 셸 명령어도 사용할 수 있습니다(예: 이전 awk 명령어).

함수

expr ::= word '(' int | word | expr ... ')'

쿼리 언어는 여러 함수를 정의합니다. 함수 이름에 따라 필요한 인수의 수와 유형이 결정됩니다. 사용할 수 있는 함수는 다음과 같습니다.

종속 항목의 전이적 폐쇄: deps

expr ::= deps(expr)
       | deps(expr, depth)

deps(x) 연산자는 인수 집합의 종속 항목의 전이적 클로저에 의해 형성된 그래프를 평가합니다. x 예를 들어 deps(//foo)의 값은 단일 노드 foo에 기반한 종속 항목 그래프로, 모든 종속 항목을 포함합니다. deps(foo/...) 값은 루트가 foo 디렉터리 아래의 모든 패키지에 있는 모든 규칙인 종속 항목 그래프입니다. 이 컨텍스트에서 '종속 항목'은 규칙과 파일 대상만 의미하므로 이 대상을 만드는 데 필요한 BUILD와 Starlark 파일은 여기에 포함되지 않습니다. 이를 위해 buildfiles 연산자를 사용해야 합니다.

결과 그래프는 종속 항목 관계에 따라 정렬됩니다. 자세한 내용은 그래프 순서 섹션을 참고하세요.

deps 연산자는 검색 심도의 상한값을 지정하는 정수 리터럴인 두 번째 인수(선택사항)를 허용합니다. 따라서 deps(foo:*, 0)foo 패키지의 모든 타겟을 반환하고 deps(foo:*, 1)foo 패키지에 있는 모든 타겟의 직접적인 기본 요건을 추가로 포함하며 deps(foo:*, 2)deps(foo:*, 1)의 노드에서 직접 연결할 수 있는 노드를 포함합니다. (이 숫자는 minrank 출력 형식에 표시되는 랭크에 해당합니다.) depth 매개변수가 생략되면 검색은 제한되지 않고 전제 조건의 재귀 타게팅 종료를 계산합니다.

역방향 종속 항목의 전이적 폐쇄: rdeps

expr ::= rdeps(expr, expr)
       | rdeps(expr, expr, depth)

rdeps(u, x) 연산자는 유니버스 세트 u의 전이적 클로저 내에서 인수 세트 x의 역방향 종속 항목으로 평가됩니다.

결과 그래프는 종속 항목 관계에 따라 정렬됩니다. 자세한 내용은 그래프 순서 섹션을 참고하세요.

rdeps 연산자는 검색 깊이의 상한값을 지정하는 정수 리터럴인 세 번째 인수(선택사항)를 허용합니다. 결과 그래프에는 인수 집합의 노드에서 지정된 깊이까지의 거리 내에 있는 노드만 포함됩니다. 따라서 rdeps(//foo, //common, 1)//common에 직접 종속되는 //foo의 전이적 클로저에 있는 모든 노드를 평가합니다. 이 숫자는 minrank 출력 형식에 표시된 순위에 해당합니다. depth 매개변수를 생략하면 검색이 제한되지 않습니다.

모든 역방향 종속 항목의 전이적 폐쇄: allrdeps

expr ::= allrdeps(expr)
       | allrdeps(expr, depth)

allrdeps 연산자는 rdeps 연산자와 유사하게 동작합니다. 단, \'역 집합'은 별도로 지정되지 않고 --universe_scope 플래그가 평가된 항목입니다. 따라서 --universe_scope=//foo/...이 전달되면 allrdeps(//bar)rdeps(//foo/..., //bar)과 같습니다.

동일한 패키지의 직접 역방향 종속 항목: same_pkg_direct_rdeps

expr ::= same_pkg_direct_rdeps(expr)

same_pkg_direct_rdeps(x) 연산자는 인수 집합의 타겟과 동일한 패키지에 있고 직접 종속되는 전체 대상 세트로 평가됩니다.

타겟 패키지 처리: 형제자매

expr ::= siblings(expr)

siblings(x) 연산자는 인수 집합의 타겟과 동일한 패키지에 있는 전체 대상 세트로 평가됩니다.

임의 선택: 일부

expr ::= some(expr)

some(x) 연산자는 인수 세트 x에서 무작위로 1개의 대상을 선택하고 해당 대상만 포함된 싱글톤 집합으로 평가됩니다. 예를 들어 some(//foo:main union //bar:baz) 표현식은 정의되지 않은 //foo:main 또는 //bar:baz가 포함된 조합으로 평가됩니다.

인수가 싱글톤이면 some은 ID 함수를 계산합니다. some(//foo:main)//foo:main과 같습니다.

some(//foo:main intersect //bar:baz) 표현식과 같이 지정된 인수 집합이 비어 있으면 오류가 발생합니다.

경로 연산자: somepath, allpaths

expr ::= somepath(expr, expr)
       | allpaths(expr, expr)

somepath(S, E)allpaths(S, E) 연산자는 두 대상 집합 간의 경로를 계산합니다. 두 쿼리 모두 시작 지점의 S 집합과 끝 지점의 E 집합이라는 두 인수를 허용합니다. somepathS의 대상에서 E의 대상으로 일부 임의 경로의 노드 그래프를 반환합니다. allpathsS의 모든 대상에서 E의 대상으로 모든 경로의 노드 그래프를 반환합니다.

결과 그래프는 종속 항목 관계에 따라 정렬됩니다. 자세한 내용은 그래프 순서 섹션을 참고하세요.

일부 경로
somepath(S1 + S2, E), 하나의 결과.
일부 경로
somepath(S1 + S2, E). 다른 검색결과가 있습니다.
모든 경로
allpaths(S1 + S2, E)

대상 종류 필터링: 종류

expr ::= kind(word, expr)

kind(pattern, input) 연산자는 대상 집합에 필터를 적용하고 예상 종류가 아닌 대상을 삭제합니다. pattern 매개변수는 일치시킬 대상의 유형을 지정합니다.

예를 들어 아래 표시된 BUILD 패키지(p 패키지용)에서 정의한 4가지 타겟의 종류가 아래 그림에 나와 있습니다.

코드 타겟 종류
        genrule(
            name = "a",
            srcs = ["a.in"],
            outs = ["a.out"],
            cmd = "...",
        )
      
//p:a genrule 규칙
//p:a.in 소스 파일
//p:a.out 생성된 파일
//p:BUILD 소스 파일

따라서 kind("cc_.* rule", foo/...)foo 아래 모든 cc_library, cc_binary 등의 규칙 대상 세트로 평가하고, //foo 대상의 종속 항목의 전이적 클로저에 있는 모든 소스 파일 집합을 평가합니다.

pattern 인수에 대한 따옴표는 필수인 경우가 많습니다. 그렇지 않으면 source file.*_test와 같은 많은 정규 표현식이 파서에 있는 단어로 간주되지 않습니다.

package group과 일치하는 경우 :all으로 끝나는 타겟이 결과를 산출하지 못할 수 있습니다. 대신 :all-targets를 사용하세요.

대상 이름 필터링: 필터

expr ::= filter(word, expr)

filter(pattern, input) 연산자는 대상 집합에 필터를 적용하고 라벨 (절대 형식)이 패턴과 일치하지 않는 대상을 삭제하고 입력의 하위 집합으로 평가합니다.

첫 번째 인수 pattern는 대상 이름 위에 정규 표현식이 포함된 단어입니다. filter 표현식은 모든 대상 x를 포함하는 세트로 평가되어 xinput의 멤버이고 x의 라벨 (절대 형태, //foo:bar 등)이 정규 표현식 pattern에 대한 (앵커되지 않음) 일치를 포함합니다. 모든 대상 이름은 //로 시작하므로 ^ 정규 표현식 앵커의 대안으로 사용할 수 있습니다.

이 연산자는 종종 intersect 연산자보다 훨씬 빠르고 강력한 대안을 제공합니다. 예를 들어 //foo:foo 대상의 모든 bar 종속 항목을 확인하려면

deps(//foo) intersect //bar/...

그러나 이 문을 실행하려면 bar 트리의 모든 BUILD 파일을 파싱해야 하므로 속도가 느려지고 관련이 없는 BUILD 파일에서 오류가 발생하기 쉽습니다. 대안은 다음과 같습니다.

filter(//bar, deps(//foo))

이 명령어는 먼저 //foo 종속 항목 집합을 계산한 다음 제공된 패턴과 일치하는 타겟, 즉 //bar을 하위 문자열로 포함하는 타겟만 필터링합니다.

filter(pattern, expr) 연산자의 또 다른 일반적인 용도는 특정 파일을 이름이나 확장자로 필터링하는 것입니다. 예를 들면 다음과 같습니다.

filter("\.cc$", deps(//foo))

그러면 //foo를 빌드하는 데 사용되는 모든 .cc 파일의 목록이 제공됩니다.

규칙 속성 필터링: 속성

expr ::= attr(word, word, expr)

attr(name, pattern, input) 연산자는 대상 집합에 필터를 적용하고, 속성이 지정되지 않은 대상, name 속성이 정의되지 않은 규칙 대상 또는 속성 값이 제공된 정규 표현식 pattern과 일치하지 않는 규칙 대상을 삭제하고 입력의 하위 집합을 평가합니다.

첫 번째 인수 name는 제공된 정규 표현식 패턴과 대조해야 하는 규칙 속성의 이름입니다. 두 번째 인수 pattern는 속성 값에 대한 정규 표현식입니다. attr 표현식은 모든 대상 x를 포함하는 세트로 평가되어 xinput 집합의 구성원이고, 정의된 속성이 name인 규칙이며, 속성 값에 정규 표현식 pattern에 대한 (고정되지 않은) 일치가 포함됩니다. name가 선택적 속성이며, 규칙이 명시적으로 지정되지 않은 경우 비교에 기본 속성 값이 사용됩니다. 예를 들면 다음과 같습니다.

attr(linkshared, 0, deps(//foo))

링크 공유 속성 (예: cc_binary 규칙)이 허용되고 이를 명시적으로 0으로 설정하거나 아예 설정하지 않은 기본값을 사용하는 모든 //foo 종속 항목을 선택합니다 (예: cc_binary 규칙).

목록 유형 속성 (예: srcs, data 등)은 [value<sub>1</sub>, ..., value<sub>n</sub>] 형식의 문자열로 변환됩니다. [ 괄호로 시작하고 ] 괄호로 끝나며 ,, 쉼표(공백, 공백)를 사용하여 여러 값을 구분합니다. 라벨은 라벨의 절대 형태를 사용하여 문자열로 변환됩니다. 예를 들어 deps=[":foo", "//otherpkg:bar", "wiz"] 속성은 [//thispkg:foo, //otherpkg:bar, //thispkg:wiz] 문자열로 변환됩니다. 대괄호는 항상 존재하므로 빈 목록은 일치 목적으로 문자열 값 []을 사용합니다. 예를 들면 다음과 같습니다.

attr("srcs", "\[\]", deps(//foo))

srcs 속성이 있는 //foo 종속 항목 중에서 모든 규칙을 선택하고

attr("data", ".{3,}", deps(//foo))

data 속성에서 1개 이상의 값을 지정하는 //foo 종속 항목 중에서 모든 규칙을 선택합니다 (//:로 인해 모든 라벨의 길이가 3자 이상).

목록 유형 속성에서 특정 value가 있는 //foo 종속 항목 중에서 모든 규칙을 선택하려면 다음을 사용하세요.

attr("tags", "[\[ ]value[,\]]", deps(//foo))

value 앞 글자가 [ 또는 공백이고 value 뒤의 문자가 쉼표 또는 ]이므로 이러한 방식으로 작동합니다.

규칙 공개 상태 필터링: 표시

expr ::= visible(expr, expr)

visible(predicate, input) 연산자는 타겟 집합에 필터를 적용하고 필수 공개 상태 없이 대상을 삭제합니다.

첫 번째 인수 predicate는 출력의 모든 대상이 표시되어야 하는 대상 집합입니다. visible 표현식은 모든 타겟 x가 포함된 세트로 평가되어 xinput 집합의 구성원이고 predicate x의 모든 타겟 yy에 표시됩니다. 예를 들면 다음과 같습니다.

visible(//foo, //bar:*)

공개 상태 제한을 위반하지 않고 //foo가 종속할 수 있는 //bar 패키지의 모든 대상을 선택합니다.

라벨 유형(라벨)의 규칙 속성 평가

expr ::= labels(word, expr)

labels(attr_name, inputs) 연산자는 inputs 세트의 일부 규칙에서 'label' 또는 '라벨 목록' 유형의 attr_name 속성에 지정된 타겟 집합을 반환합니다.

예를 들어 labels(srcs, //foo)//foo 규칙의 srcs 속성에 나타나는 타겟 집합을 반환합니다. inputs 속성에 srcs 속성이 포함된 규칙이 여러 개 있으면 srcs의 합집합이 반환됩니다.

test_suites 확장 및 필터링: 테스트

expr ::= tests(expr)

tests(x) 연산자는 x 집합의 모든 테스트 규칙 집합을 반환하고 test_suite 규칙을 참조하는 개별 테스트 집합으로 확장하고 tagsize로 필터링을 적용합니다.

기본적으로 쿼리 평가는 모든 test_suite 규칙의 테스트 외 대상을 무시합니다. 이는 --strict_test_suite 옵션을 사용하여 오류로 변경할 수 있습니다.

예를 들어 kind(test, foo:*) 쿼리는 foo 패키지의 모든 *_testtest_suite 규칙을 나열합니다. 모든 결과는 정의에 따라 foo 패키지의 구성원입니다. 이와 달리 tests(foo:*) 쿼리는 bazel test foo:*에서 실행할 개별 테스트를 모두 반환합니다. 여기에는 test_suite 규칙을 통해 직접 또는 간접적으로 참조되는 다른 패키지에 속하는 테스트가 포함될 수 있습니다.

패키지 정의 파일: buildfiles

expr ::= buildfiles(expr)

buildfiles(x) 연산자는 x 집합에 있는 각 타겟의 패키지를 정의하는 파일 집합을 반환합니다. 즉, 각 패키지에 관해 BUILD 파일과 load를 통해 참조하는 모든 .bzl 파일을 반환합니다. 이렇게 하면 load 파일이 포함된 패키지의 BUILD 파일도 반환됩니다.

이 연산자는 일반적으로 지정된 타겟을 빌드하는 데 필요한 파일 또는 패키지를 결정할 때 사용되며, 보통 아래 --output package 옵션과 함께 사용됩니다. 예를 들면 다음과 같습니다.

bazel query 'buildfiles(deps(//foo))' --output package

//foo가 전이적으로 종속되는 모든 패키지의 집합을 반환합니다.

패키지 정의 파일: rbuildfiles

expr ::= rbuildfiles(word, ...)

rbuildfiles 연산자는 쉼표로 구분된 경로 프래그먼트 목록을 가져와 이러한 경로 프래그먼트에 전이적으로 종속되는 BUILD 파일 집합을 반환합니다. 예를 들어 //foo가 패키지이면 rbuildfiles(foo/BUILD)//foo:BUILD 타겟을 반환합니다. foo/BUILD 파일에 load('//bar:file.bzl'...이 포함된 경우 rbuildfiles(bar/file.bzl)//foo:BUILD 타겟 및 //bar:file.bzl를 로드하는 다른 BUILD 파일의 타겟을 반환합니다.

rbuildfiles 연산자의 범위는 --universe_scope 플래그로 지정된 세계입니다. BUILD 파일 및 .bzl 파일에 직접 대응하지 않는 파일은 결과에 영향을 주지 않습니다. 예를 들어 소스 파일 (예: foo.cc)은 BUILD 파일에 명시적으로 언급되더라도 무시됩니다. 그러나 심볼릭 링크는 고려되므로 foo/BUILDbar/BUILD의 심볼릭 링크이면 rbuildfiles(bar/BUILD)은 결과에 //foo:BUILD를 포함합니다.

rbuildfiles 연산자는 비윤리적으로 buildfiles 연산자의 역입니다. 그러나 이 도덕적 반전은 한 방향으로 더 강력하게 유지됩니다. rbuildfiles의 출력은 buildfiles의 입력과 같습니다. 전자의 포장에는 BUILD 파일 타겟만 포함되며 이러한 파일의 타겟은 이러한 타겟을 포함할 수 있습니다. 다른 방향으로는 소통이 어려워집니다. buildfiles 연산자의 출력은 모든 패키지 및 .지정된 입력에 필요한 bzl 파일. 그러나 rbuildfiles 연산자의 입력은 이러한 타겟이 아니라 해당 대상에 상응하는 경로 프래그먼트입니다.

패키지 정의 파일: loadfiles

expr ::= loadfiles(expr)

loadfiles(x) 연산자는 x 집합에서 각 대상의 패키지를 로드하는 데 필요한 Starlark 파일 집합을 반환합니다. 즉, 각 패키지에 대해 BUILD 파일에서 참조되는 .bzl 파일을 반환합니다.

출력 형식

bazel query는 그래프를 생성합니다. bazel query--output 명령줄 옵션을 사용하여 이 그래프를 표시하는 데 사용되는 콘텐츠, 형식 및 순서를 지정합니다.

Sky Query로 실행하는 경우 정렬되지 않은 출력과 호환되는 출력 형식만 허용됩니다. 특히 graph, minrank, maxrank 출력 형식은 금지됩니다.

일부 출력 형식은 추가 옵션을 허용합니다. 각 출력 옵션의 이름에는 적용되는 출력 형식이 접두사로 지정되므로 --graph:factored--output=graph를 사용할 때만 적용됩니다. graph 이외의 출력 형식을 사용하는 경우에는 효과가 없습니다. 마찬가지로 --xml:line_numbers--output=xml가 사용되는 경우에만 적용됩니다.

결과 순서

쿼리 표현식은 항상 '그래프 순서의 보존 규칙'을 따르지만 종속 항목을 정렬하거나 순서가 지정되지 않은 방식으로 표시할 수 있습니다. 결과 세트의 타겟이나 쿼리 계산 방식에는 영향을 미치지 않습니다. 결과는 stdout에 결과가 출력되는 방식에만 영향을 미칩니다. 또한 종속 항목 순서에 상응하는 노드는 알파벳순으로 정렬될 수도 있고 정렬되지 않을 수도 있습니다. --order_output 플래그를 사용하여 이 동작을 제어할 수 있습니다. --[no]order_results 플래그는 --order_output 플래그의 기능 하위 집합을 포함하며 지원 중단되었습니다.

이 플래그의 기본값은 auto이며, 사전순으로 결과를 출력합니다. 그러나 somepath(a,b)를 사용하면 결과가 deps 순서로 인쇄됩니다.

이 플래그가 no이고 --outputbuild, label, label_kind, location, package, proto, xml 중 하나이면 출력이 무작위 순서로 인쇄됩니다. 일반적으로 가장 빠른 옵션입니다. 하지만 --outputgraph, minrank 또는 maxrank 중 하나일 때는 지원되지 않습니다. 이러한 형식을 사용하면 Bazel이 항상 종속 항목 순서 또는 순위에 따라 정렬된 결과를 출력합니다.

이 플래그가 deps이면 Bazel이 몇 가지 토폴로지 순서로 결과를 출력합니다. 즉, 먼저 종속 항목을 출력합니다. 그러나 종속 항목 순서에 따라 정렬되지 않은 노드는 한 방향에서 다른 경로로 경로가 없기 때문에 어떤 순서로든 출력될 수 있습니다.

이 플래그가 full이면 Bazel이 완전히 확정된 (총) 순서로 노드를 출력합니다. 먼저 모든 노드는 알파벳순으로 정렬됩니다. 그런 다음 목록의 각 노드가 방문 심도 노드 우선 검색의 시작으로 사용되어 방문되지 않은 노드로 나가는 가장자리가 후속 노드의 알파벳순으로 순회합니다. 마지막으로 노드는 방문한 순서와 역순으로 인쇄됩니다.

이 순서로 노드를 출력하면 속도가 느려질 수 있으므로 확정성이 중요한 경우에만 사용해야 합니다.

대상의 소스 형태를 BUILD에 표시될 때 인쇄합니다.

--output build

이 옵션을 사용하면 각 대상은 BUILD 언어로 직접 작성된 것처럼 표현됩니다. 모든 변수와 함수 호출(예: glob, 매크로)이 확장되므로 Starlark 매크로의 효과를 확인하는 데 유용합니다. 또한 각 유효 규칙은 generator_name 또는 generator_function) 값을 보고하여 유효한 규칙을 생성하기 위해 평가된 매크로의 이름을 지정합니다.

출력에서는 BUILD 파일과 동일한 구문을 사용하지만 유효한 BUILD 파일이 생성되지 않을 수도 있습니다.

--output label

이 옵션을 사용하면 결과 그래프에서 각 대상의 이름 (또는 라벨) 집합이 토폴로지 순서로 출력됩니다 (--noorder_results이 지정되지 않은 경우 결과 순서에 관한 참고 참고). (토폴로지 토폴로지 순서는 그래프 노드가 모든 후속 모델보다 먼저 표시되는 순서입니다.) 물론 그래프에는 여러 가지 토폴로지 토폴로지가 있을 수 있습니다 (역순). 단, 특정 순서만 지정되지는 않습니다.

somepath 쿼리의 출력을 인쇄할 때 노드가 출력되는 순서는 경로의 순서입니다.

주의: 동일한 라벨에서 2개의 개별 타겟이 있는 경우도 있을 수 있습니다. 예를 들어 sh_binary 규칙과 유일한 (암시적) srcs 파일은 모두 foo.sh이라고 할 수 있습니다. 쿼리 결과에 두 대상이 모두 포함된 경우 출력 (label 형식)에 중복이 포함된 것으로 표시됩니다. label_kind(아래 참고) 형식을 사용할 때 구분이 명확해집니다. 두 대상은 이름은 같지만 하나는 종류 sh_binary rule이고 다른 하나는 source file 종류입니다.

--output label_kind

label와 마찬가지로 이 출력 형식은 각 그래프의 라벨을 결과 그래프에서 토폴로지 순서로 출력하지만 추가로 대상 앞에 Kind가 있습니다.

--output minrank --output maxrank

label와 마찬가지로 minrankmaxrank 출력 형식은 결과 그래프에서 각 타겟의 라벨을 출력하지만, 토폴로지 순서로 표시되지 않고 순위 번호 앞에 표시됩니다. 결과 순서 지정 --[no]order_results 플래그의 영향을 받지 않습니다 (결과 순서 참고 참고).

이 형식에는 두 가지 변형이 있습니다. minrank는 루트 노드에서 최하위 노드까지의 최단 경로 길이에 따라 각 노드의 순위를 지정합니다. '루트' 노드 (수신 에지가 없는 노드)의 순위는 0이고, 후속 노드는 순위 1입니다. (항상 그렇듯이 가장자리는 대상에서 전제 조건을 가리키며, 타겟에 종속됩니다.)

maxrank는 루트 노드에서 가장 긴 경로의 길이에 따라 각 노드의 순위를 지정합니다. 다시 말씀드리지만 'roots'는 순위가 0이고 다른 모든 노드의 순위는 모든 이전 노드의 최대 순위보다 높은 것입니다.

한 주기의 모든 노드는 동일한 순위로 간주됩니다. 대부분의 그래프는 비순환이지만 BUILD 파일에는 잘못된 주기가 있기 때문에 주기가 발생합니다.

이러한 출력 형식은 그래프의 깊이를 파악하는 데 유용합니다. deps(x), rdeps(x) 또는 allpaths 쿼리의 결과에 사용되는 경우 순위 번호는 x에서 해당 순위의 노드까지의 최단 경로 (minrank 포함) 또는 최장 경로(maxrank 포함)의 길이와 같습니다. maxrank는 타겟을 빌드하는 데 필요한 빌드 단계의 가장 긴 시퀀스를 결정하는 데 사용할 수 있습니다.