aboutsummaryrefslogtreecommitdiffhomepage
path: root/site/docs/cquery.html
blob: 898e190f52bf8086a95d3cee43323dda796fc36a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
---
layout: documentation
title: Cquery (configurable query)
---

<h1>Cquery (Configurable Query)</h1>

<ul class="toc">
  <li><a href="#overview">Overview</a></li>
  <li><a href="#basic-syntax">Basic Syntax</a></li>
  <li><a href="#functions">Functions</a></li>
  <li><a href="#options">Options</a></li>
  <li><a href="#known-issues">Known Issues</a></li>
  <li><a href="#updates">Updates</a></li>
</ul>

<h2 id='overview'>Overview</h2>

<p>
  <code>cquery</code> is a command complementary to <code>query</code> that properly handles
  configurations. While <code>cquery</code> returns answers that are more correct, it does not
  replace <code>query</code> as it does not support all of <code>query</code>'s functions.</p>
<p>
  <code>cquery</code> achieves configuration awareness by running after the
  <a href="https://docs.bazel.build/versions/master/skylark/concepts.html#evaluation-model">analysis phase</a>
  of a build, unlike traditional <code>query</code>, which runs after the loading phase.</p>
<p>
  The most common use for <code>cquery</code> is obtaining answers that correctly evaluate
  <a href="https://docs.bazel.build/versions/master/be/common-definitions.html#configurable-attributes"><code>select()</code></a>
  statements in configurable attributes. For example:
</p>

<pre>
$ cat > tree/BUILD &lt;&lt;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
$ bazel query "deps(//tree:ash)" --define species=excelsior --noimplicit_deps
//tree:ash
//tree:white-ash
//tree:manna-ash
//tree:common-ash

#cquery
$ bazel cquery "deps(//tree:ash)" --define species=excelsior --noimplicit_deps
//tree:ash (hash-of-config)
//tree:manna-ash (hash-of-config)
</pre>


<p>
  Keep in mind that <code>cquery</code> works only on the configured target graph. Because of this,
  it does not have insight into artifacts like build actions nor access to
  <code><a href="https://docs.bazel.build/versions/master/be/general.html#test_suite">test_suite</a></code>
  rules as they are not configured targets.
</p>

<h2 id='basic-syntax'>Basic Syntax</h2>

<p>A simple example of the syntax for <code>cquery</code> is as follows:</p>

<p><code>bazel cquery "function(//target)"</code></p>

<p>The query expression (in quotes) consists of the following:

<ul>
  <li>
    <b><code>function(...)</code></b> is the function to run on the target. <code>cquery</code>
    supports most of the same <a href="https://docs.bazel.build/versions/master/query.html#functions">functions</a>
    as traditional <code>query</code>.
  </li>
  <li><b><code>//target</code></b> is the expression fed to the function. In this example, the
    expression is a simple target, but the query language also allows nesting of functions.
    See the <a href="query-how-to.md">Query How-To</a> for examples.
   </li>
</ul>

<p>
  Note that <code>cquery</code> requires a target on which to run the
  loading and analysis phases. Unless otherwise specified, <code>cquery</code> parses
  the target(s) listed in the query expression. See the <code>--universe_scope</code>
  option below for querying targets built under other targets.
</p>

<h2 id='functions'>Functions</h2>

<p>
  Of the <a href="https://docs.bazel.build/versions/master/query.html#functions" title="list of query functions">set of functions</a>
  supported by the traiditional <code>query</code>, <code>cquery</code> supports all but siblings, buildfiles, and tests. The
  functions listed below are <code>cquery</code>-specific.
</p>

<h3>config</h3>

<p><code>expr ::= config(expr, word)</code></p>

<p>
  The <code>config</code> operator attempts to return the result of the first argument, configured
  in the configuration specified by the second argument. Today, the second argument can only take in
  three options <code>target</code>, <code>host</code>, or <code>null</code> but we hope to expand
  this functionality to be able to input custom configurations (or custom configuration diffs from
  the default target configuration).
</p>

<p><code>$ bazel cquery config(//foo, host) --universe_scope=//bar</code></p>

<p>
  Note that the above example query will return <code>//foo</code> configured in the host configuration
  <em>if and only if</em> <code>//foo</code> exists in the host configuration in the universe of
  this query (which we've set to the transitive closure of <code>//bar</code>).
</p>

<p>
  If not all results of the first argument can be found in the specified
  configuration, then only those that can be found are returned. If no results of the
  first argument can be found in the specified configuration, an error is thrown.
</p>

<h2 id='options'>Options</h2>

<h3>Build Options</h3>

<p>
  <code>cquery</code> runs on top of a regular Bazel build and thus inherits the set of
  <a href="https://docs.bazel.build/versions/master/command-line-reference.html#build-options">options</a>
  available during a build.
</p>

<h3>Cquery options</h3>

<h4><code>--universe_scope</code> (comma-separated list)</h4>

<p>
  Often, the dependencies of configured targets go through
  <a href="https://docs.bazel.build/versions/master/skylark/rules.html#configurations">transitions</a>,
  which causes their configuration to differ from their dependent. This flag allows you to query
  a target as if it were built as a dependency or a transitive dependency of another target. For
  example:
</p>

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

<p>
  Genrules configure their tools in the
  <a href="https://docs.bazel.build/versions/master/skylark/rules.html#configurations">host configuration</a>
  so the following queries would produce the following outputs:
</p>

<table class="table table-condensed table-bordered table-params">
  <thead>
    <tr>
      <th>Query</th>
      <th>Target Built</th>
      <th>Output</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>bazel cquery "//x:tool"</td>
      <td>//x:tool</td>
      <td>//x:tool(targetconfig)</td>
    </tr>
    <tr>
      <td>bazel cquery "//x:tool" --universe_scope="//x:my_gen"</td>
      <td>//x:my_gen</td>
      <td>//x:tool(hostconfig)</td>
    </tr>
  </tbody>
</table>

<p>
  If this flag is set, its contents are built. <em>If it's not set, all targets
  mentioned in the query expression are built</em> instead. The transitive closure of the
  built targets are used as the universe of the query. Either way, the targets to
  be built must be buildable at the top level (that is, compatible with top-level
  options). <code>cquery</code> returns results in the transitive closure of these
  top-level targets.
</p>

<p>
  Even if it's possible to build all targets in a query expression at the top
  level, it may be beneficial to not do so. For example, explicitly setting
  <code>--universe_scope</code> could prevent building targets multiple times in
  configurations you don't care about. It could also help specify which configuration version of a
  target you're looking for (since it's not currently possible
  to fully specify this any other way). We recommend that you set this
  flag if your query expression is more complex than <code>deps(//foo)</code>.
</p>

<h4><code>--implicit_deps</code> (boolean, default=True)</h4>

<p>
  Setting this flag to false filters out all results that aren't explicitly set in
  the BUILD file and instead set elsewhere by Bazel.
</p>

<h4><code>--host_deps</code> (boolean, default=True)</h4>

<p>
  Setting this flag to false filters out all configured targets for which the
  path from the queried target to them crosses a transition between the target
  configuration and the
  <a href="https://docs.bazel.build/versions/master/skylark/rules.html#configurations">host configuration</a>.
  If the queried target is in a non-host configuration, setting <code>--nohost_deps</code> will
  only return targets that also are in non-host configurations. If the queried
  target is in a host configuration, setting <code>--nohost_deps</code> will only return
  targets also in the host configuration.
</p>

<h2 id='output-formats'>Output Formats</h2>

<p> By default, cquery outputs results in a dependency-ordered list of label and configuration pairs.
There are other options for exposing the results as well. </p>

<h3> Transitions </h3>

<p>
  Configuration <a href="https://docs.bazel.build/versions/master/skylark/rules.html#configurations">transitions</a>
  are used to build targets underneath the top level targets in different configurations than the top
  level targets. For example, a target might impose a transition to the host transition on all
  dependencies in its <code>tools</code> attribute. These are known as attribute transitions.
  Rules can also impose transitions on their own configurations, known as rule class transitions.
  This output format outputs information about these transitions such as what type they are and the
  effect they have on build options.
</p>

<p>This output format is triggered by the <code>--transitions</code> flag which by default is set to
  <code>NONE</code>. It can be set to <code>FULL</code> or <code>LITE</code> mode. <code>FULL</code>
  mode outputs information about rule class transitions and attribute transitions including a detailed
  diff of the options before and after the transition. <code>LITE</code> mode outputs the same information
  without the options diff.
</p>

<h2 id='known-issues'>Known Issues</h2>

<ul>
  <li>
    <strong>Inaccessible configurations.</strong> With the exception of the host configuration being
    printed as <code>HOST</code>, Configurations are currently output as
    hashes and there is no way for the user to input them (and thus to directly
    specify the configuration to query a target in).</li>
  <li>
    <strong>No support for <a href="https://docs.bazel.build/versions/master/skylark/aspects.html">aspects</a>,
    <a href="https://docs.bazel.build/versions/master/query.html#output-formats" title="list of query output formats">output
    options</a>, or recursive target patterns (/...).</strong></li>
  <li>
    <strong>Non-deterministic output.</strong> <code>Cquery</code> does not automatically wipe the build
    graph from previous commands and is therefore prone to picking up results
    from past queries. For example, <code>genquery</code> exerts a host transition on its <code>tools</code>
    attribute - that is, it configures its tools in the
    <a href="https://docs.bazel.build/versions/master/skylark/rules.html#configurations">host configuration</a>.
    We can see the lingering effects of that transition below.</li>
</ul>

<pre>
$ cat > foo/BUILD &lt;&lt;&lt;EOF
genrule(
    name = "my_gen",
    srcs = ["x.in"],
    outs = ["x.cc"],
    cmd = "$(locations :tool) $&lt; >$@",
    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 (host_config)
...

$ bazel cquery "//foo:tool"
tool(host_config)
</pre>

<p>
  Workaround: change any startup option to force re-analysis of configured targets. For example,
  add <code>--test_arg=&lt;whatever&gt;</code> to your build command.
</p>

<h2 id='updates'>Updates</h2>

<p>
  The Bazel configurability team is continously improving <code>cquery</code>. If you want to
  ask questions, stay updated, or get involved, contact juliexxia@google.com
</p>