Skip to content

Commit

Permalink
Add skyfunction to return all registered toolchain labels.
Browse files Browse the repository at this point in the history
Part of #2219.

Change-Id: I7293fd13bd8e0931f92afd051e18a9e7ce63762d
PiperOrigin-RevId: 161721445
  • Loading branch information
katre authored and laszlocsomor committed Jul 13, 2017
1 parent 6695345 commit f626144
Show file tree
Hide file tree
Showing 9 changed files with 456 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
// 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.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.platform.DeclaredToolchainInfo;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.rules.ExternalPackageUtil;
import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ConfiguredValueCreationException;
import com.google.devtools.build.skyframe.LegacySkyKey;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
import com.google.devtools.build.skyframe.SkyFunctionException.Transience;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.ValueOrException;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/**
* {@link SkyFunction} that returns all registered toolchains available for toolchain resolution.
*/
public class RegisteredToolchainsFunction implements SkyFunction {

@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env)
throws SkyFunctionException, InterruptedException {

BuildConfiguration configuration = (BuildConfiguration) skyKey.argument();

// Get the registered toolchains.
List<Label> registeredToolchainLabels = ExternalPackageUtil.getRegisteredToolchainLabels(env);
if (registeredToolchainLabels == null) {
return null;
}

// Load the configured target for each, and get the declared toolchain providers.
ImmutableList<DeclaredToolchainInfo> registeredToolchains =
configureRegisteredToolchains(env, configuration, registeredToolchainLabels);
if (env.valuesMissing()) {
return null;
}

return RegisteredToolchainsValue.create(registeredToolchains);
}

private ImmutableList<DeclaredToolchainInfo> configureRegisteredToolchains(
Environment env, BuildConfiguration configuration, List<Label> labels)
throws InterruptedException, RegisteredToolchainsFunctionException {
ImmutableList<SkyKey> keys =
labels
.stream()
.map(
label ->
LegacySkyKey.create(
SkyFunctions.CONFIGURED_TARGET,
new ConfiguredTargetKey(label, configuration)))
.collect(ImmutableList.toImmutableList());

Map<SkyKey, ValueOrException<ConfiguredValueCreationException>> values =
env.getValuesOrThrow(keys, ConfiguredValueCreationException.class);
if (env.valuesMissing()) {
return null;
}
ImmutableList.Builder<DeclaredToolchainInfo> toolchains = new ImmutableList.Builder<>();
for (SkyKey key : keys) {
ConfiguredTargetKey configuredTargetKey = (ConfiguredTargetKey) key.argument();
Label toolchainLabel = configuredTargetKey.getLabel();
try {
ConfiguredTarget target =
((ConfiguredTargetValue) values.get(key).get()).getConfiguredTarget();
DeclaredToolchainInfo toolchainInfo = target.getProvider(DeclaredToolchainInfo.class);
if (toolchainInfo == null) {
throw new RegisteredToolchainsFunctionException(
new InvalidTargetException(toolchainLabel), Transience.PERSISTENT);
}
toolchains.add(toolchainInfo);
} catch (ConfiguredValueCreationException e) {
throw new RegisteredToolchainsFunctionException(e, Transience.PERSISTENT);
}
}
return toolchains.build();
}

@Nullable
@Override
public String extractTag(SkyKey skyKey) {
return null;
}

/**
* Used to indicate that the given {@link Label} represents a {@link ConfiguredTarget} which is
* not a valid {@link DeclaredToolchainInfo} provider.
*/
public static final class InvalidTargetException extends Exception {

private final Label invalidLabel;

public InvalidTargetException(Label invalidLabel) {
super(String.format("target '%s' does not provide a toolchain", invalidLabel));
this.invalidLabel = invalidLabel;
}

public Label getInvalidLabel() {
return invalidLabel;
}
}

/**
* Used to declare all the exception types that can be wrapped in the exception thrown by {@link
* #compute}.
*/
public static class RegisteredToolchainsFunctionException extends SkyFunctionException {

public RegisteredToolchainsFunctionException(
InvalidTargetException cause, Transience transience) {
super(cause, transience);
}

public RegisteredToolchainsFunctionException(
ConfiguredValueCreationException cause, Transience persistent) {
super(cause, persistent);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// 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.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.platform.DeclaredToolchainInfo;
import com.google.devtools.build.skyframe.LegacySkyKey;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;

/**
* A value which represents every toolchain known to Bazel and available for toolchain resolution.
*/
@AutoValue
public abstract class RegisteredToolchainsValue implements SkyValue {

/** Returns the {@link SkyKey} for {@link RegisteredToolchainsValue}s. */
public static SkyKey key(BuildConfiguration configuration) {
return LegacySkyKey.create(SkyFunctions.REGISTERED_TOOLCHAINS, configuration);
}

public static RegisteredToolchainsValue create(
Iterable<DeclaredToolchainInfo> registeredToolchains) {
return new AutoValue_RegisteredToolchainsValue(ImmutableList.copyOf(registeredToolchains));
}

public abstract ImmutableList<DeclaredToolchainInfo> registeredToolchains();
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ public final class SkyFunctions {
SkyFunctionName.create("ACTION_TEMPLATE_EXPANSION");
public static final SkyFunctionName LOCAL_REPOSITORY_LOOKUP =
SkyFunctionName.create("LOCAL_REPOSITORY_LOOKUP");
public static final SkyFunctionName REGISTERED_TOOLCHAINS =
SkyFunctionName.create("REGISTERED_TOOLCHAINS");

public static Predicate<SkyKey> isSkyFunction(final SkyFunctionName functionName) {
return new Predicate<SkyKey>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,7 @@ private ImmutableMap<SkyFunctionName, SkyFunction> skyFunctions(
SkyFunctions.ACTION_TEMPLATE_EXPANSION,
new ActionTemplateExpansionFunction(removeActionsAfterEvaluation));
map.put(SkyFunctions.LOCAL_REPOSITORY_LOOKUP, new LocalRepositoryLookupFunction());
map.put(SkyFunctions.REGISTERED_TOOLCHAINS, new RegisteredToolchainsFunction());
map.putAll(extraSkyFunctions);
return map.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,24 @@ protected FileConfiguredTarget getHostFileConfiguredTarget(String label)
return (FileConfiguredTarget) getHostConfiguredTarget(label);
}

/**
* Rewrites the WORKSPACE to have the required boilerplate and the given lines of content.
*
* <p>Triggers Skyframe to reinitialize everything.
*/
public void rewriteWorkspace(String... lines) throws Exception {
scratch.overwriteFile(
"WORKSPACE",
new ImmutableList.Builder<String>()
.addAll(analysisMock.getWorkspaceContents(mockToolsConfig))
.addAll(ImmutableList.copyOf(lines))
.build());

invalidatePackages();
// Need to re-initialize the workspace status.
getSkyframeExecutor().injectWorkspaceStatusData("test");
}

/**
* Create and return a configured scratch rule.
*
Expand Down
20 changes: 19 additions & 1 deletion src/test/java/com/google/devtools/build/lib/rules/platform/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ filegroup(
visibility = ["//src/test/java/com/google/devtools/build/lib:__pkg__"],
)

TESTUTIL_SRCS = ["ToolchainTestCase.java"]

java_test(
name = "PlatformRulesTests",
srcs = glob(["*.java"]),
srcs = glob(
["*.java"],
exclude = TESTUTIL_SRCS,
),
test_class = "com.google.devtools.build.lib.AllTests",
deps = [
"//src/main/java/com/google/devtools/build/lib:build-base",
Expand All @@ -26,3 +31,16 @@ java_test(
"//third_party:truth",
],
)

java_library(
name = "testutil",
srcs = TESTUTIL_SRCS,
visibility = ["//src/test/java/com/google/devtools/build/lib:__subpackages__"],
deps = [
"//src/main/java/com/google/devtools/build/lib/analysis/platform",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/test/java/com/google/devtools/build/lib/skylark:testutil",
"//third_party:junit4",
"//third_party:truth",
],
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// 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.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.cmdline.Label;
import com.google.devtools.build.lib.skylark.util.SkylarkTestCase;
import org.junit.Before;

/** Utility methods for setting up platform and toolchain related tests. */
public abstract class ToolchainTestCase extends SkylarkTestCase {

public Label testToolchainType;
public ConstraintSettingInfo setting;
public ConstraintValueInfo linuxConstraint;
public ConstraintValueInfo macConstraint;

@Before
public void createConstraints() throws Exception {
scratch.file(
"constraint/BUILD",
"constraint_setting(name = 'os')",
"constraint_value(name = 'linux',",
" constraint_setting = ':os')",
"constraint_value(name = 'mac',",
" constraint_setting = ':os')");

setting = ConstraintSettingInfo.create(makeLabel("//constraint:os"));
linuxConstraint = ConstraintValueInfo.create(setting, makeLabel("//constraint:linux"));
macConstraint = ConstraintValueInfo.create(setting, makeLabel("//constraint:mac"));
}

@Before
public void createToolchains() throws Exception {
rewriteWorkspace(
"register_toolchains(", " '//toolchain:toolchain_1',", " '//toolchain:toolchain_2')");

scratch.file(
"toolchain/BUILD",
"load(':toolchain_def.bzl', 'test_toolchain')",
"toolchain_type(name = 'test_toolchain')",
"toolchain(",
" name = 'toolchain_1',",
" toolchain_type = ':test_toolchain',",
" exec_compatible_with = ['//constraint:linux'],",
" target_compatible_with = ['//constraint:mac'],",
" toolchain = ':test_toolchain_1')",
"toolchain(",
" name = 'toolchain_2',",
" toolchain_type = ':test_toolchain',",
" exec_compatible_with = ['//constraint:mac'],",
" target_compatible_with = ['//constraint:linux'],",
" toolchain = ':test_toolchain_2')",
"test_toolchain(",
" name='test_toolchain_1',",
" data = 'foo')",
"test_toolchain(",
" name='test_toolchain_2',",
" data = 'bar')");
scratch.file(
"toolchain/toolchain_def.bzl",
"def _impl(ctx):",
" toolchain = platform_common.ToolchainInfo(",
" type = Label('//toolchain:test_toolchain'),",
" data = ctx.attr.data)",
" return [toolchain]",
"test_toolchain = rule(",
" implementation = _impl,",
" attrs = {",
" 'data': attr.string()})");

testToolchainType = makeLabel("//toolchain:test_toolchain");
}
}
4 changes: 4 additions & 0 deletions src/test/java/com/google/devtools/build/lib/skyframe/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ java_library(
"//src/main/java/com/google/devtools/build/lib:vfs",
"//src/main/java/com/google/devtools/build/lib/actions",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/rules/platform",
"//src/main/java/com/google/devtools/build/skyframe",
"//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
"//src/test/java/com/google/devtools/build/lib:actions_testutil",
Expand Down Expand Up @@ -69,15 +70,18 @@ java_test(
"//src/main/java/com/google/devtools/build/lib:util",
"//src/main/java/com/google/devtools/build/lib:vfs",
"//src/main/java/com/google/devtools/build/lib/actions",
"//src/main/java/com/google/devtools/build/lib/analysis/platform",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/rules/cpp",
"//src/main/java/com/google/devtools/build/lib/rules/platform",
"//src/main/java/com/google/devtools/build/skyframe",
"//src/main/java/com/google/devtools/build/skyframe:skyframe-objects",
"//src/test/java/com/google/devtools/build/lib:actions_testutil",
"//src/test/java/com/google/devtools/build/lib:analysis_testutil",
"//src/test/java/com/google/devtools/build/lib:foundations_testutil",
"//src/test/java/com/google/devtools/build/lib:packages_testutil",
"//src/test/java/com/google/devtools/build/lib:testutil",
"//src/test/java/com/google/devtools/build/lib/rules/platform:testutil",
"//third_party:guava",
"//third_party:guava-testlib",
"//third_party:jsr305",
Expand Down
Loading

0 comments on commit f626144

Please sign in to comment.