0.3.8 select() Awareness

extra

select() is the first bit of BUILD-file syntax that looks like real conditional logic. It gives one attribute configuration-dependent values, and Bazel chooses one later. It is not a top-level if statement, and it does not turn the BUILD file into a script.1,2

cc_binary(
    name = "mybinary",
    deps = select({
        ":arm_build": [":arm_lib"],
        "//conditions:default": [":generic_lib"],
    }),
)

config_setting(
    name = "arm_build",
    values = {"cpu": "arm"},
)

When you see syntax like this, read the whole attribute as "Bazel will substitute one branch here for the active configuration." The keys are labels naming config_setting or constraint_value targets, and //conditions:default is the fallback when nothing else matches.2,3

Why This Still Fits A Declarative BUILD File

BUILD files still forbid top-level if and for statements, even though they allow limited expressions such as list comprehensions and if expressions.1 select() fits that design because it lives inside an attribute value. It describes alternatives in the graph instead of executing a branch while the file is being loaded.1,2

The attribute roles from 0.3.3 Attributes & Semantic Roles do not change. deps, srcs, or cmd still mean the same thing they meant before. select() only says that the value of that attribute varies by configuration.2 A line like deps = select({...}) declares that the target's dependencies depend on the active build configuration.

What You Need To Recognize For Now

You do not need the full configuration system yet. When reading select():

  • spot which attribute is wrapped in select()
  • scan the named conditions
  • look for //conditions:default
  • treat the chosen branch as "resolved later"

The deeper questions come later: which flags make a config_setting match, how platforms relate to constraint_value, why macros can pass select() through but cannot inspect the chosen branch themselves, and which query tools can show the resolved result.2 Those topics belong when configuration becomes explicit in 3.2 Project Configuration and, more specifically, when configurable attributes return in 3.3.1 Configurable Attributes (select()).

key takeaway

For Level 0, select() is mostly a recognition pattern. When you meet it in a BUILD file, read it as "this attribute has configuration-dependent values." Do not try to mentally execute the branches like ordinary program flow. Identify the attribute, note the fallback, and keep reading.

Check your understanding · 2 questions

1.What does deps = select({":arm_build": [":arm_lib"], "//conditions:default": [":generic_lib"]}) mean in a BUILD file?

Select one answer

2.True or false: select() in BUILD files.

Choose True or False for each sentence

select() is a top-level statement in BUILD files, equivalent to an if/else block.
//conditions:default is the fallback branch chosen when no other condition matches the current configuration.
select() can appear inside an attribute value like deps or srcs, but not as a standalone statement.
A macro can inspect which branch of a select() will be chosen and act on it during loading.
0 of 2 answered

Footnotes

  1. BUILD files — BUILD-file restrictions, sequential declaration model, and the distinction between allowed expressions and forbidden top-level control flow 1 2 3

  2. Configurable Build Attributesselect() as a configurable attribute placeholder, config_setting conditions, //conditions:default, and the loading-versus-analysis split behind later resolution 1 2 3 4 5

  3. BUILD globals referenceselect() parameter contract: condition keys are config_setting or constraint_value labels, with optional no_match_error