Skip to content

Commit

Permalink
Add toolchain resolution via late-bound-labels.
Browse files Browse the repository at this point in the history
Part of bazelbuild#2219.

Experimental, DO NOT SUBMIT.

Change-Id: I101bb9fbaab0debb20b9bc07fca3b0dc4b9ff66b
  • Loading branch information
katre committed Apr 28, 2017
1 parent c2536e1 commit 1fae65d
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/main/java/com/google/devtools/build/lib/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,7 @@ java_library(
"//src/main/java/com/google/devtools/build/lib/buildeventstream/proto:build_event_stream_java_proto",
"//src/main/java/com/google/devtools/build/lib/causes",
"//src/main/java/com/google/devtools/build/lib/cmdline",
"//src/main/java/com/google/devtools/build/lib/analysis/platform",
"//src/main/java/com/google/devtools/build/skyframe",
"//src/main/java/com/google/devtools/common/options",
"//src/main/protobuf:extra_actions_base_java_proto",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,49 @@ public Metadata getMetadata() {
}
}

/**
* Implementation for the :target_platform attribute.
*/
public static final LateBoundLabel<BuildConfiguration> TARGET_PLATFORM =
new LateBoundLabel<BuildConfiguration>() {
@Override
public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
if (rule.getRuleClassObject().getRequiredToolchains().isEmpty()) {
return null;
}
return configuration.getTargetPlatform();
}
};

/**
* Implementation for the :exec_platform attribute.
*/
public static final LateBoundLabel<BuildConfiguration> EXEC_PLATFORM =
new LateBoundLabel<BuildConfiguration>() {
@Override
public Label resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
// TODO(katre): Replace this with exec platform once we are using platforms with remote execution.
if (rule.getRuleClassObject().getRequiredToolchains().isEmpty()) {
return null;
}
return configuration.getHostPlatform();
}
};

/**
* Implementation for the :toolchains attribute.
*/
public static final LateBoundLabelList<BuildConfiguration> TOOLCHAINS =
new LateBoundLabelList<BuildConfiguration>() {
@Override
public List<Label> resolve(Rule rule, AttributeMap attributes, BuildConfiguration configuration) {
if (rule.getRuleClassObject().getRequiredToolchains().isEmpty()) {
return null;
}
return configuration.getToolchains();
}
};

/**
* Share common attributes across both base and Skylark base rules.
*/
Expand Down Expand Up @@ -194,7 +237,17 @@ public static RuleClass.Builder commonCoreAndSkylarkAttributes(RuleClass.Builder
.allowedFileTypes(FileTypeSet.NO_FILE)
.dontCheckConstraints()
.nonconfigurable("special logic for constraints and select: see ConstraintSemantics")
);
)
.add(attr(":target_platform", LABEL)
.value(TARGET_PLATFORM)
.nonconfigurable("Used in toolchain resolution"))
.add(attr(":exec_platform", LABEL)
.value(EXEC_PLATFORM)
.nonconfigurable("Used in toolchain resolution"))
.add(attr(":toolchains", LABEL_LIST)
.value(TOOLCHAINS)
.nonconfigurable("Used in toolchain resolution"))
;
}

public static RuleClass.Builder nameAttribute(RuleClass.Builder builder) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ public ImmutableList<TransitiveInfoCollection> getFiles() {
private final ErrorReporter reporter;
private final ImmutableBiMap<String, Class<? extends TransitiveInfoProvider>>
skylarkProviderRegistry;
private final ToolchainResolver toolchainResolver;

private ActionOwner actionOwner;

Expand Down Expand Up @@ -197,6 +198,7 @@ private RuleContext(
this.skylarkProviderRegistry = builder.skylarkProviderRegistry;
this.hostConfiguration = builder.hostConfiguration;
reporter = builder.reporter;
this.toolchainResolver = new ToolchainResolver(this, builder.rule.getRuleClassObject().getRequiredToolchains());
}

private ImmutableSet<String> getEnabledFeatures() {
Expand Down Expand Up @@ -1119,6 +1121,10 @@ public String expandSingleMakeVariable(String attrName, String expression) {
}
}

public ToolchainResolver getToolchainResolver() {
return toolchainResolver;
}

private void checkAttribute(String attributeName, Mode mode) {
Attribute attributeDefinition = attributes.getAttributeDefinition(attributeName);
if (attributeDefinition == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// 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.analysis;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.analysis.platform.PlatformInfo;
import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
import com.google.devtools.build.lib.packages.SkylarkExportable;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.util.Preconditions;
import java.util.List;
import javax.annotation.Nullable;

/**
* Implements toolchain resolution depending on the configuration and the target's requested
* toolchains.
*/
public class ToolchainResolver {
//private ImmutableMap<SkylarkExportable, ToolchainInfo> toolchains;
private final RuleContext ruleContext;
private final ImmutableList<SkylarkExportable> requiredToolchains;

public ToolchainResolver(RuleContext ruleContext,
ImmutableList<SkylarkExportable> requiredToolchains) {
this.ruleContext = ruleContext;
this.requiredToolchains = requiredToolchains;
}

public SkylarkDict<SkylarkExportable, ToolchainInfo> collectToolchains() {
ImmutableMap<SkylarkExportable, ToolchainInfo> toolchains = resolveToolchains();
return SkylarkDict.<SkylarkExportable, ToolchainInfo>copyOf(null, toolchains);
}

private ImmutableMap<SkylarkExportable,ToolchainInfo> resolveToolchains() {
if (requiredToolchains.isEmpty()) {
return ImmutableMap.of();
}

PlatformInfo targetPlatform = platform(ruleContext.getPrerequisite(":target_platform", Mode.DONT_CHECK));
PlatformInfo execPlatform = platform(ruleContext.getPrerequisite(":exec_platform", Mode.DONT_CHECK));
List<ToolchainInfo> toolchains = toolchains(ruleContext.getPrerequisites(":toolchains", Mode.DONT_CHECK));

ImmutableMap.Builder<SkylarkExportable,ToolchainInfo> builder = new ImmutableMap.Builder<>();
for (SkylarkExportable toolchainSymbol : requiredToolchains) {
ToolchainInfo toolchain = resolveToolchain(toolchainSymbol, toolchains);
if (toolchain != null) {
builder.put(toolchainSymbol, toolchain);
}
}

return builder.build();
}

@Nullable
private static ToolchainInfo resolveToolchain(
SkylarkExportable toolchainSymbol,
List<ToolchainInfo> toolchains) {

// TODO(https://github.com/bazelbuild/bazel/issues/2219): Implement actual resolution.
/*
for (ToolchainInfo toolchain : toolchains) {
toolchain.toString();
// check if the toolchain matches the requested symbol.
}
*/
return toolchains.get(0);

//return null;
}

public static PlatformInfo platform(TransitiveInfoCollection target) {
Object provider = target.get(PlatformInfo.SKYLARK_IDENTIFIER);
if (provider == null) {
return null;
}
Preconditions.checkState(provider instanceof PlatformInfo);
return (PlatformInfo) provider;
}

public static ToolchainInfo toolchain(TransitiveInfoCollection target) {
Object provider = target.get(ToolchainInfo.SKYLARK_IDENTIFIER);
if (provider == null) {
return null;
}
Preconditions.checkState(provider instanceof ToolchainInfo);
return (ToolchainInfo) provider;
}

public static List<ToolchainInfo> toolchains(
Iterable<? extends TransitiveInfoCollection> targets) {
return ImmutableList.copyOf(Iterables.transform(
targets,
new Function<TransitiveInfoCollection, ToolchainInfo>() {
@Override
public ToolchainInfo apply(TransitiveInfoCollection target) {
return toolchain(target);
}
}));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.RawAttributeMapper;
import com.google.devtools.build.lib.packages.SkylarkClassObject;
import com.google.devtools.build.lib.packages.SkylarkExportable;
import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider;
import com.google.devtools.build.lib.shell.ShellUtils;
Expand Down Expand Up @@ -179,6 +181,7 @@ public Object apply(Attribute attribute) {
private SkylarkRuleAttributesCollection attributesCollection;
private SkylarkRuleAttributesCollection ruleAttributesCollection;
private SkylarkClassObject splitAttributes;
private SkylarkDict<SkylarkExportable, ToolchainInfo> toolchains;

// TODO(bazel-team): we only need this because of the css_binary rule.
private ImmutableMap<Artifact, Label> artifactsLabelMap;
Expand Down Expand Up @@ -279,6 +282,7 @@ public SkylarkRuleContext(RuleContext ruleContext,
}

makeVariables = ruleContext.getConfigurationMakeVariableContext().collectMakeVariables();
toolchains = ruleContext.getToolchainResolver().collectToolchains();
}

/**
Expand All @@ -297,6 +301,7 @@ public void nullify() {
splitAttributes = null;
artifactsLabelMap = null;
outputsObject = null;
toolchains = null;
}

public void checkMutable(String attrName) throws EvalException {
Expand Down Expand Up @@ -810,6 +815,15 @@ public SkylarkDict<String, String> var() throws EvalException {
return makeVariables;
}

@SkylarkCallable(
structField = true,
doc = "Toolchains required for this rule."
)
public SkylarkDict<SkylarkExportable, ToolchainInfo> toolchains() throws EvalException {
checkMutable("toolchains");
return toolchains;
}

@Override
public String toString() {
return ruleLabelCanonicalName;
Expand Down

0 comments on commit 1fae65d

Please sign in to comment.