question mark in target names?

70 views
Skip to first unread message

Gregg Reynolds

unread,
Sep 1, 2022, 12:31:32 PM9/1/22
to bazel-discuss
I like the ergonomics of using '?' to mark config_settings and constraint_values as predicates:

In foo/BUILD.bazel:

```
platform(name = "vm",
         parents = ["@local_config_platform//:host"],
         constraint_values = [":vm?"])
constraint_setting(name = "target")
constraint_value(name = "vm?", constraint_setting = ":target")
```

Then we can have `target_host_constraints = ["//foo:vm?"]` in a rule, and pass `--//foo:vm` on the command line.

More general, for command-line settings, e.g.

In compilation_mode/BUILD.bazel:

config_setting(name = "dbg?",
               values = {"compilation_mode": "dbg"})

and then in rules

select({ "//compilation_mode:dbg?": ["-foo"] ...})

But it makes me nervous. It feels like one of those things that seems great at first but later turns out to have pestiferous corner cases. Is it a bad idea?  Anybody have experience using such names?

Thanks,

Gregg


David Turner

unread,
Sep 1, 2022, 1:59:36 PM9/1/22
to Gregg Reynolds, bazel-discuss
(NOTE: I am not on the Bazel team and do not speak for them!)

Interesting! To be honest, the question mark (?) looks like a special operator that is not part of the name, and I find this confusing. And there are already so many confusing things in Bazel :-)

For example, config_setting() does not "set" anything at all, but defines an item that can be referenced in select() calls. This should have been called config_condition() instead!.

I like to use `is_` or `has_` prefixes for these, as this makes my Bazel files clearer (e.g. "is_debug", "has_foo_feature").

I think that solves the issue you want to address in the second part of your proposal without introducing changes to Bazel.

Regarding constraint_setting(), their value cannot be selected with `--<label>=<value>` on the command line. The only thing that impacts them is the platform name. On the command line, this is done with `--platforms=<label>`. And during analysis, constraint values can only be changed by using transitions that change the value of "//command_line_option:platforms". Note that despite the use of a plural (i.e. --platforms), this option only takes a single label value, so this is not something you would use to set the value of a single build flag, independent from the others.

It looks like a build_setting() would be a better choice for your example:

```
# From foo/BUILD.bazel

# A user-settable build configuration boolean flag. Use `--//foo:vm=True` on the command-line to set it.
load("@bazel_skylib//lib:common_settings.bzl", "bool_flag")
bool_flag("vm")

# A condition to be referenced in select() statements that will hold true when //foo:vm is set.
config_setting(
    name = "is_vm",
    flag_values = {
        ":vm": True,
    },
)

# From compilation_mode/BUILD.bazel
config_setting(
    name = "is_dbg",
    values = {
        "compilation_mode": "dbg",
    },
)
```

Oh, and constraint_setting() should really be named constraint_dimension(), and build_setting() should really be called build_variable() :-)

Hope this helps.

--
You received this message because you are subscribed to the Google Groups "bazel-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bazel-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bazel-discuss/CAO40Mi%3DCANCj9WrhPH4PTYgdtmcY5DeHOS_AZ%3DigoM3CzcLdew%40mail.gmail.com.

Alexandre Rostovtsev

unread,
Sep 1, 2022, 2:02:35 PM9/1/22
to Gregg Reynolds, bazel-discuss
'?' is prohibited in Windows paths. If some rule somewhere down the line ends up using your constraint value as part of a file or directory name, it will fail on Windows.

Gregg Reynolds

unread,
Sep 1, 2022, 4:03:08 PM9/1/22
to David Turner, bazel-discuss
Thanks for the feedback.

On Thu, Sep 1, 2022 at 12:59 PM David Turner <di...@google.com> wrote:
(NOTE: I am not on the Bazel team and do not speak for them!)

Interesting! To be honest, the question mark (?) looks like a special operator that is not part of the name, and I find this confusing. And there are already so many confusing things in Bazel :-)

Yeah, I've been writing a lot of Scheme code lately, where it's normal, but it's bound to look slightly alarming to those coming from languages with more "standard" (i.e. restrictive) syntax.
 

For example, config_setting() does not "set" anything at all, but defines an item that can be referenced in select() calls. This should have been called config_condition() instead!.

I like to use `is_` or `has_` prefixes for these, as this makes my Bazel files clearer (e.g. "is_debug", "has_foo_feature").

Yep, trying to avoid that kind of thing.  I had been using stuff like `//foo/bar` and `//foo/bar:enabled` but then the problem is you end up with related build settings and config settings in different packages. I like the simplicity of "foo" and "foo?".

I think that solves the issue you want to address in the second part of your proposal without introducing changes to Bazel.

Regarding constraint_setting(), their value cannot be selected with `--<label>=<value>` on the command line.

Right. The example I gave is a bit of a special case, where I have a platform of just one constraint_value, so I want to use the same name for both. Makes it easier for the user to write custom rules with `target_compatible_with'.
 
The only thing that impacts them is the platform name. On the command line, this is done with `--platforms=<label>`. And during analysis, constraint values can only be changed by using transitions that change the value of "//command_line_option:platforms". Note that despite the use of a plural (i.e. --platforms), this option only takes a single label value, so this is not something you would use to set the value of a single build flag, independent from the others.

It looks like a build_setting() would be a better choice for your example:

```
# From foo/BUILD.bazel

# A user-settable build configuration boolean flag. Use `--//foo:vm=True` on the command-line to set it.
load("@bazel_skylib//lib:common_settings.bzl", "bool_flag")
bool_flag("vm")

# A condition to be referenced in select() statements that will hold true when //foo:vm is set.
config_setting(
    name = "is_vm",
    flag_values = {
        ":vm": True,
    },
)

I could use a build/config setting in a "target_settings" toolchain attribute, but that's a separate design issue.  I think I prefer "vm?" to "is_vm" but that's obviously a matter of taste. 

# From compilation_mode/BUILD.bazel
config_setting(
    name = "is_dbg",
    values = {
        "compilation_mode": "dbg",
    },
)
```

Oh, and constraint_setting() should really be named constraint_dimension(), and build_setting() should really be called build_variable() :-)

Don't get me started on the terminology here.  It's worse than bad. A huge impediment to learning and using IMO.  In some cases I'm using wrapper macros with sensible names to protect the innocent.

Hope this helps.

Thanks.

Gregg Reynolds

unread,
Sep 1, 2022, 4:04:19 PM9/1/22
to Alexandre Rostovtsev, bazel-discuss
On Thu, Sep 1, 2022 at 1:02 PM Alexandre Rostovtsev <arost...@google.com> wrote:
'?' is prohibited in Windows paths. If some rule somewhere down the line ends up using your constraint value as part of a file or directory name, it will fail on Windows.

Ah yes, I knew there had to be something.  Thanks.
Reply all
Reply to author
Forward
0 new messages