이 페이지에서는 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 파일에 없지만 간접 종속 항목입니다. 이 종속 항목 경로를 어떻게 추적할 수 있나요? 여기에는 allpaths
및 somepath
이라는 두 가지 유용한 함수가 있습니다. 빌드한 아티팩트에 포함된 항목만 신경 쓰고 가능한 모든 작업은 신경 쓰지 않는 경우 --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 쿼리는 지정된 범위에서 역 종속 항목을 쿼리할 수 있는 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
트리는 foo/contrib
를 제외하고 어떤 패키지에 종속되나요?
bazel query 'deps(foo/... except foo/contrib/...)' --output package
어떤 규칙 종속 항목이 있나요?
막대가 의존하는 genproto 규칙은 무엇인가요?
bazel query 'kind(genproto, deps(bar/...))'
서블릿 트리에서 Java 바이너리 규칙에 의해 전이적으로 종속되는 일부 JNI (C++) 라이브러리의 정의를 찾습니다.
bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...이제 이 바이너리에 종속된 모든 Java 바이너리의 정의를 찾아봅니다.
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를 빌드하는 데 필요한 전체 Java 소스 파일 세트는 무엇인가요?
소스 파일:
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 테스트를 빌드하는 데 필요한 전체 Java 소스 파일 세트는 무엇인가요?
소스 파일:
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))'
이 종속 항목이 존재하는 이유는 무엇인가요?
bar
가 groups2
에 의존하는 이유는 무엇인가요?
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 패키지에서 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로의 가장 긴 경로를 제공할 수 없지만, 시작점으로부터 가장 먼 노드(또는 하나의 노드)를 찾거나 x에서 x에 종속된 모든 y로의 가장 긴 경로의 길이를 표시할 수 있습니다. maxrank
사용:
bazel query 'deps(//foo-tests)' --output maxrank | tail -1 85 //third_party/zlib:zutil.c
결과는 이 빌드에서 순서대로 발생해야 하는 길이 85의 경로가 있음을 나타냅니다.