--- layout: documentation title: Cquery (configurable query) ---

# Cquery (Configurable Query)

## Overview

`cquery` is a command complementary to `query` that properly handles configurations. While `cquery` returns answers that are more correct, it does not replace `query` as it does not support all of `query`'s functions.

`cquery` achieves configuration awareness by running after the analysis phase of a build, unlike traditional `query`, which runs after the loading phase.

The most common use for `cquery` is obtaining answers that correctly evaluate `select()` statements in configurable attributes. For example:

    $ 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
    $ 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)

Keep in mind that `cquery` works only on the configured target graph. Because of this, it does not have insight into artifacts like build actions nor access to `test_suite` rules as they are not configured targets.

## Basic Syntax

A simple example of the syntax for `cquery` is as follows:

`bazel cquery "function(//target)"`

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

- `function(...)` is the function to run on the target. `cquery` supports most of the same functions as traditional `query`.
- `//target` 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 Query How-To for examples.

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

## Functions

Of the set of functions supported by the traiditional `query`, `cquery` supports all but siblings, buildfiles, and tests. The functions listed below are `cquery`-specific.

### config

`expr ::= config(expr, word)`

The `config` 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 `target`, `host`, or `null` but we hope to expand this functionality to be able to input custom configurations (or custom configuration diffs from the default target configuration).

`$ bazel cquery config(//foo, host) --universe_scope=//bar`

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

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.

## Options

### Build Options

`cquery` runs on top of a regular Bazel build and thus inherits the set of options available during a build.

### Cquery options

#### `--universe_scope` (comma-separated list)

Often, the dependencies of configured targets go through transitions, 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:

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

Genrules configure their tools in the host configuration so the following queries would produce the following outputs:

Query | Target Built | Output
--- | --- | ---
bazel cquery "//x:tool" | //x:tool | //x:tool(targetconfig)
bazel cquery "//x:tool" --universe_scope="//x:my_gen" | //x:my_gen | //x:tool(hostconfig)

If this flag is set, its contents are built. If it's not set, all targets mentioned in the query expression are built 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). `cquery` returns results in the transitive closure of these top-level targets.

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 `--universe_scope` 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 `deps(//foo)`.

#### `--implicit_deps` (boolean, default=True)

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

#### `--host_deps` (boolean, default=True)

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 host configuration. If the queried target is in a non-host configuration, setting `--nohost_deps` will only return targets that also are in non-host configurations. If the queried target is in a host configuration, setting `--nohost_deps` will only return targets also in the host configuration.

## Output Formats

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.

### Transitions

Configuration transitions 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 `tools` 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.

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

## Known Issues

- Inaccessible configurations. With the exception of the host configuration being printed as `HOST`, 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).
- No support for aspects, output options, or recursive target patterns (/...).
- Non-deterministic output. `Cquery` does not automatically wipe the build graph from previous commands and is therefore prone to picking up results from past queries. For example, `genquery` exerts a host transition on its `tools` attribute - that is, it configures its tools in the host configuration. We can see the lingering effects of that transition below.

    $ 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 (host_config)
    ...

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

Workaround: change any startup option to force re-analysis of configured targets. For example, add `--test_arg=<whatever>` to your build command.

## Updates

The Bazel configurability team is continuously improving `cquery`. If you want to ask questions, stay updated, or get involved, contact juliexxia@google.com