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

Bazel 쿼리 방법

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

이 페이지에서는 Bazel의 쿼리 언어를 사용하여 코드에서 종속 항목을 추적하는 방법을 설명합니다.

언어 세부정보 및 --output 플래그 세부정보는 참조 매뉴얼, Bazel 쿼리 참조, Bazel cquery 참조를 확인하세요. 명령줄에서 bazel help query 또는 bazel help cquery를 입력하여 도움말을 볼 수 있습니다.

대상 누락과 같은 오류를 무시하면서 쿼리를 실행하려면 --keep_going 플래그를 사용합니다.

규칙의 종속 항목 찾기

//foo의 종속 항목을 확인하려면 bazel 쿼리에서 deps 함수를 사용합니다.

$ bazel query "deps(//foo)"
//foo:foo
//foo:foo-dep
...

//foo을 빌드하는 데 필요한 모든 타겟의 집합입니다.

두 패키지 간의 종속 항목 체인 추적

//third_party/zlib:zlibonly 라이브러리는 //foo의 BUILD 파일에 없지만 간접 종속 항목입니다. 이 종속 항목 경로를 추적하려면 어떻게 해야 하나요? 여기에는 allpathssomepath의 두 가지 유용한 함수가 있습니다. 또한 가능한 모든 작업이 아닌 빌드한 아티팩트에 포함되는 항목에만 관심이 있는 경우 --notool_deps를 사용하여 도구 종속 항목을 제외할 수도 있습니다.

모든 종속 항목의 그래프를 시각화하려면 dot 명령줄 도구를 통해 bazel 쿼리 출력을 파이핑합니다.

$ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg

종속 항목 그래프가 크고 복잡한 경우 단일 경로로 시작하는 것이 도움이 될 수 있습니다.

$ bazel query "somepath(//foo:foo, third_party/zlib:zlibonly)"
//foo:foo
//translations/tools:translator
//translations/base:base
//third_party/py/MySQL:MySQL
//third_party/py/MySQL:_MySQL.so
//third_party/mysql:mysql
//third_party/zlib:zlibonly

allpaths--output graph을 지정하지 않으면 종속 항목 그래프의 평탄화된 목록이 생성됩니다.

$ bazel query "allpaths(//foo, third_party/...)"
  ...many errors detected in BUILD files...
//foo:foo
//translations/tools:translator
//translations/tools:aggregator
//translations/base:base
//tools/pkg:pex
//tools/pkg:pex_phase_one
//tools/pkg:pex_lib
//third_party/python:python_lib
//translations/tools:messages
//third_party/py/xml:xml
//third_party/py/xml:utils/boolean.so
//third_party/py/xml:parsers/sgmlop.so
//third_party/py/xml:parsers/pyexpat.so
//third_party/py/MySQL:MySQL
//third_party/py/MySQL:_MySQL.so
//third_party/mysql:mysql
//third_party/openssl:openssl
//third_party/zlib:zlibonly
//third_party/zlib:zlibonly_v1_2_3
//third_party/python:headers
//third_party/openssl:crypto

참고: 암시적 종속 항목

//foo의 BUILD 파일은 //translations/tools:aggregator를 참조하지 않습니다. 그렇다면 직접적인 종속 항목은 어디인가요?

일부 규칙에는 추가 라이브러리 또는 도구에 대한 암시적 종속 항목이 포함됩니다. 예를 들어 genproto 규칙을 빌드하려면 먼저 프로토콜 컴파일러를 빌드해야 합니다. 따라서 모든 genproto 규칙은 프로토콜 컴파일러에 대한 암시적 종속 항목을 전달합니다. 이러한 종속 항목은 빌드 파일에 언급되지 않지만 빌드 도구에 추가됩니다. 현재 암시적 종속 항목 전체 세트는 문서화되지 않았습니다. --noimplicit_deps를 사용하면 쿼리 결과에서 이러한 deps를 필터링할 수 있습니다. cquery의 경우 해결된 도구 모음이 포함됩니다.

종속 항목 반전

일부 대상에 따라 달라지는 대상 집합을 알아야 할 수도 있습니다. 예를 들어 코드를 변경하려는 경우 어떤 코드가 손상되는지 알고 싶을 수 있습니다. rdeps(u, x)을 사용하여 u의 전이적 닫는 내에서 x에 있는 타겟의 역방향 종속 항목을 찾을 수 있습니다.

Bazel의 Sky Query는 사용자가 지정한 유니버스에서 역방향 종속 항목을 쿼리할 수 있는 allrdeps 함수를 지원합니다.

기타 용도

bazel query를 사용하여 많은 종속 항목 관계를 분석할 수 있습니다.

존재 대상

foo 아래에는 어떤 패키지가 있나요?

bazel query 'foo/...' --output package

foo 패키지에는 어떤 규칙이 정의되나요?

bazel query 'kind(rule, foo:*)' --output label_kind

foo 패키지의 규칙에 따라 생성되는 파일은 무엇인가요?

bazel query 'kind("generated file", //foo:*)'

Starlark 매크로 foo에서 어떤 타겟을 생성하나요?

bazel query 'attr(generator_function, foo, //path/to/search/...)'

//foo을(를) 빌드하는 데 필요한 BUILD 파일 집합은 무엇인가요?

bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:

test_suite가 확장되는 개별 테스트는 무엇인가요?

bazel query 'tests(//foo:smoke_tests)'

다음 중 C++ 테스트인 것은 무엇인가요?

bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'

다음 중 작은 것은 무엇인가요? 매체? 대형?

bazel query 'attr(size, small, tests(//foo:smoke_tests))'

bazel query 'attr(size, medium, tests(//foo:smoke_tests))'

bazel query 'attr(size, large, tests(//foo:smoke_tests))'

foo 아래에 패턴과 일치하는 테스트는 무엇인가요?

bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'

패턴은 정규식이며 규칙의 전체 이름에 적용됩니다. 비슷한 작업을 하는 것과 비슷함

bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'

path/to/file/bar.java 파일이 포함된 패키지는 무엇인가요?

 bazel query path/to/file/bar.java --output=package

path/to/file/bar.java?의 빌드 라벨

bazel query path/to/file/bar.java

path/to/file/bar.java 파일이 소스로 포함된 규칙 대상은 무엇인가요?

fullname=$(bazel query path/to/file/bar.java)
bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"

패키지 종속 항목 존재 ...

foo가 사용하는 패키지는 무엇인가요? foo를 빌드하려면 무엇을 체크아웃해야 하나요?

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

foo/contrib를 제외한 foo 트리가 사용하는 패키지는 무엇인가요?

bazel query 'deps(foo/... except foo/contrib/...)' --output package

규칙 종속 항목이 있는 이유

이 바는 어떤 genproto 규칙에 종속되나요?

bazel query 'kind(genproto, deps(bar/...))'

서블릿 트리에서 자바 바이너리 규칙에 의해 전이적으로 종속되는 일부 JNI (C++) 라이브러리의 정의를 찾습니다.

bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
이제 종속 항목에 종속된 모든 자바 바이너리의 정의를 확인합니다.
bazel query 'let jbs = kind(java_binary, //java/com/example/frontend/...) in
  let cls = kind(cc_.*library, deps($jbs)) in
    $jbs intersect allpaths($jbs, $cls)'

파일 종속성 정보

foo를 빌드하는 데 필요한 전체 자바 소스 파일 세트는 무엇인가요?

소스 파일:

bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$

생성된 파일:

bazel query 'kind("generated file", deps(//path/to/target/foo/...))' | grep java$

QUX 테스트를 빌드하는 데 필요한 전체 자바 소스 파일 세트는 무엇인가요?

소스 파일:

bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$

생성된 파일:

bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$

X와 Y의 종속 항목 차이

//foo//foo:foolib에 의존하지 않는 타겟은 무엇인가요?

bazel query 'deps(//foo) except deps(//foo:foolib)'

foo 테스트에서 //foo 프로덕션 바이너리가 종속되지 않는 C++ 라이브러리는 무엇인가요?

bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'

이 종속 항목이 있는 이유 ...

bargroups2를 사용하는 이유는 무엇인가요?

bazel query 'somepath(bar/...,groups2/...:*)'

이 쿼리의 결과를 얻으면 단일 타겟이 예기치 않거나 위험하고 바람직하지 않은 bar의 종속 항목으로 눈에 띄도록 하는 경우가 많습니다. 그러면 쿼리를 더 세분화하여 다음 작업을 수행할 수 있습니다.

docker/updater:updater_systest(py_test)에서 종속된 일부 cc_library까지의 경로를 표시합니다.

bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in
  somepath(docker/updater:updater_systest, $cc)'

//photos/frontend:lib 라이브러리가 동일한 라이브러리 //third_party/jpeglib//third_party/jpeg의 두 변형에 종속되는 이유는 무엇인가요?

이 쿼리는 다음과 같이 요약됩니다. "두 라이브러리에 종속된 //photos/frontend:lib의 하위 그래프가 표시됩니다. 토폴로지 순서로 볼 때 결과의 마지막 요소는 가장 가능성이 높은 원인입니다.

bazel query 'allpaths(//photos/frontend:lib, //third_party/jpeglib)
                intersect
               allpaths(//photos/frontend:lib, //third_party/jpeg)'
//photos/frontend:lib
//photos/frontend:lib_impl
//photos/frontend:lib_dispatcher
//photos/frontend:icons
//photos/frontend/modules/gadgets:gadget_icon
//photos/thumbnailer:thumbnail_lib
//third_party/jpeg/img:renderer

필요한 요소

막대 아래의 어떤 규칙이 Y를 사용하나요?

bazel query 'bar/... intersect allpaths(bar/..., Y)'

T의 패키지에 직접적으로 포함되는 타겟은 무엇인가요?

bazel query 'same_pkg_direct_rdeps(T)'

종속 항목을 중단하는 방법

bar가 더 이상 X에 종속되지 않도록 하려면 어떤 종속 항목 경로를 중단해야 하나요?

svg 파일에 그래프를 출력하려면 다음 안내를 따르세요.

bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg

기타

//foo-tests 빌드에 몇 개의 순차적 단계가 있나요?

현재 쿼리 언어는 x에서 y까지의 가장 긴 경로를 제공할 수 없지만, 시작점에서 가장 먼 노드 (또는 a)를 찾거나 x부터 y에 이르기까지 가장 긴 경로의 길이를 표시할 수 있습니다. maxrank를 사용합니다.

bazel query 'deps(//foo-tests)' --output maxrank | tail -1
85 //third_party/zlib:zutil.c

결과는 이 빌드에서 순서대로 발생해야 하는 85 길이의 경로가 있음을 나타냅니다.