Repository: bazelbuild/bazel
Issue: Starlark rules need to be able to opt out of toolchain resolution
Labels: type: feature request
P2

Currently, native rules can use [`RuleClass.Builder.useToolchainResolution`](https://source.bazel.build/bazel/+/a8353612b4791531ae4e2ed463cf0e5d8a4009e8:src/main/java/com/google/devtools/build/lib/packages/RuleClass.java;l=1393;bpt=1) to disable toolchain resolution. This is used for configuration-related rules like `platform`, `constraint_setting`, etc.

With the advent of Starlark-based build settings, some starlark rules are configuration-like and also need to opt out of toolchain resolution, so we need to expose this to Starlark's [`rule`](https://docs.bazel.build/versions/0.28.0/skylark/lib/globals.html#rule) function.

Proposed syntax:
```
config_like_rule = rule(
    implementation = _config_like_rule_impl,
    attrs = { ... },
    use_toolchain_resolution = False,
)
```


Issue comments:
Ccing @laurentlb and @gregestren for comment.
Does this need to be the rally call for Starlark customization? Could we get away with natively disabling toolchain resolution for all rule classes that are build settings?
In other words: if a `rule` has a `build_setting` attribute, automatically disable toolchain resolution.
I prefer to avoid magic checks like that, in favor of simple explicit definitions. There may be further classes of rules that don't need toolchains (or execution platforms), so I'd like to enable them, as well.
There's already intentional magic in distinguishing build settings, particularly the implicit surprise `build_setting_default` attribute: https://docs.bazel.build/versions/master/skylark/config.html#instantiating-build-settings.

We had lots of discussion about the place magic should have and while I leaned in the same direction you do, the broader consensus was that magic was appropriate here.

So for `build_setting` specifically I think we should stay consistent and not introduce more API overhead for them. I also see no reason to let users toggle this either way: Bazel should hard-code this decision for them.

> There may be further classes of rules that don't need toolchains (or execution platforms), so I'd like to > enable them, 

This makes sense. When would we expect to need them?
> There's already intentional magic in distinguishing build settings, particularly the implicit surprise build_setting_default attribute

Fair enough, I can set the useToolchainResolution flag in the same spot.

> When would we expect to need [rules that don't use toolchain resolution]?

One use case that has come up is custom rules that provide PlatformInfo, although so far that's been in the "it'd be interesting if we could" camp, not the "this is something we need" camp.

Closing this for now, until we have a need for this.

Pull request review comments:

Patch that resolved the issue:
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index f4119496292500..0a08231e4c6bc0 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -853,6 +853,10 @@ public RuleClass build(String name, String key) {
           attrBuilder.allowedRuleClasses(ANY_RULE);
         }
         this.add(attrBuilder);
+
+        // Build setting rules should opt out of toolchain resolution, since they form part of the
+        // configuration.
+        this.useToolchainResolution(false);
       }
 
       return new RuleClass(


Test patch: