-
Notifications
You must be signed in to change notification settings - Fork 4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new skyfunction to create build configuration keys.
This essentially exposes BuildConfigurationKeyProducer as a SkyFunction. Work towards platform-based flags: #19409. PiperOrigin-RevId: 599838440 Change-Id: Id6c0b00f43fe813f77dbed8c7a6fee0f989649a6
- Loading branch information
1 parent
f9f2240
commit 4ddc4a1
Showing
5 changed files
with
251 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
...ain/java/com/google/devtools/build/lib/skyframe/config/BuildConfigurationKeyFunction.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// Copyright 2024 The Bazel Authors. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
package com.google.devtools.build.lib.skyframe.config; | ||
|
||
import com.google.common.collect.ImmutableMap; | ||
import com.google.devtools.build.lib.analysis.config.BuildOptions; | ||
import com.google.devtools.build.lib.analysis.producers.BuildConfigurationKeyProducer; | ||
import com.google.devtools.build.lib.analysis.producers.BuildConfigurationKeyProducer.ResultSink; | ||
import com.google.devtools.build.skyframe.SkyFunction; | ||
import com.google.devtools.build.skyframe.SkyFunctionException; | ||
import com.google.devtools.build.skyframe.SkyKey; | ||
import com.google.devtools.build.skyframe.SkyValue; | ||
import com.google.devtools.build.skyframe.state.Driver; | ||
import com.google.devtools.build.skyframe.state.StateMachine; | ||
import com.google.devtools.common.options.OptionsParsingException; | ||
import javax.annotation.Nullable; | ||
|
||
/** Function that returns a fully updated {@link BuildConfigurationKey}. */ | ||
public class BuildConfigurationKeyFunction implements SkyFunction { | ||
/** | ||
* {@link BuildConfigurationKeyProducer} works on a {@code Map<String, BuildOptions>}, but this | ||
* skyfunction only operates on a single {@link BuildOptions}, so this static key is used to | ||
* create that map and read the resulting {@link BuildConfigurationKey}. | ||
*/ | ||
private static final String BUILD_OPTIONS_MAP_SINGLETON_KEY = "key"; | ||
|
||
@Nullable | ||
@Override | ||
public SkyValue compute(SkyKey skyKey, Environment env) | ||
throws BuildConfigurationKeyFunctionException, InterruptedException { | ||
// Delegate all work to BuildConfigurationKeyProducer. | ||
BuildConfigurationKeyValue.Key key = (BuildConfigurationKeyValue.Key) skyKey.argument(); | ||
BuildOptions buildOptions = key.buildOptions(); | ||
Sink sink = new Sink(); | ||
Driver driver = | ||
new Driver( | ||
new BuildConfigurationKeyProducer( | ||
sink, | ||
/* runAfter= */ StateMachine.DONE, | ||
ImmutableMap.of(BUILD_OPTIONS_MAP_SINGLETON_KEY, buildOptions))); | ||
|
||
boolean complete = driver.drive(env); | ||
|
||
try { | ||
// Check for exceptions before returning whether to restart. | ||
sink.checkErrors(); | ||
if (!complete) { | ||
return null; | ||
} | ||
|
||
BuildConfigurationKey buildConfigurationKey = sink.getKey(); | ||
return BuildConfigurationKeyValue.create(buildConfigurationKey); | ||
} catch (OptionsParsingException e) { | ||
throw new BuildConfigurationKeyFunctionException(e); | ||
} catch (PlatformMappingException e) { | ||
throw new BuildConfigurationKeyFunctionException(e); | ||
} | ||
} | ||
|
||
/** Sink implementation to handle results from {@link BuildConfigurationKeyProducer}. */ | ||
private static final class Sink implements ResultSink { | ||
@Nullable private ImmutableMap<String, BuildConfigurationKey> transitionedOptions; | ||
@Nullable private OptionsParsingException transitionError; | ||
@Nullable private PlatformMappingException platformMappingException; | ||
|
||
@Override | ||
public void acceptTransitionError(OptionsParsingException e) { | ||
this.transitionError = e; | ||
} | ||
|
||
@Override | ||
public void acceptPlatformMappingError(PlatformMappingException e) { | ||
this.platformMappingException = e; | ||
} | ||
|
||
@Override | ||
public void acceptTransitionedConfigurations( | ||
ImmutableMap<String, BuildConfigurationKey> transitionedOptions) { | ||
this.transitionedOptions = transitionedOptions; | ||
} | ||
|
||
void checkErrors() throws OptionsParsingException, PlatformMappingException { | ||
if (this.transitionError != null) { | ||
throw this.transitionError; | ||
} | ||
if (this.platformMappingException != null) { | ||
throw this.platformMappingException; | ||
} | ||
} | ||
|
||
BuildConfigurationKey getKey() { | ||
if (this.transitionedOptions != null) { | ||
return this.transitionedOptions.get(BUILD_OPTIONS_MAP_SINGLETON_KEY); | ||
} | ||
throw new IllegalStateException("No exceptions or result value found"); | ||
} | ||
} | ||
|
||
/** Exception type for errors while creating the {@link BuildConfigurationKeyValue}. */ | ||
public static final class BuildConfigurationKeyFunctionException extends SkyFunctionException { | ||
|
||
public BuildConfigurationKeyFunctionException(OptionsParsingException optionsParsingException) { | ||
super(optionsParsingException, Transience.PERSISTENT); | ||
} | ||
|
||
public BuildConfigurationKeyFunctionException( | ||
PlatformMappingException platformMappingException) { | ||
super(platformMappingException, Transience.PERSISTENT); | ||
} | ||
} | ||
} |
123 changes: 123 additions & 0 deletions
123
src/main/java/com/google/devtools/build/lib/skyframe/config/BuildConfigurationKeyValue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
// Copyright 2024 The Bazel Authors. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
package com.google.devtools.build.lib.skyframe.config; | ||
|
||
import com.google.common.base.MoreObjects; | ||
import com.google.devtools.build.lib.analysis.config.BuildOptions; | ||
import com.google.devtools.build.lib.concurrent.ThreadSafety; | ||
import com.google.devtools.build.lib.skyframe.SkyFunctions; | ||
import com.google.devtools.build.lib.skyframe.serialization.VisibleForSerialization; | ||
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; | ||
import com.google.devtools.build.skyframe.SkyFunctionName; | ||
import com.google.devtools.build.skyframe.SkyKey; | ||
import com.google.devtools.build.skyframe.SkyValue; | ||
import java.util.Objects; | ||
|
||
/** Stores a {@link BuildConfigurationKey} with all platform mappings applied. */ | ||
@AutoCodec | ||
public final class BuildConfigurationKeyValue implements SkyValue { | ||
|
||
/** Key for {@link BuildConfigurationKeyValue} based on the build options. */ | ||
@ThreadSafety.Immutable | ||
@AutoCodec | ||
public static final class Key implements SkyKey { | ||
private static final SkyKeyInterner<Key> interner = SkyKey.newInterner(); | ||
|
||
@AutoCodec.Instantiator | ||
@VisibleForSerialization | ||
public static Key create(BuildOptions buildOptions) { | ||
return interner.intern(new Key(buildOptions)); | ||
} | ||
|
||
private final BuildOptions buildOptions; | ||
|
||
private Key(BuildOptions buildOptions) { | ||
this.buildOptions = buildOptions; | ||
} | ||
|
||
public BuildOptions buildOptions() { | ||
return buildOptions; | ||
} | ||
|
||
@Override | ||
public SkyFunctionName functionName() { | ||
return SkyFunctions.BUILD_CONFIGURATION_KEY; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Key key = (Key) o; | ||
return Objects.equals(buildOptions, key.buildOptions); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hashCode(buildOptions); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "BuildConfigurationKeyValue.Key{buildOptions=" + buildOptions.checksum() + "}"; | ||
} | ||
|
||
@Override | ||
public SkyKeyInterner<Key> getSkyKeyInterner() { | ||
return interner; | ||
} | ||
} | ||
|
||
public static BuildConfigurationKeyValue create(BuildConfigurationKey buildConfigurationKey) { | ||
return new BuildConfigurationKeyValue(buildConfigurationKey); | ||
} | ||
|
||
private final BuildConfigurationKey buildConfigurationKey; | ||
|
||
BuildConfigurationKeyValue(BuildConfigurationKey buildConfigurationKey) { | ||
this.buildConfigurationKey = buildConfigurationKey; | ||
} | ||
|
||
public BuildConfigurationKey buildConfigurationKey() { | ||
return buildConfigurationKey; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (this == obj) { | ||
return true; | ||
} | ||
if (!(obj instanceof BuildConfigurationKeyValue)) { | ||
return false; | ||
} | ||
BuildConfigurationKeyValue that = (BuildConfigurationKeyValue) obj; | ||
return this.buildConfigurationKey.equals(that.buildConfigurationKey); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hashCode(buildConfigurationKey); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return MoreObjects.toStringHelper(this) | ||
.add("buildConfigurationKey", buildConfigurationKey) | ||
.toString(); | ||
} | ||
} |