diff options
Diffstat (limited to 'src/main/java')
9 files changed, 235 insertions, 69 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/ExecutionInfoSpecifier.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/ExecutionInfoSpecifier.java new file mode 100644 index 0000000000..d6d37e05c9 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/ExecutionInfoSpecifier.java @@ -0,0 +1,34 @@ +// Copyright 2016 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.actions; + +import java.util.Map; + +/** + * An action that specifies requirements for its execution. + */ +public interface ExecutionInfoSpecifier { + + /** + * Returns execution data for this action. This is used to signal hardware requirements to the + * execution (ex. "requires-darwin"). This is a workaround to allow execution on platforms other + * than that specified by the host configuration. The ability to choose seperate platforms by + * action can provide a performance advantage. + * + * <p>Restrictions are mapped to arbitrary values (typically "") so as to be consistent with + * {@link com.google.devtools.build.lib.actions.Spawn#getExecutionInfo()}. + */ + Map<String, String> getExecutionInfo(); +} diff --git a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java index b9d86748e7..e364d9e535 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/actions/SpawnAction.java @@ -64,7 +64,7 @@ import javax.annotation.CheckReturnValue; /** * An Action representing an arbitrary subprocess to be forked and exec'd. */ -public class SpawnAction extends AbstractAction { +public class SpawnAction extends AbstractAction implements ExecutionInfoSpecifier { private static class ExtraActionInfoSupplier<T> { private final GeneratedExtension<ExtraActionInfo, T> extension; private final T value; @@ -364,6 +364,7 @@ public class SpawnAction extends AbstractAction { /** * Returns the out-of-band execution data for this action. */ + @Override public Map<String, String> getExecutionInfo() { return executionInfo; } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java index 8b86d48453..eda0dfbc73 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java @@ -213,6 +213,7 @@ public abstract class CcBinary implements RuleConfiguredTargetFactory { linkActionBuilder.setLinkType(linkType); linkActionBuilder.setLinkStaticness(linkStaticness); linkActionBuilder.setFake(fake); + linkActionBuilder.setFeatureConfiguration(featureConfiguration); if (CppLinkAction.enableSymbolsCounts(cppConfiguration, fake, linkType)) { linkActionBuilder.setSymbolCountsOutput(ruleContext.getPackageRelativeArtifact( diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java index 41124222bb..b6d9e10c94 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeatures.java @@ -520,6 +520,7 @@ public class CcToolchainFeatures implements Serializable { flagSetBuilder.add(new FlagSet(flagSet)); } this.flagSets = flagSetBuilder.build(); + ImmutableList.Builder<EnvSet> envSetBuilder = ImmutableList.builder(); for (CToolchain.EnvSet flagSet : feature.getEnvSetList()) { envSetBuilder.add(new EnvSet(flagSet)); @@ -532,8 +533,11 @@ public class CcToolchainFeatures implements Serializable { return name; } - private void expandEnvironment(String action, Variables variables, - ImmutableMap.Builder<String, String> envBuilder) { + /** + * Adds environment variables for the given action to the provided builder. + */ + private void expandEnvironment( + String action, Variables variables, ImmutableMap.Builder<String, String> envBuilder) { for (EnvSet envSet : envSets) { envSet.expandEnvironment(action, variables, envBuilder); } @@ -551,6 +555,42 @@ public class CcToolchainFeatures implements Serializable { } /** + * An executable to be invoked by a blaze action. Can carry information on its platform + * restrictions. + */ + @Immutable + static class Tool { + private final String toolPathString; + private final ImmutableSet<String> executionRequirements; + + private Tool(CToolchain.Tool tool) { + toolPathString = tool.getToolPath(); + executionRequirements = ImmutableSet.copyOf(tool.getExecutionRequirementList()); + } + + @VisibleForTesting + public Tool(String toolPathString, ImmutableSet<String> executionRequirements) { + this.toolPathString = toolPathString; + this.executionRequirements = executionRequirements; + } + + /** + * Returns the path to this action's tool relative to the provided crosstool path. + */ + PathFragment getToolPath(PathFragment crosstoolTopPathFragment) { + return crosstoolTopPathFragment.getRelative(toolPathString); + } + + /** + * Returns a list of requirement hints that apply to the execution of this tool. + */ + ImmutableSet<String> getExecutionRequirements() { + return executionRequirements; + } + } + + + /** * A container for information on a particular blaze action. * * <p>An ActionConfig can select a tool for its blaze action based on the set of active @@ -597,9 +637,8 @@ public class CcToolchainFeatures implements Serializable { * Returns the path to this action's tool relative to the provided crosstool path given a set * of enabled features. */ - private PathFragment getTool( - PathFragment crosstoolTopPathFragment, final Set<String> enabledFeatureNames) { - Optional<Tool> tool = + private Tool getTool(final Set<String> enabledFeatureNames) { + Optional<CToolchain.Tool> tool = Iterables.tryFind( tools, new Predicate<CToolchain.Tool>() { @@ -612,7 +651,7 @@ public class CcToolchainFeatures implements Serializable { } }); if (tool.isPresent()) { - return crosstoolTopPathFragment.getRelative(tool.get().getToolPath()); + return new Tool(tool.get()); } else { throw new IllegalArgumentException( "Matching tool for action " @@ -968,7 +1007,7 @@ public class CcToolchainFeatures implements Serializable { public static class FeatureConfiguration { private final ImmutableSet<String> enabledFeatureNames; private final Iterable<Feature> enabledFeatures; - + private final ImmutableMap<String, ActionConfig> actionConfigByActionName; public FeatureConfiguration() { @@ -983,6 +1022,7 @@ public class CcToolchainFeatures implements Serializable { Iterable<ActionConfig> enabledActionConfigs, ImmutableMap<String, ActionConfig> actionConfigByActionName) { this.enabledFeatures = enabledFeatures; + this.actionConfigByActionName = actionConfigByActionName; ImmutableSet.Builder<String> featureBuilder = ImmutableSet.builder(); for (Feature feature : enabledFeatures) { @@ -1004,6 +1044,13 @@ public class CcToolchainFeatures implements Serializable { } /** + * @return whether an action config for the blaze action with the given name is enabled. + */ + boolean actionIsConfigured(String actionName) { + return actionConfigByActionName.containsKey(actionName); + } + + /** * @return the command line for the given {@code action}. */ List<String> getCommandLine(String action, Variables variables) { @@ -1024,19 +1071,17 @@ public class CcToolchainFeatures implements Serializable { } return envBuilder.build(); } - + /** - * Returns the path to the given action's tool under this FeatureConfiguration relative to the - * crosstool. + * Returns a given action's tool under this FeatureConfiguration. */ - PathFragment getToolPathFragmentForAction( - final String actionName, PathFragment crosstoolTopPathFragment) { + Tool getToolForAction(String actionName) { Preconditions.checkArgument( actionConfigByActionName.containsKey(actionName), "Action %s does not have an enabled configuration in the toolchain.", actionName); ActionConfig actionConfig = actionConfigByActionName.get(actionName); - return actionConfig.getTool(crosstoolTopPathFragment, enabledFeatureNames); + return actionConfig.getTool(enabledFeatureNames); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java index 0e530012cd..c9bf6657ff 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileAction.java @@ -37,6 +37,7 @@ import com.google.devtools.build.lib.actions.ResourceSet; import com.google.devtools.build.lib.actions.extra.CppCompileInfo; import com.google.devtools.build.lib.actions.extra.ExtraActionInfo; import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.actions.ExecutionInfoSpecifier; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.PerLabelOptions; import com.google.devtools.build.lib.cmdline.Label; @@ -85,7 +86,8 @@ import javax.annotation.concurrent.GuardedBy; * Action that represents some kind of C++ compilation step. */ @ThreadCompatible -public class CppCompileAction extends AbstractAction implements IncludeScannable { +public class CppCompileAction extends AbstractAction + implements IncludeScannable, ExecutionInfoSpecifier { /** * Represents logic that determines if an artifact is a special input, meaning that it may require * additional inputs when it is compiled or may not be available to other actions. @@ -172,6 +174,7 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable private final ImmutableList<Artifact> builtinIncludeFiles; @VisibleForTesting public final CppCompileCommandLine cppCompileCommandLine; private final boolean usePic; + private final ImmutableSet<String> executionRequirements; @VisibleForTesting final CppConfiguration cppConfiguration; @@ -223,6 +226,10 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable * @param context the compilation context * @param copts options for the compiler * @param coptsFilter regular expression to remove options from {@code copts} + * @param executionRequirements out-of-band hints to be passed to the execution backend to signal + * platform requirements + * @param actionName a string giving the name of this action for the purpose of toolchain + * evaluation */ protected CppCompileAction( ActionOwner owner, @@ -253,6 +260,8 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable Iterable<IncludeScannable> lipoScannables, UUID actionClassId, boolean usePic, + ImmutableSet<String> executionRequirements, + String actionName, RuleContext ruleContext) { super(owner, createInputs(ruleContext, @@ -286,11 +295,13 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable features, featureConfiguration, variables, - fdoBuildStamp); + fdoBuildStamp, + actionName); this.actionContext = actionContext; this.lipoScannables = lipoScannables; this.actionClassId = actionClassId; this.usePic = usePic; + this.executionRequirements = executionRequirements; // We do not need to include the middleman artifact since it is a generated // artifact and will definitely exist prior to this action execution. @@ -702,6 +713,15 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable return cppCompileCommandLine.getCompilerOptions(); } + @Override + public Map<String, String> getExecutionInfo() { + ImmutableMap.Builder<String, String> result = ImmutableMap.<String, String>builder(); + for (String requirement : executionRequirements) { + result.put(requirement, ""); + } + return result.build(); + } + /** * Enforce that the includes actually visited during the compile were properly * declared in the rules. @@ -1122,6 +1142,7 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable f.addUUID(actionClassId); f.addStringMap(getEnvironment()); f.addStrings(getArgv()); + f.addStrings(executionRequirements); /* * getArgv() above captures all changes which affect the compilation @@ -1270,6 +1291,7 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable private final Collection<String> features; private final FeatureConfiguration featureConfiguration; @VisibleForTesting public final CcToolchainFeatures.Variables variables; + private final String actionName; // The value of the BUILD_FDO_TYPE macro to be defined on command line @Nullable private final String fdoBuildStamp; @@ -1284,7 +1306,8 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable Collection<String> features, FeatureConfiguration featureConfiguration, CcToolchainFeatures.Variables variables, - @Nullable String fdoBuildStamp) { + @Nullable String fdoBuildStamp, + String actionName) { this.sourceFile = Preconditions.checkNotNull(sourceFile); this.dotdFile = CppFileTypes.mustProduceDotdFile(sourceFile.getPath().toString()) ? Preconditions.checkNotNull(dotdFile) : null; @@ -1296,13 +1319,14 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable this.featureConfiguration = featureConfiguration; this.variables = variables; this.fdoBuildStamp = fdoBuildStamp; + this.actionName = actionName; } /** * Returns the environment variables that should be set for C++ compile actions. */ protected Map<String, String> getEnvironment() { - return featureConfiguration.getEnvironmentVariables(getActionName(), variables); + return featureConfiguration.getEnvironmentVariables(actionName, variables); } protected List<String> getArgv(PathFragment outputFile) { @@ -1325,39 +1349,6 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable return commandLine; } - private String getActionName() { - PathFragment sourcePath = sourceFile.getExecPath(); - if (CppFileTypes.CPP_MODULE_MAP.matches(sourcePath)) { - return CPP_MODULE_COMPILE; - } else if (CppFileTypes.CPP_HEADER.matches(sourcePath)) { - // TODO(bazel-team): Handle C headers that probably don't work in C++ mode. - if (featureConfiguration.isEnabled(CppRuleClasses.PARSE_HEADERS)) { - return CPP_HEADER_PARSING; - } else if (featureConfiguration.isEnabled(CppRuleClasses.PREPROCESS_HEADERS)) { - return CPP_HEADER_PREPROCESSING; - } else { - // CcCommon.collectCAndCppSources() ensures we do not add headers to - // the compilation artifacts unless either 'parse_headers' or - // 'preprocess_headers' is set. - throw new IllegalStateException(); - } - } else if (CppFileTypes.C_SOURCE.matches(sourcePath)) { - return C_COMPILE; - } else if (CppFileTypes.CPP_SOURCE.matches(sourcePath)) { - return CPP_COMPILE; - } else if (CppFileTypes.OBJC_SOURCE.matches(sourcePath)) { - return OBJC_COMPILE; - } else if (CppFileTypes.OBJCPP_SOURCE.matches(sourcePath)) { - return OBJCPP_COMPILE; - } else if (CppFileTypes.ASSEMBLER.matches(sourcePath)) { - return ASSEMBLE; - } else if (CppFileTypes.ASSEMBLER_WITH_C_PREPROCESSOR.matches(sourcePath)) { - return PREPROCESS_ASSEMBLE; - } - // CcLibraryHelper ensures CppCompileAction only gets instantiated for supported file types. - throw new IllegalStateException(); - } - public List<String> getCompilerOptions() { List<String> options = new ArrayList<>(); CppConfiguration toolchain = cppConfiguration; @@ -1393,8 +1384,7 @@ public class CppCompileAction extends AbstractAction implements IncludeScannable // unfiltered compiler options to inject include paths, which is superseded by the feature // configuration; on the other hand toolchains switch off warnings for the layering check // that will be re-added by the feature flags. - addFilteredOptions(options, - featureConfiguration.getCommandLine(getActionName(), variables)); + addFilteredOptions(options, featureConfiguration.getCommandLine(actionName, variables)); // TODO(bazel-team): Move this into a feature; more specifically, create a feature for both // the amount of debug information requested, and whether the debug info is written in a diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java index 1cdcf26c93..81ae9144ad 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppCompileActionBuilder.java @@ -20,6 +20,7 @@ import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.ActionOwner; import com.google.devtools.build.lib.actions.Artifact; @@ -242,6 +243,39 @@ public class CppCompileActionBuilder { Predicates.notNull()); } + private String getActionName() { + PathFragment sourcePath = sourceFile.getExecPath(); + if (CppFileTypes.CPP_MODULE_MAP.matches(sourcePath)) { + return CppCompileAction.CPP_MODULE_COMPILE; + } else if (CppFileTypes.CPP_HEADER.matches(sourcePath)) { + // TODO(bazel-team): Handle C headers that probably don't work in C++ mode. + if (featureConfiguration.isEnabled(CppRuleClasses.PARSE_HEADERS)) { + return CppCompileAction.CPP_HEADER_PARSING; + } else if (featureConfiguration.isEnabled(CppRuleClasses.PREPROCESS_HEADERS)) { + return CppCompileAction.CPP_HEADER_PREPROCESSING; + } else { + // CcCommon.collectCAndCppSources() ensures we do not add headers to + // the compilation artifacts unless either 'parse_headers' or + // 'preprocess_headers' is set. + throw new IllegalStateException(); + } + } else if (CppFileTypes.C_SOURCE.matches(sourcePath)) { + return CppCompileAction.C_COMPILE; + } else if (CppFileTypes.CPP_SOURCE.matches(sourcePath)) { + return CppCompileAction.CPP_COMPILE; + } else if (CppFileTypes.OBJC_SOURCE.matches(sourcePath)) { + return CppCompileAction.OBJC_COMPILE; + } else if (CppFileTypes.OBJCPP_SOURCE.matches(sourcePath)) { + return CppCompileAction.OBJCPP_COMPILE; + } else if (CppFileTypes.ASSEMBLER.matches(sourcePath)) { + return CppCompileAction.ASSEMBLE; + } else if (CppFileTypes.ASSEMBLER_WITH_C_PREPROCESSOR.matches(sourcePath)) { + return CppCompileAction.PREPROCESS_ASSEMBLE; + } + // CcLibraryHelper ensures CppCompileAction only gets instantiated for supported file types. + throw new IllegalStateException(); + } + /** * Builds the Action as configured and returns the to be generated Artifact. * @@ -266,6 +300,15 @@ public class CppCompileActionBuilder { realMandatoryInputsBuilder.add(sourceFile); boolean fake = tempOutputFile != null; + // If the crosstool uses action_configs to configure cc compilation, collect execution info + // from there, otherwise, use no execution info. + // TODO(b/27903698): Assert that the crosstool has an action_config for this action. + ImmutableSet<String> executionRequirements = ImmutableSet.of(); + if (featureConfiguration.actionIsConfigured(getActionName())) { + executionRequirements = + featureConfiguration.getToolForAction(getActionName()).getExecutionRequirements(); + } + // Copying the collections is needed to make the builder reusable. if (fake) { return new FakeCppCompileAction(owner, ImmutableList.copyOf(features), featureConfiguration, @@ -305,6 +348,8 @@ public class CppCompileActionBuilder { getLipoScannables(realMandatoryInputs), actionClassId, usePic, + executionRequirements, + getActionName(), ruleContext); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java index b0a1b7d825..154ecf6f75 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkAction.java @@ -38,6 +38,7 @@ import com.google.devtools.build.lib.actions.extra.ExtraActionInfo; import com.google.devtools.build.lib.analysis.AnalysisEnvironment; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; +import com.google.devtools.build.lib.analysis.actions.ExecutionInfoSpecifier; import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.collect.CollectionUtils; @@ -50,6 +51,7 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe; import com.google.devtools.build.lib.packages.RuleErrorConsumer; +import com.google.devtools.build.lib.rules.cpp.CcToolchainFeatures.FeatureConfiguration; import com.google.devtools.build.lib.rules.cpp.Link.LinkStaticness; import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType; import com.google.devtools.build.lib.rules.cpp.LinkerInputs.LibraryToLink; @@ -76,7 +78,7 @@ import javax.annotation.Nullable; * Action that represents a linking step. */ @ThreadCompatible -public final class CppLinkAction extends AbstractAction { +public final class CppLinkAction extends AbstractAction implements ExecutionInfoSpecifier { /** * An abstraction for creating intermediate and output artifacts for C++ linking. * @@ -107,10 +109,16 @@ public final class CppLinkAction extends AbstractAction { private static final String LINK_GUID = "58ec78bd-1176-4e36-8143-439f656b181d"; private static final String FAKE_LINK_GUID = "da36f819-5a15-43a9-8a45-e01b60e10c8b"; + /** + * The name of this action for the purpose of crosstool features/action_configs + */ + private static final String ACTION_NAME = "cpp-link"; + private final CppConfiguration cppConfiguration; private final LibraryToLink outputLibrary; private final LibraryToLink interfaceOutputLibrary; - + private final ImmutableSet<String> executionRequirements; + private final LinkCommandLine linkCommandLine; /** True for cc_fake_binary targets. */ @@ -155,7 +163,8 @@ public final class CppLinkAction extends AbstractAction { boolean fake, boolean isLTOIndexing, Iterable<LTOBackendArtifacts> allLTOBackendArtifacts, - LinkCommandLine linkCommandLine) { + LinkCommandLine linkCommandLine, + ImmutableSet<String> executionRequirements) { super(owner, inputs, outputs); this.mandatoryInputs = inputs; this.cppConfiguration = cppConfiguration; @@ -165,6 +174,7 @@ public final class CppLinkAction extends AbstractAction { this.isLTOIndexing = isLTOIndexing; this.allLTOBackendArtifacts = allLTOBackendArtifacts; this.linkCommandLine = linkCommandLine; + this.executionRequirements = executionRequirements; } private static Iterable<LinkerInput> filterLinkerInputs(Iterable<LinkerInput> inputs) { @@ -243,6 +253,15 @@ public final class CppLinkAction extends AbstractAction { return outputLibrary.getArtifact().getPath(); } + @Override + public Map<String, String> getExecutionInfo() { + ImmutableMap.Builder<String, String> result = ImmutableMap.<String, String>builder(); + for (String requirement : executionRequirements) { + result.put(requirement, ""); + } + return result.build(); + } + @VisibleForTesting public List<String> getRawLinkArgv() { return linkCommandLine.getRawLinkArgv(); @@ -405,6 +424,8 @@ public final class CppLinkAction extends AbstractAction { f.addString(fake ? FAKE_LINK_GUID : LINK_GUID); f.addString(getCppConfiguration().getLdExecutable().getPathString()); f.addStrings(linkCommandLine.arguments()); + f.addStrings(executionRequirements); + // TODO(bazel-team): For correctness, we need to ensure the invariant that all values accessed // during the execution phase are also covered by the key. Above, we add the argv to the key, // which covers most cases. Unfortunately, the extra action and fake support methods above also @@ -518,6 +539,7 @@ public final class CppLinkAction extends AbstractAction { private PathFragment runtimeSolibDir; protected final BuildConfiguration configuration; private final CppConfiguration cppConfiguration; + private FeatureConfiguration featureConfiguration; // Morally equivalent with {@link Context}, except these are mutable. // Keep these in sync with {@link Context}. @@ -870,6 +892,17 @@ public final class CppLinkAction extends AbstractAction { analysisEnvironment.registerAction(parameterFileWriteAction); } + // If the crosstool uses action_configs to configure cc compilation, collect execution info + // from there, otherwise, use no execution info. + // TODO(b/27903698): Assert that the crosstool has an action_config for this action. + ImmutableSet<String> executionRequirements = ImmutableSet.of(); + if (featureConfiguration != null) { + if (featureConfiguration.actionIsConfigured(ACTION_NAME)) { + executionRequirements = + featureConfiguration.getToolForAction(ACTION_NAME).getExecutionRequirements(); + } + } + return new CppLinkAction( getOwner(), inputsBuilder.deduplicate().build(), @@ -880,7 +913,8 @@ public final class CppLinkAction extends AbstractAction { fake, isLTOIndexing, allLTOArtifacts, - linkCommandLine); + linkCommandLine, + executionRequirements); } /** @@ -954,6 +988,14 @@ public final class CppLinkAction extends AbstractAction { this.crosstoolInputs = inputs; return this; } + + /** + * Sets the feature configuration for the action. + */ + public Builder setFeatureConfiguration(FeatureConfiguration featureConfiguration) { + this.featureConfiguration = featureConfiguration; + return this; + } /** * This is the LTO indexing step, rather than the real link. diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java index 579e8492d8..b7fe1be014 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppModel.java @@ -300,6 +300,7 @@ public final class CppModel { builder.setExtraSystemIncludePrefixes(additionalIncludes); builder.setFdoBuildStamp(CppHelper.getFdoBuildStamp(ruleContext)); builder.setFeatureConfiguration(featureConfiguration); + return builder; } @@ -642,6 +643,7 @@ public final class CppModel { .addLTOBitcodeFiles(ccOutputs.getLtoBitcodeFiles()) .setLinkType(linkType) .setLinkStaticness(LinkStaticness.FULLY_STATIC) + .setFeatureConfiguration(featureConfiguration) .build(); env.registerAction(maybePicAction); result.addStaticLibrary(maybePicAction.getOutputLibrary()); @@ -662,6 +664,7 @@ public final class CppModel { .addLTOBitcodeFiles(ccOutputs.getLtoBitcodeFiles()) .setLinkType(picLinkType) .setLinkStaticness(LinkStaticness.FULLY_STATIC) + .setFeatureConfiguration(featureConfiguration) .build(); env.registerAction(picAction); result.addPicStaticLibrary(picAction.getOutputLibrary()); @@ -690,18 +693,20 @@ public final class CppModel { // Should we also link in any libraries that this library depends on? // That is required on some systems... - CppLinkAction action = newLinkActionBuilder(soImpl) - .setInterfaceOutput(soInterface) - .addNonLibraryInputs(ccOutputs.getObjectFiles(usePicForSharedLibs)) - .addNonLibraryInputs(ccOutputs.getHeaderTokenFiles()) - .setLinkType(LinkTargetType.DYNAMIC_LIBRARY) - .setLinkStaticness(LinkStaticness.DYNAMIC) - .addLinkopts(linkopts) - .addLinkopts(sonameLinkopts) - .setRuntimeInputs( - CppHelper.getToolchain(ruleContext).getDynamicRuntimeLinkMiddleman(), - CppHelper.getToolchain(ruleContext).getDynamicRuntimeLinkInputs()) - .build(); + CppLinkAction action = + newLinkActionBuilder(soImpl) + .setInterfaceOutput(soInterface) + .addNonLibraryInputs(ccOutputs.getObjectFiles(usePicForSharedLibs)) + .addNonLibraryInputs(ccOutputs.getHeaderTokenFiles()) + .setLinkType(LinkTargetType.DYNAMIC_LIBRARY) + .setLinkStaticness(LinkStaticness.DYNAMIC) + .addLinkopts(linkopts) + .addLinkopts(sonameLinkopts) + .setRuntimeInputs( + CppHelper.getToolchain(ruleContext).getDynamicRuntimeLinkMiddleman(), + CppHelper.getToolchain(ruleContext).getDynamicRuntimeLinkInputs()) + .setFeatureConfiguration(featureConfiguration) + .build(); env.registerAction(action); LibraryToLink dynamicLibrary = action.getOutputLibrary(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java index dc5b22dad8..75638eed25 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FakeCppCompileAction.java @@ -20,6 +20,7 @@ import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionExecutionException; @@ -116,6 +117,8 @@ public class FakeCppCompileAction extends CppCompileAction { ImmutableList.<IncludeScannable>of(), GUID, usePic, + ImmutableSet.<String>of(), + CppCompileAction.CPP_COMPILE, ruleContext); this.tempOutputFile = Preconditions.checkNotNull(tempOutputFile); } |