動作圖查詢 (查詢)

回報問題 查看原始碼 。 。 。 。 夜間。 。 7.3 。 。 7.2 。 。 7.1 。 。 7.0 。 。 6.5

aquery 指令可讓您查詢建構圖中的動作。 它會在事後分析設定的目標圖上運作,以及公開 動作、成果及其關係的相關資訊。

想查看動作/成果屬性時,aquery 就非常實用 從設定的目標圖表產生的結果舉例來說 以及相關輸入/輸出內容/記憶法

這項工具接受多種指令列選項。 值得注意的是,查詢指令會在一般 Bazel 建構作業之上執行,並沿用 建構期間可用的選項組合

可支援的函式也適用於 query,但siblingsbuildfilestests

aquery 輸出內容範例 (未提供特定詳細資料):

$ bazel aquery 'deps(//some:label)'
action 'Writing file some_file_name'
  Mnemonic: ...
  Target: ...
  Configuration: ...
  ActionKey: ...
  Inputs: [...]
  Outputs: [...]

基本語法

以下為 aquery 語法的簡單範例:

bazel aquery "aquery_function(function(//target))"

查詢運算式 (以引號括住) 包含下列內容:

  • aquery_function(...)aquery 專屬的函式。 詳情請參閱下文
  • function(...):標準函式 與傳統 query 相同
  • //target 是相關目標的標籤。
# aquery examples:
# Get the action graph generated while building //src/target_a
$ bazel aquery '//src/target_a'

# Get the action graph generated while building all dependencies of //src/target_a
$ bazel aquery 'deps(//src/target_a)'

# Get the action graph generated while building all dependencies of //src/target_a
# whose inputs filenames match the regex ".*cpp".
$ bazel aquery 'inputs(".*cpp", deps(//src/target_a))'

使用查詢函式

有三個 aquery 函式:

  • inputs:依輸入內容篩選動作。
  • outputs:按照輸出內容篩選動作
  • mnemonic:依記憶篩選動作

expr ::= inputs(word, expr)

inputs 運算子會傳回從建構 expr 產生的動作。 輸入檔案名稱與 word 提供的規則運算式相符。

$ bazel aquery 'inputs(".*cpp", deps(//src/target_a))'

outputsmnemonic 函式的語法很類似。

您亦可結合函式以執行 AND 作業。例如:

  $ bazel aquery 'mnemonic("Cpp.*", (inputs(".*cpp", inputs("foo.*", //src/target_a))))'

上述指令會找出與建構 //src/target_a 相關的所有操作。 其記憶法符合 "Cpp.*" 且輸入內容符合模式 ".*cpp""foo.*"

以下為語法錯誤的示例:

        $ bazel aquery 'deps(inputs(".*cpp", //src/target_a))'
        ERROR: aquery filter functions (inputs, outputs, mnemonic) produce actions,
        and therefore can't be the input of other function types: deps
        deps(inputs(".*cpp", //src/target_a))

選項

建構選項

aquery 會在一般 Bazel 建構作業上執行,因此繼承了一組 選項 可在建構期間使用

查詢選項

--output=(text|summary|proto|jsonproto|textproto), default=text

預設的輸出格式 (text) 是人類可讀的格式, 使用 prototextprotojsonproto 做為機器可讀的格式。 proto 訊息為 analysis.ActionGraphContainer

--include_commandline, default=true

在輸出中包含動作指令列的內容 (可能很大)。

--include_artifacts, default=true

包括動作輸入和輸出內容的名稱 (可能很大)。

--include_aspects, default=true

是否要在輸出內容中加入 Aspect 產生的動作。

--include_param_files, default=false

加入指令中所用參數檔案的內容 (可能很大)。

--include_file_write_contents, default=false

針對 actions.write() 動作加入檔案內容,以及 SourceSymlinkManifest 動作的資訊清單檔案。檔案內容 以 --output=xxxprotofile_contents 欄位傳回。 使用 --output=text 時,輸出結果會 FileWriteContents: [<base64-encoded file contents>]

--skyframe_state, default=false

在未執行額外分析的情況下,請將動作圖從 SkyFrame 中轉儲。

其他工具和功能

查詢 SkyFrame 的狀態

SkyFrame 會評估並 Bazel 的增量模型。在 Bazel 伺服器的每個執行個體中,SkyFrame 都會儲存依附元件圖表 從先前「分析」階段執行時建構而成。

在部分情況下,在 SkyFrame 上查詢動作圖會很有用。 應用情境範例如下:

  1. 執行 bazel build //target_a
  2. 執行 bazel build //target_b
  3. 已產生檔案「foo.out」。

身為 Bazel 使用者,我想判斷 foo.out 是否從建構作業產生 //target_a//target_b

一個可以執行 bazel aquery 'outputs("foo.out", //target_a)',並 bazel aquery 'outputs("foo.out", //target_b)'以便瞭解 建立 foo.out 並接收目標不過 之前建構的目標可以大於 2,這樣就能執行多個 aquery 省去麻煩

或者,您也可以使用 --skyframe_state 標記:

  # List all actions on Skyframe's action graph
  $ bazel aquery --output=proto --skyframe_state

  # or

  # List all actions on Skyframe's action graph, whose output matches "foo.out"
  $ bazel aquery --output=proto --skyframe_state 'outputs("foo.out")'

--skyframe_state 模式下,aquery 會擷取動作圖的內容 SkyFrame 會將 Bazel 執行個體保留在 Bazel 的例項上,(選用) 對其執行篩選, 輸出結果,但不會重新執行分析階段。

特殊注意事項

輸出格式

--skyframe_state 目前僅適用於 --output=proto--output=textproto

在查詢運算式中不納入目標標籤

目前,--skyframe_state 會查詢 SkyFrame 上的整個動作圖表, 無論目標為何讓查詢中指定的目標標籤和 將 --skyframe_state 視為語法錯誤:

  # WRONG: Target Included
  $ bazel aquery --output=proto --skyframe_state **//target_a**
  ERROR: Error while parsing '//target_a)': Specifying build target(s) [//target_a] with --skyframe_state is currently not supported.

  # WRONG: Target Included
  $ bazel aquery --output=proto --skyframe_state 'inputs(".*.java", **//target_a**)'
  ERROR: Error while parsing '//target_a)': Specifying build target(s) [//target_a] with --skyframe_state is currently not supported.

  # CORRECT: Without Target
  $ bazel aquery --output=proto --skyframe_state
  $ bazel aquery --output=proto --skyframe_state 'inputs(".*.java")'

比較查詢輸出

您可以使用 aquery_differ 工具,比較兩個不同查詢叫用的輸出內容。 舉例來說,在變更規則定義後 執行的指令列並未改變aquery_differ 是適當的工具。

您可以在 bazelbuild/bazel 存放區中使用這項工具。 如要使用,請將存放區複製到本機電腦。使用範例:

  $ bazel run //tools/aquery_differ -- \
  --before=/path/to/before.proto \
  --after=/path/to/after.proto \
  --input_type=proto \
  --attrs=cmdline \
  --attrs=inputs

上述指令會傳回查詢輸出的 beforeafter 之間的差異: 有哪些動作出現在其中,但不是其他動作;這兩個動作不同 每個查詢輸出中的指令列/輸入內容...)。執行上述指令的結果如下:

  Aquery output 'after' change contains an action that generates the following outputs that aquery output 'before' change doesn't:
  ...
  /list of output files/
  ...

  [cmdline]
  Difference in the action that generates the following output(s):
    /path/to/abc.out
  --- /path/to/before.proto
  +++ /path/to/after.proto
  @@ -1,3 +1,3 @@
    ...
    /cmdline diff, in unified diff format/
    ...

指令選項

--before, --after:要比較的查詢輸出檔案

--input_type=(proto|text_proto), default=proto:輸入格式 檔案。系統會支援 prototextproto 查詢輸出內容。

--attrs=(cmdline|inputs), default=cmdline:動作屬性 要比較的項目

長寬比

可能的長寬比 然後將套用規則對下列項目產生的查詢輸出: 這些切面會包含「切面路徑」,也就是 套用至產生動作的目標所套用的切面。

Aspect-on-Aspect 範例:

  t0
  ^
  | <- a1
  t1
  ^
  | <- a2
  t2

i 成為規則 ri 的目標,可套用切面 i 並提供給依附元件

假設套用目標 t0 時 a2 產生動作 X。模型會根據 動作 X 的 bazel aquery --include_aspects 'deps(//t2)' 會是:

  action ...
  Mnemonic: ...
  Target: //my_pkg:t0
  Configuration: ...
  AspectDescriptors: [//my_pkg:rule.bzl%**a2**(foo=...)
    -> //my_pkg:rule.bzl%**a1**(bar=...)]
  ...

這表示「X」動作是由套用的 Aspect a2 產生 a1(t0),其中 a1(t0) 是套用 Aspect a1 的結果 且成效達到目標 t0

每個 AspectDescriptor 都有以下格式:

  AspectClass([param=value,...])

AspectClass 可以是 Aspect 類別的名稱 (用於原生切面),或 bzl_file%aspect_name (適用於 Starlark 切面)。AspectDescriptor 是 按照 依附元件圖

連結 JSON 設定檔

查詢可提供有關建構中動作的資訊 (包括執行的原因、 JSON 設定檔 指明執行時機和持續時間。 您可以透過動作的主要輸出,來結合這 2 組資訊。

如何納入動作JSON 設定檔輸出內容並產生設定檔 --experimental_include_primary_output --noexperimental_slim_json_profile。 精簡設定檔與主要輸出內容不相容。動作的主要輸出內容 都包含在內

我們目前並未提供標準工具,無法合併這 2 個資料來源,但你可以 使用上述資訊建立您自己的指令碼。

已知問題

處理共用動作

有時候,動作會 共用 也不必面對設定的目標

在執行階段中,這些共用動作會 只會視為一個,且只會執行一次。 不過,查詢會在執行前、分析後動作圖上運作,因此會將這些結果 例如不同動作的輸出 Artifact 都具有相同的 execPath。因此 對等的構件似乎重複。

如需查詢問題/預定功能清單,請前往 GitHub

常見問題

即使輸入檔案的內容有所變更,ActionKey 仍然不變。

在查詢中,ActionKey 是指從來源取得的 String ActionAnalysisMetadata#getKey:

  Returns a string encoding all of the significant behaviour of this Action that might affect the
  output. The general contract of `getKey` is this: if the work to be performed by the
  execution of this action changes, the key must change.

  ...

  Examples of changes that should affect the key are:

  - Changes to the BUILD file that materially affect the rule which gave rise to this Action.
  - Changes to the command-line options, environment, or other global configuration resources
      which affect the behaviour of this kind of Action (other than changes to the names of the
      input/output files, which are handled externally).
  - An upgrade to the build tools which changes the program logic of this kind of Action
      (typically this is achieved by incorporating a UUID into the key, which is changed each
      time the program logic of this action changes).
  Note the following exception: for actions that discover inputs, the key must change if any
  input names change or else action validation may falsely validate.

這不包括變更輸入檔案的內容,請勿混淆 RemoteCacheClient#ActionKey

更新

如有任何問題/功能要求,請透過這個頁面回報問題。