|
| 1 | +## Auto-configured builds examples |
| 2 | +**Requirements: Bazel 9.0 or newer.** |
| 3 | + |
| 4 | +*Auto-configured builds* is a Bazel 9.0+ feature that lets project owners declare which build flags should apply to their project's targets. |
| 5 | + |
| 6 | +This makes it possible to write |
| 7 | + |
| 8 | + $ bazel test //foo/... |
| 9 | + |
| 10 | +and bazel automatically adds whatever flags are appropriate for `foo`'s builds. |
| 11 | + |
| 12 | +This is similar to [bazelrc](https://bazel.build/run/bazelrc) with the crucial difference that bazelrc files are *user-registered*, not *project-registered*. That means `bazelrc`-added flags depend on who does the build and which `bazelrcs` they've registered, not which targets they're building. |
| 13 | + |
| 14 | +The features described here make it easier for *anyone* to write `$ bazel test //foo/...` - a project dev, external contributor, library maintainer, IDE, AI agent, or CI system - and consistently get the same results with the same flags regardless of how they've set up their workspace or if they've ever built the project before. Project owners can then ensure everyone builds with correct, project-approved flags. |
| 15 | + |
| 16 | +More info at https://github.com/bazelbuild/bazel/issues/24839. |
| 17 | + |
| 18 | +### `PROJECT.scl` |
| 19 | +Flag settings are declared in a file called `PROJECT.scl`. This lives in your source repository next to your `BUILD` files. |
| 20 | + |
| 21 | +`$ bazel test //foo/bar/baz:all` looks for a `PROJECT.scl` in `foo/bar/baz/` to find the project's flag settings. If that file doesn't exist, it looks in `foo/bar/`, then `foo/`, and so on until it either finds a match or determines the project has no flag settings. |
| 22 | + |
| 23 | +This also applies to `bazel build` and `bazel cquery`. |
| 24 | + |
| 25 | +### Project-wide settings with warnings for unexpected flags |
| 26 | +[warn](warn) is an example that sets two sets of flags for a project. The first set, `default_config`, triggers by default. The second, `debug_config`, can be set with `--scl_config=debug_config`. If the user sets any other flags, bazel emits a warning that the build is non-canonical. |
| 27 | + |
| 28 | +*Default flags:* |
| 29 | +```sh |
| 30 | +$ bazel build //warn:all |
| 31 | +INFO: Reading project settings from //warn:PROJECT.scl. |
| 32 | +INFO: Applying flags from the config 'default_config' defined in //warn:PROJECT.scl: [--platforms=//:myplatform, |
| 33 | + --compilation_mode=opt, --@custom_flags//:project_flag="custom flag value"] |
| 34 | +INFO: Found 2 targets... |
| 35 | +INFO: Build completed successfully, 3 total actions |
| 36 | +``` |
| 37 | + |
| 38 | +*Non-default supported flags:* |
| 39 | +```sh |
| 40 | +$ bazel build //warn:all --scl_config=debug_config |
| 41 | +INFO: Reading project settings from //warn:PROJECT.scl. |
| 42 | +INFO: Applying flags from the config 'debug_config' defined in //warn:PROJECT.scl: [--platforms=//:myplatform, |
| 43 | + --compilation_mode=dbg, --@custom_flags//:project_flag="debug value"] |
| 44 | +INFO: Found 2 targets... |
| 45 | +INFO: Build completed successfully, 3 total actions |
| 46 | +``` |
| 47 | + |
| 48 | +*Unexpected flags:* |
| 49 | +```sh |
| 50 | +$ bazel build //warn:all --copt=abc |
| 51 | +INFO: Reading project settings from //warn:PROJECT.scl. |
| 52 | +WARNING: This build uses a project file (//warn:PROJECT.scl), but also sets output-affecting flags in the command |
| 53 | + line or user bazelrc: ['--copt=abc']. Please consider removing these flags. |
| 54 | +INFO: Applying flags from the config 'default_config' defined in //warn:PROJECT.scl: [--platforms=//:myplatform, |
| 55 | + --compilation_mode=opt, --@custom_flags//:project_flag="custom flag value" |
| 56 | +INFO: Found 2 targets... |
| 57 | +INFO: Build completed successfully, 3 total actions |
| 58 | +``` |
| 59 | +
|
| 60 | +### Project-wide settings with incompatible flag checks |
| 61 | +[compatible](compatible) is an example that sets two sets of flags for a project. It lets the user set other, unrelated flags with a warning but fails the build if the user sets contradictory flags. |
| 62 | +
|
| 63 | +*Default flags:* |
| 64 | +```sh |
| 65 | +$ bazel build //compatible:all |
| 66 | +INFO: Reading project settings from //compatible:PROJECT.scl. |
| 67 | +INFO: Applying flags from the config 'default_config' defined in //compatible:PROJECT.scl: |
| 68 | + [--platforms=//:myplatform, --compilation_mode=opt, --@custom_flags//:project_flag="custom flag value"] |
| 69 | +INFO: Found 2 targets... |
| 70 | +INFO: Build completed successfully, 3 total actions |
| 71 | +``` |
| 72 | +
|
| 73 | +*Unexpected non-conflicting flag:* |
| 74 | +```sh |
| 75 | +$ bazel build //compatible:all --copt=abc |
| 76 | +INFO: Reading project settings from //compatible:PROJECT.scl. |
| 77 | +WARNING: This build uses a project file (//compatible:PROJECT.scl), but also sets output-affecting flags in |
| 78 | + the command line or user bazelrc: ['--copt=abc']. Please consider removing these flags. |
| 79 | +INFO: Applying flags from the config 'default_config' defined in //compatible:PROJECT.scl: |
| 80 | + [--platforms=//:myplatform, --compilation_mode=opt, --@custom_flags//:project_flag="custom flag value"] |
| 81 | +INFO: Build completed successfully, 3 total actions |
| 82 | +``` |
| 83 | +
|
| 84 | +*Unexpected conflicting flag:* |
| 85 | +```sh |
| 86 | +$ bazel build //compatible:all --compilation_mode=fastbuild |
| 87 | +INFO: Reading project settings from //compatible:PROJECT.scl. |
| 88 | +ERROR: Cannot parse options: This build uses a project file (//compatible:PROJECT.scl) that does not allow |
| 89 | + conflicting flags in the command line or user bazelrc. Found ['--compilation_mode=fastbuild']. Please remove |
| 90 | + these flags or disable project file resolution via --noenforce_project_configs. |
| 91 | +ERROR: Build did NOT complete successfully |
| 92 | +``` |
| 93 | +
|
| 94 | +### Project-wide settings with strict checks |
| 95 | +[strict](strict) is an example that sets two sets of flags for a project. It fails the build if the user sets any flags to any values different than the project settings. This is the strictest form of flag checking. It ensures all builds use pre-approved, canonical flags. |
| 96 | +
|
| 97 | +*Default flags:* |
| 98 | +```sh |
| 99 | +$ bazel build //strict:all |
| 100 | +INFO: Reading project settings from //strict:PROJECT.scl. |
| 101 | +INFO: Applying flags from the config 'default_config' defined in //strict:PROJECT.scl: [--platforms=//:myplatform, |
| 102 | + --compilation_mode=opt, --@custom_flags//:project_flag="custom flag value"] |
| 103 | +INFO: Found 2 targets... |
| 104 | +INFO: Build completed successfully, 3 total actions |
| 105 | +``` |
| 106 | +
|
| 107 | +*Unexpected non-conflicting flag:* |
| 108 | +```sh |
| 109 | +$ bazel build //strict:all --copt=abc |
| 110 | +INFO: Reading project settings from //strict:PROJECT.scl. |
| 111 | +ERROR: Cannot parse options: This build uses a project file (//strict:PROJECT.scl) that does not allow |
| 112 | + output-affeccting flags in the command line or user bazelrc. Found ['--copt=abc']. Please remove these flags or |
| 113 | + disable project file resolution via --noenforce_project_configs. |
| 114 | +ERROR: Build did NOT complete successfully |
| 115 | +``` |
| 116 | +
|
| 117 | +### Per-target flag settings |
| 118 | +[target_specific](target_specific) sets different default flags for different targets. This example applies the [warn](warn) enforcement policy. |
| 119 | +
|
| 120 | +*`//target_specific:one`:* |
| 121 | +```sh |
| 122 | +$ bazel build //target_specific:one |
| 123 | +INFO: Reading project settings from //target_specific:PROJECT.scl. |
| 124 | +INFO: Applying flags from the config 'default_config_for_target_one' defined in //target_specific:PROJECT.scl: |
| 125 | + [--platforms=//:myplatform, --@custom_flags//:project_flag="settings for target one"] |
| 126 | +INFO: Found 1 target... |
| 127 | +INFO: Build completed successfully, 1 total action |
| 128 | +``` |
| 129 | +
|
| 130 | +*`//target_specific:two`:* |
| 131 | +```sh |
| 132 | +$ bazel build //target_specific:two |
| 133 | +INFO: Reading project settings from //target_specific:PROJECT.scl. |
| 134 | +INFO: Applying flags from the config 'default_config_for_target_two' defined in //target_specific:PROJECT.scl: |
| 135 | + [--platforms=//:myplatform, --@custom_flags//:project_flag="settings for target two"] |
| 136 | +INFO: Found 1 target... |
| 137 | +INFO: Build completed successfully, 1 total action |
| 138 | +``` |
| 139 | +
|
| 140 | +**Note:** `$ bazel build //target_specific:all` fails because no common set of flags applies to both targets. You can resolve this either by explicitly setting `--scl_config` or disabling project flags with `--noenforce_project_configs`. Comment on https://github.com/bazelbuild/bazel/issues/24839 if you're interested in more automatic behavior. |
| 141 | +
|
| 142 | +### Aliases |
| 143 | +[alias](alias) is a project with different disjoint directories. You can refer them all to the same souce of flag truth with `PROJECT.scl` aliases. |
| 144 | +
|
| 145 | +*Main project definition in `alias/project_main`:* |
| 146 | +```sh |
| 147 | +$ bazel build //alias/project_main:main |
| 148 | +INFO: Reading project settings from //alias/project_main:PROJECT.scl. |
| 149 | +INFO: Applying flags from the config 'default_config' defined in //alias/project_main:PROJECT.scl: |
| 150 | + [--platforms=//:myplatform, --compilation_mode=opt, --@custom_flags//:project_flag="custom flag value"] |
| 151 | +INFO: Found 1 target... |
| 152 | +INFO: Build completed successfully, 1 total action |
| 153 | +``` |
| 154 | +
|
| 155 | +*`alias/project_lib` is a different directory but part of the same project:* |
| 156 | + ```sh |
| 157 | +$ cat alias/project_lib/PROJECT.scl |
| 158 | +project = { |
| 159 | + "actual": "//alias/project_main:PROJECT.scl", |
| 160 | +} |
| 161 | +``` |
| 162 | +
|
| 163 | +```sh |
| 164 | +$ bazel build //alias/project_lib:lib |
| 165 | +INFO: Reading project settings from //alias/project_main:PROJECT.scl. |
| 166 | +INFO: Applying flags from the config 'default_config' defined in //alias/project_main:PROJECT.scl: |
| 167 | + [--platforms=//:myplatform, --compilation_mode=opt, --@custom_flags//:project_flag="custom flag value"] |
| 168 | +INFO: Found 1 target... |
| 169 | +INFO: Build completed successfully, 1 total action |
| 170 | +``` |
| 171 | +
|
| 172 | +**Note:** In this example both directories have the same parent directory. You can alternatively move the project definition to `alias/PROJECT.scl` for the same effect. This also requires an `alias/BUILD` file, which may be empty. |
| 173 | +
|
| 174 | +### Questions? |
| 175 | +This is an evolving feature. These examples don't cover everything. |
| 176 | +
|
| 177 | +Comment at https://github.com/bazelbuild/bazel/issues/24839 with more questions and requests. |
| 178 | +
|
0 commit comments