구성 가능한 검색어 (cquery)

<ph type="x-smartling-placeholder"></ph> 문제 신고 소스 보기 1박 · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

cquery은(는) 올바르게 처리할 수 있는 query의 변형입니다. select() 및 빌드 옵션 빌드에 미치는 영향 그래프로 확인할 수 있습니다.

이를 위해 Bazel 분석의 결과를 바탕으로 단계, 이러한 효과를 통합합니다. 반면 query는 옵션이 평가되기 전 Bazel의 로드 단계

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

$ cat > tree/BUILD <<EOF
sh_library(
    name = "ash",
    deps = select({
        ":excelsior": [":manna-ash"],
        ":americana": [":white-ash"],
        "//conditions:default": [":common-ash"],
    }),
)
sh_library(name = "manna-ash")
sh_library(name = "white-ash")
sh_library(name = "common-ash")
config_setting(
    name = "excelsior",
    values = {"define": "species=excelsior"},
)
config_setting(
    name = "americana",
    values = {"define": "species=americana"},
)
EOF
# Traditional query: query doesn't know which select() branch you will choose,
# so it conservatively lists all of possible choices, including all used config_settings.
$ bazel query "deps(//tree:ash)" --noimplicit_deps
//tree:americana
//tree:ash
//tree:common-ash
//tree:excelsior
//tree:manna-ash
//tree:white-ash

# cquery: cquery lets you set build options at the command line and chooses
# the exact dependencies that implies (and also the config_setting targets).
$ bazel cquery "deps(//tree:ash)" --define species=excelsior --noimplicit_deps
//tree:ash (9f87702)
//tree:manna-ash (9f87702)
//tree:americana (9f87702)
//tree:excelsior (9f87702)

각 결과에는 다음의 고유 식별자 (9f87702)가 포함됩니다. 포드의 구성을 빌드됩니다

cquery는 구성된 타겟 그래프에 대해 실행되기 때문입니다. 통계가 없습니다 test_suite에 대한 액세스나 빌드 작업 같은 아티팩트에 이러한 규칙은 구성된 대상이 아니기 때문입니다. 전자의 경우 aquery를 참고하세요.

기본 구문

간단한 cquery 호출은 다음과 같습니다.

bazel cquery "function(//target)"

"function(//target)" 쿼리 표현식은 다음과 같이 구성됩니다.

  • function(...)은 타겟에서 실행할 함수입니다. cquery 대부분의 query함수 및 몇 가지 새로운 기능이 있습니다.
  • //target은 함수에 제공되는 표현식입니다. 이 예에서 단순한 타겟입니다. 하지만 쿼리 언어는 함수 중첩도 허용합니다. 예시는 쿼리 가이드를 참고하세요.

cquery에는 로드 및 분석을 실행하는 대상이 필요합니다. 있습니다. 달리 명시되지 않는 한 cquery는 쿼리 표현식을 사용합니다. --universe_scope를 참고하세요. 최상위 빌드 대상의 종속 항목을 쿼리하는 데 사용됩니다

구성

다음 행은,

//tree:ash (9f87702)

//tree:ash는 ID가 9f87702인 구성에서 빌드되었음을 의미합니다. 대부분의 경우 빌드 옵션 값의 불투명 해시이며 구성할 수 있습니다

구성의 전체 콘텐츠를 보려면 다음을 실행합니다.

$ bazel config 9f87702

9f87702는 전체 ID의 프리픽스입니다. 이는 전체 ID가 SHA-256 해시가 길고 추적하기 어렵습니다. cquery는 모든 유효한 접두어로 사용할 수 있으며, 이는 Git 짧은 해시. 전체 ID를 보려면 $ bazel config를 실행합니다.

대상 패턴 평가

//foocqueryquery의 의미가 다릅니다. 이는 cquery구성된 대상을 평가하며 빌드 그래프에는 여러 개의 타겟이 있을 수 있습니다. 구성된 //foo 버전입니다.

cquery의 경우 쿼리 표현식의 대상 패턴은 해당 패턴과 일치하는 라벨이 있는 구성된 모든 대상에 전송합니다. 출력: 확정적이지만 cquery는 다음 순서 이외의 순서를 보장하지 않습니다. 핵심 검색어 주문 계약을 참조하세요.

이렇게 하면 query를 사용할 때보다 쿼리 표현식에서 더 섬세한 결과가 생성됩니다. 예를 들어 다음은 여러 결과를 생성할 수 있습니다.

# Analyzes //foo in the target configuration, but also analyzes
# //genrule_with_foo_as_tool which depends on an exec-configured
# //foo. So there are two configured target instances of //foo in
# the build graph.
$ bazel cquery //foo --universe_scope=//foo,//genrule_with_foo_as_tool
//foo (9f87702)
//foo (exec)

쿼리할 인스턴스를 정확하게 선언하려면 다음을 사용합니다. config 함수

query대상 패턴 보기 대상 패턴에 대한 자세한 내용은 문서를 참조하세요.

함수

함수 집합 query, cqueryallrdeps님, buildfiles, rbuildfiles, siblings, testsvisible

cquery에는 다음과 같은 새 함수도 도입되었습니다.

config

expr ::= config(expr, word)

config 연산자는 다음에 대해 구성된 타겟을 찾으려고 시도합니다. 첫 번째 인수로 나타내는 라벨과 두 번째 인수입니다.

두 번째 인수에 유효한 값은 null 또는 커스텀 구성 해시가 필요합니다. 해시는 $ bazel config 또는 이전 cquery의 출력에서 가져올 수 있습니다.

예:

$ bazel cquery "config(//bar, 3732cc8)" --universe_scope=//foo
$ bazel cquery "deps(//foo)"
//bar (exec)
//baz (exec)

$ bazel cquery "config(//baz, 3732cc8)"

지정된 찾을 수 있는 것만 반환됩니다. 결과가 없는 경우 지정된 구성에서 찾을 수 있는 경우 쿼리가 실패합니다.

옵션

빌드 옵션

cquery는 일반 Bazel 빌드에서 실행되므로 옵션을 제공합니다.

cquery 옵션 사용

--universe_scope (쉼표로 구분된 목록)

구성된 대상의 종속 항목은 전환 이로 인해 구성이 종속 항목과 달라집니다. 이 플래그 : 타겟이 종속 항목 또는 전이적으로 빌드된 것처럼 타겟을 쿼리할 수 있음 종속되지 않도록 주의해야 합니다 예를 들면 다음과 같습니다.

# x/BUILD
genrule(
     name = "my_gen",
     srcs = ["x.in"],
     outs = ["x.cc"],
     cmd = "$(locations :tool) $< >$@",
     tools = [":tool"],
)
cc_binary(
    name = "tool",
    srcs = ["tool.cpp"],
)

Genrule은 실행 구성 따라서 다음 쿼리는 다음과 같은 출력을 생성합니다.

쿼리 빌드 목표 출력
bazel cquery '//x:도구' //x:tool //x:tool(targetconfig)
bazel cquery '//x:도구' --universe_scope=&quot;//x:my_gen&quot; //x:my_gen //x:tool(execconfig)

이 플래그를 설정하면 플래그의 콘텐츠가 빌드됩니다. 설정하지 않으면 모든 타겟이 대신 쿼리 표현식에 언급된 모든 종속 항목이 빌드됩니다. 쿼리의 세계로 사용됩니다. 어떤 방법을 사용하든 빌드는 최상위 수준에서 빌드 가능해야 합니다. 즉, 최상위 수준 옵션). cquery는 임시로 닫힌 결과를 반환합니다. 최상위 수준 타겟이 있습니다.

상단의 쿼리 표현식에 모든 대상을 빌드할 수 있더라도 그렇게 하지 않는 것이 좋습니다. 예를 들어, --universe_scope으로 인해 다음 위치에서 타겟이 여러 번 구축되지 않을 수 있습니다. 구성하지 않도록 하는 것이 좋습니다 또한 애플리케이션의 특정 구성 버전을 지정하는 데 현재 고객층이 원하는 타겟에 다른 방법으로 완전히 지정할 수 있음). 이 플래그를 쿼리 표현식이 deps(//foo)보다 더 복잡한 경우

--implicit_deps (불리언, 기본값=True)

이 플래그를 false로 설정하면 명시적으로 설정되지 않은 모든 결과가 필터링됩니다. BUILD 파일로 가져오고 대신 Bazel이 다른 곳에 설정합니다. 여기에는 해결된 필터링이 포함됩니다. 있습니다.

--tool_deps (불리언, 기본값=True)

이 플래그를 false로 설정하면 쿼리된 대상에서 대상까지의 경로가 대상 간 전환을 교차합니다. 구성 및 비대상 구성에 대해 자세히 알아보세요. 쿼리된 대상이 대상 구성에 있는 경우 --notool_deps를 설정하면 타겟 구성에도 있는 타겟만 반환합니다. 쿼리된 타겟이 비대상 구성에 있습니다. --notool_deps을(를) 설정하면 비대상 구성에서도 마찬가지입니다 이 설정은 일반적으로 필터링에 영향을 주지 않습니다. 결정된 도구 모음의 개수입니다.

--include_aspects (불리언, 기본값=True)

요소에 의해 추가된 종속 항목을 포함합니다.

이 플래그가 사용 중지되면 cquery somepath(X, Y) 및 X가 관점을 통해서만 Y에 의존하면 cquery deps(X) | grep 'Y'는 Y를 생략합니다.

출력 형식

기본적으로 cquery 출력은 종속 항목에 정렬된 라벨 및 구성 쌍 목록을 생성합니다. 결과를 노출하는 다른 옵션도 있습니다.

화면전환

--transitions=lite
--transitions=full

구성 전환 서로 다른 여러 위치의 최상위 타겟 아래에 타겟을 빌드하는 데 더 높은 수준의 성능을 적용할 수 있습니다

예를 들어, 대상은 모든 이메일에서 exec 구성으로의 전환을 tools 속성에 종속 항목을 추가합니다. 이를 속성이라고 하며 사용할 수 있습니다. 또한 규칙은 자체 구성에 전환을 부과할 수도 있습니다. 규칙 클래스 전환이라고 합니다 이 출력 형식은 유형 및 빌드에 미치는 영향 등 이러한 전환이 있습니다.

이 출력 형식은 기본적으로 다음과 같은 --transitions 플래그에 의해 트리거됩니다. NONE로 설정합니다. FULL 또는 LITE 모드로 설정할 수 있습니다. FULL 모드 출력 속성 전환에 대한 정보를 옵션 간의 차이점에 대해 자세히 알아보겠습니다. 교통수단 LITE개 옵션 diff 없이 동일한 정보를 출력합니다.

프로토콜 메시지 출력

--output=proto

이 옵션을 사용하면 결과 대상이 바이너리 프로토콜로 인쇄됩니다. 버퍼 형태입니다. 프로토콜 버퍼의 정의는 src/main/protobuf/analysis_v2.proto.

CqueryResult는 cquery 결과가 포함된 최상위 메시지입니다. 그것은 ConfiguredTarget 메시지 목록과 Configuration 목록이 있습니다. 메시지를 보낼 수 있습니다 각 ConfiguredTarget에는 값이 동일한 configuration_id가 있습니다. 상응하는 Configuration 메시지의 id 필드 값으로 변환합니다.

--[no]proto:include_configurations

기본적으로 cquery 결과는 각 구성할 수 있습니다. 이 정보를 생략하고 proto 출력을 얻고 싶은 경우 proto 출력과 정확히 동일한 형식이 지정된 경우 이 플래그를 false로 설정하세요.

쿼리의 proto 출력 문서 참조 proto 출력 관련 옵션을 확인하세요.

그래프 출력

--output=graph

이 옵션을 사용하면 Graphviz 호환 .dot 파일로 출력이 생성됩니다. query의 이벤트 보기 자세한 내용은 그래프 출력 문서를 참고하세요. cquery 또한 --graph:node_limit--graph:factored입니다.

파일 출력

--output=files

이 옵션은 일치하는 각 타겟에 의해 생성된 출력 파일의 목록을 출력합니다. bazel build 끝에 출력된 목록과 유사한 쿼리로 쿼리를 실행합니다. 있습니다. 출력에는 요청된 포드에서 결정된 --output_groups 플래그 여기에는 소스 파일이 포함됩니다.

이 출력 형식에서 내보낸 모든 경로는 execrootbazel info execution_root을(를) 통해 bazel-out 편의 심볼릭 링크가 있는 경우 기본 저장소의 파일 경로도 작업공간을 기준으로 확인됩니다. 를 참조하세요.

Starlark를 사용하여 출력 형식 정의

--output=starlark

이 출력 형식은 Starlark 함수를 실행하고 값을 출력합니다. 반환합니다. --starlark:file 플래그는 클러스터의 위치를 지정합니다. 단일 매개변수로 format 함수를 정의하는 Starlark 파일 target입니다. 이 함수는 각 타겟 표시됩니다. 또는 편의를 위해 def format(target): return expr로 선언된 함수의 본문입니다. --starlark:expr 플래그.

'cquery' 스타라크 방언

cquery Starlark 환경은 BUILD 또는 .bzl 파일과 다릅니다. 여기에는 다음이 포함됩니다. 올코어 Starlark 기본 제공 상수 및 함수 아래에 설명된 몇 가지 cquery 관련 방법이 있지만 예를 들어 glob은 포함되지 않습니다. native 또는 rule이며 로드 문을 지원하지 않습니다.

build_options(target)

build_options(target)는 키가 빌드 옵션 식별자인 맵을 반환합니다 (자세한 내용은 구성) 그 값이 Starlark 값입니다. 법적 Starlark가 아닌 값이 있는 빌드 옵션 이 맵에서는 값이 생략됩니다.

타겟이 입력 파일인 경우 build_options(target)는 입력 파일로 None을 반환합니다. 대상의 구성은 null입니다.

제공업체(대상)

providers(target)는 키가 제공업체 (예: "DefaultInfo")를 포함하고 이 속성의 값이 Starlark 값입니다. 제공업체 법적 Starlark 값이 아닌 값은 이 맵에서 생략됩니다.

//foo에서 생성된 모든 파일의 기본 이름을 공백으로 구분된 목록으로 출력합니다.

  bazel cquery //foo --output=starlark \
    --starlark:expr="' '.join([f.basename for f in target.files.to_list()])"

규칙 대상에 의해 생성된 모든 파일의 경로를 공백으로 구분된 목록으로 //bar 및 하위 패키지:

  bazel cquery 'kind(rule, //bar/...)' --output=starlark \
    --starlark:expr="' '.join([f.path for f in target.files.to_list()])"

//foo로 등록된 모든 작업의 연상 기호 목록을 출력합니다.

  bazel cquery //foo --output=starlark \
    --starlark:expr="[a.mnemonic for a in target.actions]"

cc_library //baz에 의해 등록된 컴파일 출력의 목록을 출력합니다.

  bazel cquery //baz --output=starlark \
    --starlark:expr="[f.path for f in target.output_groups.compilation_outputs.to_list()]"

//foo를 빌드할 때 명령줄 옵션 --javacopt의 값을 출력합니다.

  bazel cquery //foo --output=starlark \
    --starlark:expr="build_options(target)['//command_line_option:javacopt']"

정확히 하나의 출력으로 각 대상의 라벨을 출력합니다. 이 예에서는 파일에 정의된 Starlark 함수.

  $ cat example.cquery

  def has_one_output(target):
    return len(target.files.to_list()) == 1

  def format(target):
    if has_one_output(target):
      return target.label
    else:
      return ""

  $ bazel cquery //baz --output=starlark --starlark:file=example.cquery

각 대상의 라벨(엄격히 Python 3)을 출력합니다. 이 예에서는 파일에 정의된 Starlark 함수.

  $ cat example.cquery

  def format(target):
    p = providers(target)
    py_info = p.get("PyInfo")
    if py_info and py_info.has_py3_only_sources:
      return target.label
    else:
      return ""

  $ bazel cquery //baz --output=starlark --starlark:file=example.cquery

사용자 정의 제공업체에서 값을 추출합니다.

  $ cat some_package/my_rule.bzl

  MyRuleInfo = provider(fields={"color": "the name of a color"})

  def _my_rule_impl(ctx):
      ...
      return [MyRuleInfo(color="red")]

  my_rule = rule(
      implementation = _my_rule_impl,
      attrs = {...},
  )

  $ cat example.cquery

  def format(target):
    p = providers(target)
    my_rule_info = p.get("//some_package:my_rule.bzl%MyRuleInfo'")
    if my_rule_info:
      return my_rule_info.color
    return ""

  $ bazel cquery //baz --output=starlark --starlark:file=example.cquery

cquery와 쿼리 비교

cquery과(와) query은(는) 서로 보완하며 다음 영역에서 뛰어납니다. 있습니다. 다음 사항을 고려하여 적합한 방법을 결정하세요.

  • cquery는 특정 select() 브랜치를 따라가 정확하게 모델링할 수 있습니다. query에서 알지 못함 빌드가 선택하는 브랜치이므로 모든 브랜치를 포함하여 과대 근사치가 됩니다.
  • cquery의 정밀도를 얻으려면 훨씬 더 많은 그래프를 빌드해야 합니다. query는 지원합니다. 특히 cquery query만 실행되는 동안 구성된 대상 평가 대상을 평가합니다. 이렇게 하면 시간이 더 많이 걸리고 더 많은 메모리를 사용합니다.
  • cquery 해석 쿼리 언어가 모호성을 야기함 query에서 피하는 방법 예를 들어 "//foo"이 두 가지 구성에 있는 경우 cquery "deps(//foo)"에서 사용해야 할까요? 이때 config 함수가 도움이 될 수 있습니다.
  • 최신 도구인 cquery는 특정 용도를 지원하지 않습니다. 있습니다. 자세한 내용은 알려진 문제를 참고하세요.

알려진 문제

cquery가 '빌드'하는 모든 타겟 구성이 동일해야 합니다.

쿼리를 평가하기 전에 cquery는 할 수 있습니다. 대상 "빌드" 기본적으로 쿼리에 표시되는 모든 라벨 중에서 선택됩니다. 표현식 (이는 재정의될 수 있음) --universe_scope) 이러한 구성이 동일해야 합니다.

이들은 일반적으로 최상위 '타겟'을 공유하지만 구성, 규칙은 자체 구성을 변경할 수 있으며 들어오는 가장자리 전환. 여기서 cquery는 부족합니다.

해결 방법: 가능하면 --universe_scope을 더 엄격한 값으로 설정합니다. 범위를 제공합니다 예를 들면 다음과 같습니다.

# This command attempts to build the transitive closures of both //foo and
# //bar. //bar uses an incoming edge transition to change its --cpu flag.
$ bazel cquery 'somepath(//foo, //bar)'
ERROR: Error doing post analysis query: Top-level targets //foo and //bar
have different configurations (top-level targets with different
configurations is not supported)

# This command only builds the transitive closure of //foo, under which
# //bar should exist in the correct configuration.
$ bazel cquery 'somepath(//foo, //bar)' --universe_scope=//foo

--output=xml을(를) 지원하지 않습니다.

비확정 출력.

cquery는 빌드 그래프를 자동으로 완전 삭제하지 않음 이전 명령어에서 결과를 가져오는 경향이 있습니다. 쿼리합니다. 예를 들어 genquery는 다음 위치에 exec 전환을 실행합니다. tools 속성입니다. 즉, exec 구성을 실행합니다.

아래에서 전환의 지속적인 효과를 확인할 수 있습니다.

$ cat > foo/BUILD <<<EOF
genrule(
    name = "my_gen",
    srcs = ["x.in"],
    outs = ["x.cc"],
    cmd = "$(locations :tool) $< >$@",
    tools = [":tool"],
)
cc_library(
    name = "tool",
)
EOF

    $ bazel cquery "//foo:tool"
tool(target_config)

    $ bazel cquery "deps(//foo:my_gen)"
my_gen (target_config)
tool (exec_config)
...

    $ bazel cquery "//foo:tool"
tool(exec_config)

해결 방법: 구성된 대상을 강제로 재분석하도록 시작 옵션을 변경합니다. 예를 들어 빌드 명령어에 --test_arg=&lt;whatever&gt;를 추가합니다.

문제 해결

재귀 대상 패턴 (/...)

다음과 같은 문제가 발생할 경우:

$ bazel cquery --universe_scope=//foo:app "somepath(//foo:app, //foo/...)"
ERROR: Error doing post analysis query: Evaluation failed: Unable to load package '[foo]'
because package is not in scope. Check that all target patterns in query expression are within the
--universe_scope of this query.

이는 //foo 패키지가 범위에 속하지 않음을 잘못 나타냅니다. --universe_scope=//foo:app에 포함되어 있습니다. 이는 Kubernetes의 설계 제한으로 인해 cquery 이 문제를 해결하려면 유니버스에 명시적으로 //foo/...를 포함하세요. 범위:

$ bazel cquery --universe_scope=//foo:app,//foo/... "somepath(//foo:app, //foo/...)"

작동하지 않는 경우 (예: //foo/...의 일부 타겟이 빌드하려는 경우)를 통해 수동으로 패턴을 패키지로 나뉩니다.

# Replace "//foo/..." with a subshell query call (not cquery!) outputting each package, piped into
# a sed call converting "<pkg>" to "//<pkg>:*", piped into a "+"-delimited line merge.
# Output looks like "//foo:*+//foo/bar:*+//foo/baz".
#
$  bazel cquery --universe_scope=//foo:app "somepath(//foo:app, $(bazel query //foo/...
--output=package | sed -e 's/^/\/\//' -e 's/$/:*/' | paste -sd "+" -))"