aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java125
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionValue.java75
-rw-r--r--src/test/java/com/google/devtools/build/lib/rules/platform/ToolchainTestCase.java17
-rw-r--r--src/test/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunctionTest.java85
6 files changed, 302 insertions, 3 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
index 76193e976f..e0762b33bb 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java
@@ -109,6 +109,8 @@ public final class SkyFunctions {
SkyFunctionName.create("LOCAL_REPOSITORY_LOOKUP");
public static final SkyFunctionName REGISTERED_TOOLCHAINS =
SkyFunctionName.create("REGISTERED_TOOLCHAINS");
+ public static final SkyFunctionName TOOLCHAIN_RESOLUTION =
+ SkyFunctionName.create("TOOLCHAIN_RESOLUTION");
public static Predicate<SkyKey> isSkyFunction(final SkyFunctionName functionName) {
return new Predicate<SkyKey>() {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 1dfe85f30c..463e3f3d5f 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -456,6 +456,7 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory {
new ActionTemplateExpansionFunction(removeActionsAfterEvaluation));
map.put(SkyFunctions.LOCAL_REPOSITORY_LOOKUP, new LocalRepositoryLookupFunction());
map.put(SkyFunctions.REGISTERED_TOOLCHAINS, new RegisteredToolchainsFunction());
+ map.put(SkyFunctions.TOOLCHAIN_RESOLUTION, new ToolchainResolutionFunction());
map.putAll(extraSkyFunctions);
return map.build();
}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java
new file mode 100644
index 0000000000..7a61c67271
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunction.java
@@ -0,0 +1,125 @@
+// Copyright 2017 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;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.platform.DeclaredToolchainInfo;
+import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.packages.NoSuchThingException;
+import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ConfiguredValueCreationException;
+import com.google.devtools.build.lib.skyframe.RegisteredToolchainsFunction.InvalidTargetException;
+import com.google.devtools.build.lib.skyframe.ToolchainResolutionValue.ToolchainResolutionKey;
+import com.google.devtools.build.lib.syntax.EvalException;
+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 javax.annotation.Nullable;
+
+/** {@link SkyFunction} which performs toolchain resolution for a class of rules. */
+public class ToolchainResolutionFunction implements SkyFunction {
+
+ @Nullable
+ @Override
+ public SkyValue compute(SkyKey skyKey, Environment env)
+ throws SkyFunctionException, InterruptedException {
+ ToolchainResolutionKey key = (ToolchainResolutionKey) skyKey.argument();
+
+ // Get all toolchains.
+ RegisteredToolchainsValue toolchains;
+ try {
+ toolchains =
+ (RegisteredToolchainsValue)
+ env.getValueOrThrow(
+ RegisteredToolchainsValue.key(key.configuration()),
+ ConfiguredValueCreationException.class,
+ InvalidTargetException.class,
+ EvalException.class);
+ if (toolchains == null) {
+ return null;
+ }
+ } catch (ConfiguredValueCreationException e) {
+ throw new ToolchainResolutionFunctionException(e);
+ } catch (InvalidTargetException e) {
+ throw new ToolchainResolutionFunctionException(e);
+ } catch (EvalException e) {
+ throw new ToolchainResolutionFunctionException(e);
+ }
+
+ // Find the right one.
+ DeclaredToolchainInfo toolchain =
+ resolveConstraints(
+ key.toolchainType(),
+ key.targetPlatform(),
+ key.execPlatform(),
+ toolchains.registeredToolchains());
+ return ToolchainResolutionValue.create(toolchain.toolchainLabel());
+ }
+
+ // TODO(katre): Implement real resolution.
+ private DeclaredToolchainInfo resolveConstraints(
+ Label toolchainType,
+ PlatformInfo targetPlatform,
+ PlatformInfo execPlatform,
+ ImmutableList<DeclaredToolchainInfo> toolchains)
+ throws ToolchainResolutionFunctionException {
+ for (DeclaredToolchainInfo toolchain : toolchains) {
+ if (toolchain.toolchainType().equals(toolchainType)) {
+ return toolchain;
+ }
+ }
+ throw new ToolchainResolutionFunctionException(new NoToolchainFoundException(toolchainType));
+ }
+
+ @Nullable
+ @Override
+ public String extractTag(SkyKey skyKey) {
+ return null;
+ }
+
+ /** Used to indicate that a toolchain was not found for the current request. */
+ public static final class NoToolchainFoundException extends NoSuchThingException {
+ private final Label missingToolchainType;
+
+ public NoToolchainFoundException(Label missingToolchainType) {
+ super(String.format("no matching toolchain found for %s", missingToolchainType));
+ this.missingToolchainType = missingToolchainType;
+ }
+
+ public Label missingToolchainType() {
+ return missingToolchainType;
+ }
+ }
+
+ /** Used to indicate errors during the computation of an {@link ToolchainResolutionValue}. */
+ private static final class ToolchainResolutionFunctionException extends SkyFunctionException {
+ public ToolchainResolutionFunctionException(NoToolchainFoundException e) {
+ super(e, Transience.PERSISTENT);
+ }
+
+ public ToolchainResolutionFunctionException(ConfiguredValueCreationException e) {
+ super(e, Transience.PERSISTENT);
+ }
+
+ public ToolchainResolutionFunctionException(InvalidTargetException e) {
+ super(e, Transience.PERSISTENT);
+ }
+
+ public ToolchainResolutionFunctionException(EvalException e) {
+ super(e, Transience.PERSISTENT);
+ }
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionValue.java
new file mode 100644
index 0000000000..1f553e6350
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionValue.java
@@ -0,0 +1,75 @@
+// Copyright 2017 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;
+
+import com.google.auto.value.AutoValue;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.skyframe.SkyFunctionName;
+import com.google.devtools.build.skyframe.SkyKey;
+import com.google.devtools.build.skyframe.SkyValue;
+
+/** A value which represents the selected toolchain for a specific target and execution platform. */
+@AutoValue
+public abstract class ToolchainResolutionValue implements SkyValue {
+
+ // A key representing the input data.
+ public static SkyKey key(
+ BuildConfiguration configuration,
+ Label toolchainType,
+ PlatformInfo targetPlatform,
+ PlatformInfo execPlatform) {
+ return ToolchainResolutionKey.create(
+ configuration, toolchainType, targetPlatform, execPlatform);
+ }
+
+ /** {@link SkyKey} implementation used for {@link ToolchainResolutionFunction}. */
+ @AutoValue
+ public abstract static class ToolchainResolutionKey implements SkyKey {
+ @Override
+ public SkyFunctionName functionName() {
+ return SkyFunctions.TOOLCHAIN_RESOLUTION;
+ }
+
+ @Override
+ public ToolchainResolutionKey argument() {
+ return this;
+ }
+
+ public abstract BuildConfiguration configuration();
+
+ public abstract Label toolchainType();
+
+ public abstract PlatformInfo targetPlatform();
+
+ public abstract PlatformInfo execPlatform();
+
+ public static ToolchainResolutionKey create(
+ BuildConfiguration configuration,
+ Label toolchainType,
+ PlatformInfo targetPlatform,
+ PlatformInfo execPlatform) {
+ return new AutoValue_ToolchainResolutionValue_ToolchainResolutionKey(
+ configuration, toolchainType, targetPlatform, execPlatform);
+ }
+ }
+
+ public static ToolchainResolutionValue create(Label toolchainLabel) {
+ return new AutoValue_ToolchainResolutionValue(toolchainLabel);
+ }
+
+ public abstract Label toolchainLabel();
+}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/platform/ToolchainTestCase.java b/src/test/java/com/google/devtools/build/lib/rules/platform/ToolchainTestCase.java
index 87bce409db..5d170baac0 100644
--- a/src/test/java/com/google/devtools/build/lib/rules/platform/ToolchainTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/rules/platform/ToolchainTestCase.java
@@ -16,6 +16,7 @@ package com.google.devtools.build.lib.rules.platform;
import com.google.devtools.build.lib.analysis.platform.ConstraintSettingInfo;
import com.google.devtools.build.lib.analysis.platform.ConstraintValueInfo;
+import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.skylark.util.SkylarkTestCase;
import org.junit.Before;
@@ -23,11 +24,15 @@ import org.junit.Before;
/** Utility methods for setting up platform and toolchain related tests. */
public abstract class ToolchainTestCase extends SkylarkTestCase {
- public Label testToolchainType;
+ public PlatformInfo targetPlatform;
+ public PlatformInfo hostPlatform;
+
public ConstraintSettingInfo setting;
public ConstraintValueInfo linuxConstraint;
public ConstraintValueInfo macConstraint;
+ public Label testToolchainType;
+
@Before
public void createConstraints() throws Exception {
scratch.file(
@@ -44,9 +49,15 @@ public abstract class ToolchainTestCase extends SkylarkTestCase {
}
@Before
+ public void createPlatforms() throws Exception {
+ targetPlatform =
+ PlatformInfo.builder().setLabel(makeLabel("//platforms:target_platform")).build();
+ hostPlatform = PlatformInfo.builder().setLabel(makeLabel("//platforms:host_platform")).build();
+ }
+
+ @Before
public void createToolchains() throws Exception {
- rewriteWorkspace(
- "register_toolchains(", " '//toolchain:toolchain_1',", " '//toolchain:toolchain_2')");
+ rewriteWorkspace("register_toolchains('//toolchain:toolchain_1', '//toolchain:toolchain_2')");
scratch.file(
"toolchain/BUILD",
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunctionTest.java
new file mode 100644
index 0000000000..88bc501d12
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ToolchainResolutionFunctionTest.java
@@ -0,0 +1,85 @@
+// Copyright 2017 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;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.devtools.build.skyframe.EvaluationResultSubjectFactory.assertThatEvaluationResult;
+
+import com.google.common.testing.EqualsTester;
+import com.google.devtools.build.lib.rules.platform.ToolchainTestCase;
+import com.google.devtools.build.lib.skyframe.util.SkyframeExecutorTestUtils;
+import com.google.devtools.build.skyframe.EvaluationResult;
+import com.google.devtools.build.skyframe.SkyKey;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/** Tests for {@link ToolchainResolutionValue} and {@link ToolchainResolutionFunction}. */
+@RunWith(JUnit4.class)
+public class ToolchainResolutionFunctionTest extends ToolchainTestCase {
+
+ private EvaluationResult<ToolchainResolutionValue> invokeToolchainResolution(SkyKey key)
+ throws InterruptedException {
+ try {
+ getSkyframeExecutor().getSkyframeBuildView().enableAnalysis(true);
+ return SkyframeExecutorTestUtils.evaluate(
+ getSkyframeExecutor(), key, /*keepGoing=*/ false, reporter);
+ } finally {
+ getSkyframeExecutor().getSkyframeBuildView().enableAnalysis(false);
+ }
+ }
+
+ // TODO(katre): Current toolchain resolution does not actually check the constraints, it just
+ // returns the first toolchain available.
+ @Test
+ public void testResolution() throws Exception {
+ SkyKey key =
+ ToolchainResolutionValue.key(targetConfig, testToolchainType, targetPlatform, hostPlatform);
+ EvaluationResult<ToolchainResolutionValue> result = invokeToolchainResolution(key);
+
+ assertThatEvaluationResult(result).hasNoError();
+
+ ToolchainResolutionValue toolchainResolutionValue = result.get(key);
+ assertThat(toolchainResolutionValue.toolchainLabel())
+ .isEqualTo(makeLabel("//toolchain:test_toolchain_1"));
+ }
+
+ @Test
+ public void testResolution_noneFound() throws Exception {
+ // Clear the toolchains.
+ rewriteWorkspace();
+
+ SkyKey key =
+ ToolchainResolutionValue.key(targetConfig, testToolchainType, targetPlatform, hostPlatform);
+ EvaluationResult<ToolchainResolutionValue> result = invokeToolchainResolution(key);
+
+ assertThatEvaluationResult(result)
+ .hasErrorEntryForKeyThat(key)
+ .hasExceptionThat()
+ .hasMessageThat()
+ .contains("no matching toolchain found for //toolchain:test_toolchain");
+ }
+
+ @Test
+ public void testToolchainResolutionValue_equalsAndHashCode() {
+ new EqualsTester()
+ .addEqualityGroup(
+ ToolchainResolutionValue.create(makeLabel("//test:toolchain_impl_1")),
+ ToolchainResolutionValue.create(makeLabel("//test:toolchain_impl_1")))
+ .addEqualityGroup(
+ ToolchainResolutionValue.create(makeLabel("//test:toolchain_impl_2")),
+ ToolchainResolutionValue.create(makeLabel("//test:toolchain_impl_2")));
+ }
+}