Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Platform mappings: support setting Starlark flags #18288

Closed
wants to merge 2 commits into from

Conversation

gregestren
Copy link
Contributor

In other words, support:

platforms:
  //:my_platform
    --//mypkg:my_custom_flag=value

Non-goals:

  • Refactor the relationship between the Starlark and native option parsers
  • Support Starlark flag -> platform mappings (we could add this if needed but platform mappings isn't a feature we want to expand more than necessary)
  • Parse with simplified ad hoc logic instead of directly using StarlarkOptionsParser as the source of truth

Approach:

  1. The basic problem (described here) is StarlarkOptionsParser needs to convert flag names to Targets. PlatformMappingValue calls the parsers but can't Skyframe-load Targets.
  2. So we add support in PlatformMappingFunction to Skyframe-load the needed Targets
  3. But StarlarkOptionParser already has code for doing that, outside of a Skyfunction environment, through SkyframeExecutor.loadTargetPatternsWithoutFilters.
  4. So factor out StarlarkOptionParsers Target loading into an interface the caller can implement
  5. The original callers (BlazeOptionHandler and CanonicalizeCommand) provide the same implementation as before
  6. PlatformMappingFunction provides a Skyframe retriever through PackageFunction (which is a cleaner way to get Targets within a Skyfunction)

I also had to factor out StarlarkOptionsParser.java into its own java_library to prevent dependency cycles between :runtime and Skyframe: :runtime already depends on Skyframe, and by calling StarlarkOptionsParser from a Skyfunction that adds a dependency the other way.

Thanks @katre for initial investigation.

Fixes #18199.

PiperOrigin-RevId: 528888600
Change-Id: Ie3597f4a1d406c6918fadbdcdb208d23db6a2aa2

In other words, support:

```
platforms:
  //:my_platform
    --//mypkg:my_custom_flag=value
```

### Non-goals:
 - Refactor the relationship between the Starlark and native option parsers
 - Support Starlark flag -> platform mappings (we could add this if needed but
   platform mappings isn't a feature we want to expand more than necessary)
 - Parse with simplified ad hoc logic instead of directly using `StarlarkOptionsParser` as the source of truth

### Approach:
1. The basic problem (described [here](bazelbuild#18199 (comment))) is
 `StarlarkOptionsParser` needs to convert flag names to `Target`s, `PlatformMappingValue` parses the flags but can't Skyframe-load `Target`s.
1. So we add support in `PlatformMappingFunction` to Skyframe-load the needed `Target`s
1. But `StarlarkOptionParser` already has code for doing that, outside of a `Skyfunction` environment, through `skyframeExecutor.loadTargetPatternsWithoutFilters`.
1. So factor out `StarlarkOptionParser`s `Target` loading into an interface the the caller can implement
1. The original callers (`BlazeOptionHandler` and `CanonicalizeCommand`) provide the same implementation as before
1. `PlatformMappingFunction provides a Skyframe retriever through `PackageFunction` (which is a cleaner way to get `Target`s within a `Skyfunction`)

I also had to factor out `StarlarkOptionsParser` into its own `java_library` to prevent dependency cycles between `:runtime` and Skyframe: `:runtime` already
depends on Skyframe, and by calling `StarlarkOptionsParser` from a Skyfunction that adds a dependency the other way.

Thanks @katre for initial investigation.

Fixes bazelbuild#18199.

PiperOrigin-RevId: 528888600
Change-Id: Ie3597f4a1d406c6918fadbdcdb208d23db6a2aa2
@gregestren gregestren requested a review from katre May 3, 2023 01:07
@gregestren gregestren added the team-Configurability platforms, toolchains, cquery, select(), config transitions label May 3, 2023
@github-actions github-actions bot added awaiting-review PR is awaiting review from an assigned reviewer and removed team-Configurability platforms, toolchains, cquery, select(), config transitions labels May 3, 2023
@gregestren
Copy link
Contributor Author

@gregestren gregestren added the team-Configurability platforms, toolchains, cquery, select(), config transitions label May 3, 2023
@gregestren
Copy link
Contributor Author

I only included a basic test in this first commit. Happy to add more (e.g. bad label checking).

* <p>Hence this class. By dropping those events, we restrict all info and error reporting logic
* to the options parsing pipeline.
*/
private static class NonPostingEventHandler implements ExtendedEventHandler {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note this is just ported out of StarlarkOptionsParser.

@Override
public Target loadBuildSetting(String targetLabel)
throws InterruptedException, TargetParsingException {
TargetPatternPhaseValue result =
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation code is ported out of StarlarkOptionsParser.

@jin
Copy link
Member

jin commented May 3, 2023

Thanks @gregestren! Do you mind adding a more comprehensive test that changes the platform in a transition, and verifies that the associated build flag with the platform also changes value?

Copy link
Member

@katre katre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall LGTM.

I would have preferred this split into a few PRs:

  1. Move StarlarkOptionsParser to a new target and introduce the BuildSettingsLoader interface (and existing usage).
  2. This would have introduced no new behavior, making testing simpler.
  3. Add new usage of StarlarkOptions in platform mapping.
  4. New behavior, so new tests.

But this is written so it's fine as-is.

*
* <p>This is used for top-level flag parsing, outside any {@link SkyFunction}.
*/
public static class SkyframeExecutorTargetLoader
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need a new inner class? Can the BlazeOptionHandler implement BuildSettingLoader directly, or just define loadBuildSetting in BlazeOptionHandler and pass in a method reference?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CanonicalizeCommand also references this, which is why I made it its own entity:

@gregestren
Copy link
Contributor Author

gregestren commented May 3, 2023

Overall LGTM.

I would have preferred this split into a few PRs:

I was thinking something similar but wanted to at least start with the full picture to show how it all fits together.

This was on the verge of being complicated enough to merit a design doc. But IMO not quite that complicated (since it's not user-facing aside from one very specific difference) and we really don't want to publicize platform mapping upgrades any more than necessary.

@gregestren
Copy link
Contributor Author

Thanks @gregestren! Do you mind adding a more comprehensive test that changes the platform in a transition, and verifies that the associated build flag with the platform also changes value?

On it...

Also, I'm not sure how this handles labels outside the main repo. I did my best to use canonical label references but all that logic is so subtle and you never know.

This is complicated enough where I'd like to not worry about that for this PR. If you think you'd need that let me know and let's explore as a followup patch (or even better if no patch is needed at all).

@gregestren
Copy link
Contributor Author

@brentleyjones out of curiosity, what's your interest in this change?

@brentleyjones
Copy link
Contributor

Not out if need (that I know of).

I'm just a fan of Starlark build settings/flags, so I like changes like this that make them work in more places.

PiperOrigin-RevId: 528888600
Change-Id: Ie3597f4a1d406c6918fadbdcdb208d23db6a2aa2
@gregestren
Copy link
Contributor Author

Thanks @gregestren! Do you mind adding a more comprehensive test that changes the platform in a transition, and verifies that the associated build flag with the platform also changes value?

Added tests.

@gregestren gregestren added awaiting-PR-merge PR has been approved by a reviewer and is ready to be merge internally and removed awaiting-review PR is awaiting review from an assigned reviewer labels May 4, 2023
Copy link
Member

@jin jin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the test case! @Colecf FYI

I'll leave the review of the impl details to John.

@katre
Copy link
Member

katre commented May 4, 2023

LGTM for me.

@copybara-service copybara-service bot closed this in 8a7f5e2 May 4, 2023
@sgowroji sgowroji removed the awaiting-PR-merge PR has been approved by a reviewer and is ready to be merge internally label May 5, 2023
@Colecf
Copy link

Colecf commented May 5, 2023

Thanks Greg! I'll try and pull this into android and test it out.

fweikert pushed a commit to fweikert/bazel that referenced this pull request May 25, 2023
In other words, support:

```
platforms:
  //:my_platform
    --//mypkg:my_custom_flag=value
```

#### Non-goals:
 - Refactor the relationship between the Starlark and native option parsers
 - Support Starlark flag -> platform mappings (we could add this if needed but platform mappings isn't a feature we want to expand more than necessary)
 - Parse with simplified ad hoc logic instead of directly using `StarlarkOptionsParser` as the source of truth

#### Approach:
1. The basic problem (described [here](bazelbuild#18199 (comment))) is `StarlarkOptionsParser` needs to convert flag names to `Target`s. `PlatformMappingValue` calls the parsers but can't Skyframe-load `Target`s.
1. So we add support in `PlatformMappingFunction` to Skyframe-load the needed `Target`s
1. But `StarlarkOptionParser` already has code for doing that, outside of a `Skyfunction` environment, through `SkyframeExecutor.loadTargetPatternsWithoutFilters`.
1. So factor out `StarlarkOptionParser`s `Target` loading into an interface the caller can implement
1. The original callers (`BlazeOptionHandler` and `CanonicalizeCommand`) provide the same implementation as before
1. `PlatformMappingFunction` provides a Skyframe retriever through `PackageFunction` (which is a cleaner way to get `Target`s within a `Skyfunction`)

I also had to factor out `StarlarkOptionsParser.java` into its own `java_library` to prevent dependency cycles between `:runtime` and Skyframe: `:runtime` already depends on Skyframe, and by calling `StarlarkOptionsParser` from a Skyfunction that adds a dependency the other way.

Thanks @katre for initial investigation.

Fixes bazelbuild#18199.

PiperOrigin-RevId: 528888600
Change-Id: Ie3597f4a1d406c6918fadbdcdb208d23db6a2aa2

Closes bazelbuild#18288.

Change-Id: Ie3597f4a1d406c6918fadbdcdb208d23db6a2aa2
PiperOrigin-RevId: 529479790
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
team-Configurability platforms, toolchains, cquery, select(), config transitions
Projects
None yet
Development

Successfully merging this pull request may close these issues.

platform_mappings files cannot set build flags
6 participants