diff options
author | 2017-05-30 13:50:04 +0200 | |
---|---|---|
committer | 2017-05-30 16:43:53 +0200 | |
commit | 573916acd2551772645a2f23ce3087771ed1d1e8 (patch) | |
tree | c0d7d503258bd09e62880452852fcaa4c9640c21 /src | |
parent | 84a8e95910f069dd03a19b0fc634f95bb0beac95 (diff) |
Add FeatureSpecification.
RELNOTES: None.
PiperOrigin-RevId: 157450873
Diffstat (limited to 'src')
12 files changed, 302 insertions, 187 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppSemantics.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppSemantics.java index e7b9830928..507cc76de4 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppSemantics.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppSemantics.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.rules.cpp.CppCompileActionContext; import com.google.devtools.build.lib.rules.cpp.CppConfiguration; import com.google.devtools.build.lib.rules.cpp.CppConfiguration.HeadersCheckingMode; import com.google.devtools.build.lib.rules.cpp.CppSemantics; +import com.google.devtools.build.lib.rules.cpp.FeatureSpecification; import com.google.devtools.build.lib.rules.cpp.IncludeProcessing; import com.google.devtools.build.lib.rules.cpp.NoProcessing; import com.google.devtools.build.lib.vfs.PathFragment; @@ -48,7 +49,9 @@ public class BazelCppSemantics implements CppSemantics { @Override public void finalizeCompileActionBuilder( - RuleContext ruleContext, CppCompileActionBuilder actionBuilder) { + RuleContext ruleContext, + CppCompileActionBuilder actionBuilder, + FeatureSpecification featureSpecification) { actionBuilder.setCppConfiguration(ruleContext.getFragment(CppConfiguration.class)); actionBuilder.setActionContext(CppCompileActionContext.class); // Because Bazel does not support include scanning, we need the entire crosstool filegroup, diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java index 505d8e33b0..6a130fcc8e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCommon.java @@ -52,7 +52,6 @@ import com.google.devtools.build.lib.vfs.PathFragment; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; import javax.annotation.Nullable; @@ -594,21 +593,20 @@ public final class CcCommon { /** * Creates the feature configuration for a given rule. * - * @param ruleContext the context of the rule we want the feature configuration for. - * @param ruleSpecificRequestedFeatures features that will be requested, and thus be always - * enabled if the toolchain supports them. - * @param ruleSpecificUnsupportedFeatures features that are not supported in the current context. - * @param sourceCategory the source category for this build. + * @see CcCommon#configureFeatures( + * RuleContext, FeatureSpecification, SourceCategory, CcToolchainProvider) + * + * @param features CcToolchainFeatures instance to use to get FeatureConfiguration * @return the feature configuration for the given {@code ruleContext}. */ public static FeatureConfiguration configureFeatures( RuleContext ruleContext, - Set<String> ruleSpecificRequestedFeatures, - Set<String> ruleSpecificUnsupportedFeatures, + FeatureSpecification featureSpecification, SourceCategory sourceCategory, - CcToolchainProvider toolchain) { + CcToolchainProvider toolchain, + CcToolchainFeatures features) { ImmutableSet.Builder<String> unsupportedFeaturesBuilder = ImmutableSet.builder(); - unsupportedFeaturesBuilder.addAll(ruleSpecificUnsupportedFeatures); + unsupportedFeaturesBuilder.addAll(featureSpecification.getUnsupportedFeatures()); if (!toolchain.supportsHeaderParsing()) { // TODO(bazel-team): Remove once supports_header_parsing has been removed from the // cc_toolchain rule. @@ -618,7 +616,7 @@ public final class CcCommon { if (toolchain.getCppCompilationContext().getCppModuleMap() == null) { unsupportedFeaturesBuilder.add(CppRuleClasses.MODULE_MAPS); } - Set<String> unsupportedFeatures = unsupportedFeaturesBuilder.build(); + ImmutableSet<String> unsupportedFeatures = unsupportedFeaturesBuilder.build(); ImmutableSet.Builder<String> requestedFeatures = ImmutableSet.builder(); for (String feature : Iterables.concat( @@ -631,12 +629,14 @@ public final class CcCommon { requestedFeatures.add(feature); } } - requestedFeatures.addAll(ruleSpecificRequestedFeatures); + requestedFeatures.addAll(featureSpecification.getRequestedFeatures()); requestedFeatures.addAll(sourceCategory.getActionConfigSet()); + FeatureSpecification currentFeatureSpecification = + FeatureSpecification.create(requestedFeatures.build(), unsupportedFeatures); FeatureConfiguration configuration = - toolchain.getFeatures().getFeatureConfiguration(requestedFeatures.build()); + features.getFeatureConfiguration(currentFeatureSpecification); for (String feature : unsupportedFeatures) { if (configuration.isEnabled(feature)) { ruleContext.ruleError( @@ -653,22 +653,35 @@ public final class CcCommon { return configuration; } + + /** + * Creates the feature configuration for a given rule. + * + * @see CcCommon#configureFeatures(RuleContext, CcToolchainProvider, SourceCategory) + * + * @param toolchain the current toolchain provider + * @return the feature configuration for the given {@code ruleContext}. + */ + public static FeatureConfiguration configureFeatures( + RuleContext ruleContext, + FeatureSpecification featureSpecification, + SourceCategory sourceCategory, + CcToolchainProvider toolchain) { + return configureFeatures( + ruleContext, featureSpecification, sourceCategory, toolchain, toolchain.getFeatures()); + } + /** * Creates a feature configuration for a given rule. * - * @param ruleContext the context of the rule we want the feature configuration for. - * @param toolchain the toolchain we want the feature configuration for. + * @see CcCommon#configureFeatures(RuleContext, CcToolchainProvider) + * * @param sourceCategory the category of sources to be used in this build. * @return the feature configuration for the given {@code ruleContext}. */ public static FeatureConfiguration configureFeatures( RuleContext ruleContext, CcToolchainProvider toolchain, SourceCategory sourceCategory) { - return configureFeatures( - ruleContext, - ImmutableSet.<String>of(), - ImmutableSet.<String>of(), - sourceCategory, - toolchain); + return configureFeatures(ruleContext, FeatureSpecification.EMPTY, sourceCategory, toolchain); } /** 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 d4088e9686..4cbc6cf8ce 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 @@ -41,7 +41,6 @@ import java.io.ObjectInputStream; import java.io.Serializable; import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -1718,23 +1717,27 @@ public class CcToolchainFeatures implements Serializable { */ @Immutable public static class FeatureConfiguration { + private final FeatureSpecification featureSpecification; private final ImmutableSet<String> enabledFeatureNames; private final Iterable<Feature> enabledFeatures; private final ImmutableSet<String> enabledActionConfigActionNames; private final ImmutableMap<String, ActionConfig> actionConfigByActionName; - + public FeatureConfiguration() { this( + FeatureSpecification.EMPTY, ImmutableList.<Feature>of(), ImmutableList.<ActionConfig>of(), ImmutableMap.<String, ActionConfig>of()); } private FeatureConfiguration( + FeatureSpecification featureSpecification, Iterable<Feature> enabledFeatures, Iterable<ActionConfig> enabledActionConfigs, ImmutableMap<String, ActionConfig> actionConfigByActionName) { + this.featureSpecification = featureSpecification; this.enabledFeatures = enabledFeatures; this.actionConfigByActionName = actionConfigByActionName; @@ -1806,6 +1809,10 @@ public class CcToolchainFeatures implements Serializable { ActionConfig actionConfig = actionConfigByActionName.get(actionName); return actionConfig.getTool(enabledFeatureNames); } + + public FeatureSpecification getFeatureSpecification() { + return featureSpecification; + } } /** All artifact name patterns defined in this feature configuration. */ @@ -1871,7 +1878,7 @@ public class CcToolchainFeatures implements Serializable { * A cache of feature selection results, so we do not recalculate the feature selection for all * actions. */ - private transient LoadingCache<Collection<String>, FeatureConfiguration> configurationCache = + private transient LoadingCache<FeatureSpecification, FeatureConfiguration> configurationCache = buildConfigurationCache(); /** @@ -2013,19 +2020,18 @@ public class CcToolchainFeatures implements Serializable { this.configurationCache = buildConfigurationCache(); } - /** - * @return an empty {@code FeatureConfiguration} cache. - */ - private LoadingCache<Collection<String>, FeatureConfiguration> buildConfigurationCache() { + /** @return an empty {@code FeatureConfiguration} cache. */ + private LoadingCache<FeatureSpecification, FeatureConfiguration> buildConfigurationCache() { return CacheBuilder.newBuilder() - // TODO(klimek): Benchmark and tweak once we support a larger configuration. + // TODO(klimek): Benchmark and tweak once we support a larger configuration. .maximumSize(10000) - .build(new CacheLoader<Collection<String>, FeatureConfiguration>() { - @Override - public FeatureConfiguration load(Collection<String> requestedFeatures) { - return computeFeatureConfiguration(requestedFeatures); - } - }); + .build( + new CacheLoader<FeatureSpecification, FeatureConfiguration>() { + @Override + public FeatureConfiguration load(FeatureSpecification featureSpecification) { + return computeFeatureConfiguration(featureSpecification); + } + }); } /** @@ -2038,28 +2044,25 @@ public class CcToolchainFeatures implements Serializable { * <p>Additional features will be enabled if the toolchain supports them and they are implied by * requested features. */ - public FeatureConfiguration getFeatureConfiguration(Collection<String> requestedFeatures) { - return configurationCache.getUnchecked(requestedFeatures); - } - - private FeatureConfiguration computeFeatureConfiguration(Collection<String> requestedFeatures) { - // Command line flags will be output in the order in which they are specified in the toolchain - // configuration. - return new FeatureSelection(requestedFeatures).run(); + public FeatureConfiguration getFeatureConfiguration(FeatureSpecification featureSpecification) { + return configurationCache.getUnchecked(featureSpecification); } - + /** - * Given a list of {@code requestedFeatures}, returns all features that are enabled by the - * toolchain configuration. + * Given {@code featureSpecification}, returns a FeatureConfiguration with all requested features + * enabled. * * <p>A requested feature will not be enabled if the toolchain does not support it (which may * depend on other requested features). * * <p>Additional features will be enabled if the toolchain supports them and they are implied by * requested features. - */ - public FeatureConfiguration getFeatureConfiguration(String... requestedFeatures) { - return getFeatureConfiguration(Arrays.asList(requestedFeatures)); + */ + public FeatureConfiguration computeFeatureConfiguration( + FeatureSpecification featureSpecification) { + // Command line flags will be output in the order in which they are specified in the toolchain + // configuration. + return new FeatureSelection(featureSpecification).run(); } /** Returns the list of features that specify themselves as enabled by default. */ @@ -2146,10 +2149,12 @@ public class CcToolchainFeatures implements Serializable { * from selectables that have unmet requirements. */ private final Set<CrosstoolSelectable> enabled = new HashSet<>(); - - private FeatureSelection(Collection<String> requestedSelectables) { + private final FeatureSpecification featureSpecification; + + private FeatureSelection(FeatureSpecification featureSpecification) { + this.featureSpecification = featureSpecification; ImmutableSet.Builder<CrosstoolSelectable> builder = ImmutableSet.builder(); - for (String name : requestedSelectables) { + for (String name : featureSpecification.getRequestedFeatures()) { if (selectablesByName.containsKey(name)) { builder.add(selectablesByName.get(name)); } @@ -2197,7 +2202,10 @@ public class CcToolchainFeatures implements Serializable { } return new FeatureConfiguration( - enabledFeaturesInOrder, enabledActionConfigsInOrder, actionConfigsByActionName); + featureSpecification, + enabledFeaturesInOrder, + enabledActionConfigsInOrder, + actionConfigsByActionName); } /** 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 1495309af2..c04501d8ca 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 @@ -263,10 +263,8 @@ public final class CppModel { this.soImplArtifact = soImplFilename; return this; } - - /** - * Sets the feature configuration to be used for C/C++ actions. - */ + + /** Sets the feature configuration to be used for C/C++ actions. */ public CppModel setFeatureConfiguration(FeatureConfiguration featureConfiguration) { this.featureConfiguration = featureConfiguration; return this; @@ -615,7 +613,8 @@ public final class CppModel { /*ltoIndexingFile=*/ null, builder.getContext().getCppModuleMap(), ImmutableMap.<String, String>of()); - semantics.finalizeCompileActionBuilder(ruleContext, builder); + semantics.finalizeCompileActionBuilder( + ruleContext, builder, featureConfiguration.getFeatureSpecification()); CppCompileAction compileAction = builder.buildAndValidate(ruleContext); env.registerAction(compileAction); Artifact tokenFile = compileAction.getOutputFile(); @@ -675,7 +674,8 @@ public final class CppModel { builder.setGcnoFile(gcnoFile); builder.setDwoFile(dwoFile); - semantics.finalizeCompileActionBuilder(ruleContext, builder); + semantics.finalizeCompileActionBuilder( + ruleContext, builder, featureConfiguration.getFeatureSpecification()); CppCompileAction compileAction = builder.build(); AnalysisEnvironment env = ruleContext.getAnalysisEnvironment(); env.registerAction(compileAction); @@ -734,7 +734,8 @@ public final class CppModel { /*ltoIndexingFile=*/ null, builder.getContext().getCppModuleMap(), /*sourceSpecificBuildVariables=*/ ImmutableMap.<String, String>of()); - semantics.finalizeCompileActionBuilder(ruleContext, builder); + semantics.finalizeCompileActionBuilder( + ruleContext, builder, featureConfiguration.getFeatureSpecification()); CppCompileAction compileAction = builder.buildAndValidate(ruleContext); env.registerAction(compileAction); Artifact tokenFile = compileAction.getOutputFile(); @@ -813,7 +814,8 @@ public final class CppModel { picBuilder.setDwoFile(dwoFile); picBuilder.setLTOIndexingFile(ltoIndexingFile); - semantics.finalizeCompileActionBuilder(ruleContext, picBuilder); + semantics.finalizeCompileActionBuilder( + ruleContext, picBuilder, featureConfiguration.getFeatureSpecification()); CppCompileAction picAction = picBuilder.buildAndValidate(ruleContext); env.registerAction(picAction); directOutputs.add(picAction.getOutputFile()); @@ -879,7 +881,8 @@ public final class CppModel { builder.setDwoFile(noPicDwoFile); builder.setLTOIndexingFile(ltoIndexingFile); - semantics.finalizeCompileActionBuilder(ruleContext, builder); + semantics.finalizeCompileActionBuilder( + ruleContext, builder, featureConfiguration.getFeatureSpecification()); CppCompileAction compileAction = builder.buildAndValidate(ruleContext); env.registerAction(compileAction); Artifact objectFile = compileAction.getOutputFile(); @@ -919,7 +922,8 @@ public final class CppModel { /*ltoIndexingFile=*/ null, builder.getContext().getCppModuleMap(), source.getBuildVariables()); - semantics.finalizeCompileActionBuilder(ruleContext, builder); + semantics.finalizeCompileActionBuilder( + ruleContext, builder, featureConfiguration.getFeatureSpecification()); CppCompileActionTemplate actionTemplate = new CppCompileActionTemplate( sourceArtifact, outputFiles, @@ -965,7 +969,8 @@ public final class CppModel { /*ltoIndexingFile=*/ null, builder.getContext().getCppModuleMap(), ImmutableMap.<String, String>of()); - semantics.finalizeCompileActionBuilder(ruleContext, builder); + semantics.finalizeCompileActionBuilder( + ruleContext, builder, featureConfiguration.getFeatureSpecification()); CppCompileAction action = builder.buildAndValidate(ruleContext); env.registerAction(action); if (addObject) { @@ -1301,7 +1306,8 @@ public final class CppModel { /*ltoIndexingFile=*/ null, builder.getContext().getCppModuleMap(), ImmutableMap.<String, String>of()); - semantics.finalizeCompileActionBuilder(ruleContext, dBuilder); + semantics.finalizeCompileActionBuilder( + ruleContext, dBuilder, featureConfiguration.getFeatureSpecification()); CppCompileAction dAction = dBuilder.buildAndValidate(ruleContext); ruleContext.registerAction(dAction); @@ -1318,7 +1324,8 @@ public final class CppModel { /*ltoIndexingFile=*/ null, builder.getContext().getCppModuleMap(), ImmutableMap.<String, String>of()); - semantics.finalizeCompileActionBuilder(ruleContext, sdBuilder); + semantics.finalizeCompileActionBuilder( + ruleContext, sdBuilder, featureConfiguration.getFeatureSpecification()); CppCompileAction sdAction = sdBuilder.buildAndValidate(ruleContext); ruleContext.registerAction(sdAction); diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppSemantics.java index 4f3a9c12eb..dfdafb6ded 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppSemantics.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppSemantics.java @@ -38,7 +38,9 @@ public interface CppSemantics { * minute. */ void finalizeCompileActionBuilder( - RuleContext ruleContext, CppCompileActionBuilder actionBuilder); + RuleContext ruleContext, + CppCompileActionBuilder actionBuilder, + FeatureSpecification featureSpecification); /** * Called before {@link CppCompilationContext}s are finalized. diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/FeatureSpecification.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/FeatureSpecification.java new file mode 100644 index 0000000000..dfc563165b --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/FeatureSpecification.java @@ -0,0 +1,36 @@ +// Copyright 2014 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.cpp; + +import com.google.auto.value.AutoValue; +import com.google.common.collect.ImmutableSet; + +/** + * Object encapsulating which additional toolchain features should be enabled and/or disabled. + */ +@AutoValue +public abstract class FeatureSpecification { + + public static final FeatureSpecification EMPTY = + create(ImmutableSet.<String>of(), ImmutableSet.<String>of()); + + public static final FeatureSpecification create( + ImmutableSet<String> requestedFeatures, ImmutableSet<String> unsupportedFeatures) { + return new AutoValue_FeatureSpecification(requestedFeatures, unsupportedFeatures); + } + + public abstract ImmutableSet<String> getRequestedFeatures(); + + public abstract ImmutableSet<String> getUnsupportedFeatures(); +} diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java index 0d44e352ed..be5a99d5e4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/proto/CcProtoAspect.java @@ -51,6 +51,7 @@ import com.google.devtools.build.lib.rules.cpp.CppConfiguration; import com.google.devtools.build.lib.rules.cpp.CppHelper; import com.google.devtools.build.lib.rules.cpp.CppRuleClasses; import com.google.devtools.build.lib.rules.cpp.CppSemantics; +import com.google.devtools.build.lib.rules.cpp.FeatureSpecification; import com.google.devtools.build.lib.rules.proto.ProtoCommon; import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder; import com.google.devtools.build.lib.rules.proto.ProtoCompileActionBuilder.ToolchainInvocation; @@ -217,8 +218,7 @@ public class CcProtoAspect extends NativeAspectClass implements ConfiguredAspect FeatureConfiguration featureConfiguration = CcCommon.configureFeatures( ruleContext, - requestedFeatures.build(), - unsupportedFeatures.build(), + FeatureSpecification.create(requestedFeatures.build(), unsupportedFeatures.build()), CcLibraryHelper.SourceCategory.CC, ccToolchain(ruleContext)); return featureConfiguration; diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java b/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java index 50bceaa339..cb22ab4bfd 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/CrosstoolCompilationSupport.java @@ -53,6 +53,7 @@ import com.google.devtools.build.lib.rules.cpp.CppLinkAction; import com.google.devtools.build.lib.rules.cpp.CppLinkActionBuilder; import com.google.devtools.build.lib.rules.cpp.CppRuleClasses; import com.google.devtools.build.lib.rules.cpp.FdoSupportProvider; +import com.google.devtools.build.lib.rules.cpp.FeatureSpecification; import com.google.devtools.build.lib.rules.cpp.IncludeProcessing; import com.google.devtools.build.lib.rules.cpp.Link.LinkStaticness; import com.google.devtools.build.lib.rules.cpp.Link.LinkTargetType; @@ -454,8 +455,8 @@ public class CrosstoolCompilationSupport extends CompilationSupport { private static FeatureConfiguration getFeatureConfiguration(RuleContext ruleContext, BuildConfiguration configuration) { - ImmutableList.Builder<String> activatedCrosstoolSelectables = - ImmutableList.<String>builder() + ImmutableSet.Builder<String> activatedCrosstoolSelectables = + ImmutableSet.<String>builder() .addAll(ACTIVATED_ACTIONS) .addAll( ruleContext @@ -514,7 +515,9 @@ public class CrosstoolCompilationSupport extends CompilationSupport { return configuration .getFragment(CppConfiguration.class) .getFeatures() - .getFeatureConfiguration(activatedCrosstoolSelectables.build()); + .getFeatureConfiguration( + FeatureSpecification.create( + activatedCrosstoolSelectables.build(), ImmutableSet.<String>of())); } private static ImmutableList<Artifact> getObjFiles( diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java index 8b725dc850..51d4c7c9a6 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcCppSemantics.java @@ -31,6 +31,7 @@ import com.google.devtools.build.lib.rules.cpp.CppConfiguration; import com.google.devtools.build.lib.rules.cpp.CppConfiguration.HeadersCheckingMode; import com.google.devtools.build.lib.rules.cpp.CppFileTypes; import com.google.devtools.build.lib.rules.cpp.CppSemantics; +import com.google.devtools.build.lib.rules.cpp.FeatureSpecification; import com.google.devtools.build.lib.rules.cpp.HeaderDiscovery.DotdPruningMode; import com.google.devtools.build.lib.rules.cpp.IncludeProcessing; import com.google.devtools.build.lib.util.FileTypeSet; @@ -94,7 +95,9 @@ public class ObjcCppSemantics implements CppSemantics { @Override public void finalizeCompileActionBuilder( - RuleContext ruleContext, CppCompileActionBuilder actionBuilder) { + RuleContext ruleContext, + CppCompileActionBuilder actionBuilder, + FeatureSpecification featureSpecification) { actionBuilder.setCppConfiguration(ruleContext.getFragment(CppConfiguration.class)); actionBuilder.setActionContext(CppCompileActionContext.class); // Because Bazel does not support include scanning, we need the entire crosstool filegroup, diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java index a697c6ec76..4d6109fe9a 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcToolchainFeaturesTest.java @@ -40,7 +40,6 @@ import com.google.devtools.build.lib.testutil.TestUtils; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.build.lib.view.config.crosstool.CrosstoolConfig.CToolchain; import com.google.protobuf.TextFormat; -import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; @@ -95,7 +94,7 @@ public class CcToolchainFeaturesTest { private Set<String> getEnabledFeatures(CcToolchainFeatures features, String... requestedFeatures) throws Exception { FeatureConfiguration configuration = - features.getFeatureConfiguration(Arrays.asList(requestedFeatures)); + features.getFeatureConfiguration(assumptionsFor(requestedFeatures)); ImmutableSet.Builder<String> enabledFeatures = ImmutableSet.builder(); for (String feature : features.getActivatableNames()) { if (configuration.isEnabled(feature)) { @@ -105,47 +104,61 @@ public class CcToolchainFeaturesTest { return enabledFeatures.build(); } + private FeatureSpecification assumptionsFor(String... requestedFeatures) { + return FeatureSpecification.create( + ImmutableSet.copyOf(requestedFeatures), ImmutableSet.<String>of()); + } + @Test public void testUnconditionalFeature() throws Exception { - assertThat(buildFeatures("").getFeatureConfiguration("a") - .isEnabled("a")).isFalse(); - assertThat(buildFeatures("feature { name: 'a' }").getFeatureConfiguration("b") - .isEnabled("a")).isFalse(); - assertThat(buildFeatures("feature { name: 'a' }").getFeatureConfiguration("a") - .isEnabled("a")).isTrue(); + assertThat(buildFeatures("").getFeatureConfiguration(assumptionsFor("a")).isEnabled("a")) + .isFalse(); + assertThat( + buildFeatures("feature { name: 'a' }") + .getFeatureConfiguration(assumptionsFor("b")) + .isEnabled("a")) + .isFalse(); + assertThat( + buildFeatures("feature { name: 'a' }") + .getFeatureConfiguration(assumptionsFor("a")) + .isEnabled("a")) + .isTrue(); } @Test public void testUnsupportedAction() throws Exception { - FeatureConfiguration configuration = buildFeatures("").getFeatureConfiguration(); + FeatureConfiguration configuration = + buildFeatures("").getFeatureConfiguration(assumptionsFor()); assertThat(configuration.getCommandLine("invalid-action", createVariables())).isEmpty(); } @Test public void testFlagOrderEqualsSpecOrder() throws Exception { - FeatureConfiguration configuration = buildFeatures( - "feature {", - " name: 'a'", - " flag_set {", - " action: 'c++-compile'", - " flag_group { flag: '-a-c++-compile' }", - " }", - " flag_set {", - " action: 'link'", - " flag_group { flag: '-a-c++-compile' }", - " }", - "}", - "feature {", - " name: 'b'", - " flag_set {", - " action: 'c++-compile'", - " flag_group { flag: '-b-c++-compile' }", - " }", - " flag_set {", - " action: 'link'", - " flag_group { flag: '-b-link' }", - " }", - "}").getFeatureConfiguration("a", "b"); + FeatureConfiguration configuration = + buildFeatures( + "feature {", + " name: 'a'", + " flag_set {", + " action: 'c++-compile'", + " flag_group { flag: '-a-c++-compile' }", + " }", + " flag_set {", + " action: 'link'", + " flag_group { flag: '-a-c++-compile' }", + " }", + "}", + "feature {", + " name: 'b'", + " flag_set {", + " action: 'c++-compile'", + " flag_group { flag: '-b-c++-compile' }", + " }", + " flag_set {", + " action: 'link'", + " flag_group { flag: '-b-link' }", + " }", + "}") + .getFeatureConfiguration(assumptionsFor("a", "b")); List<String> commandLine = configuration.getCommandLine( CppCompileAction.CPP_COMPILE, createVariables()); assertThat(commandLine).containsExactly("-a-c++-compile", "-b-c++-compile").inOrder(); @@ -153,33 +166,35 @@ public class CcToolchainFeaturesTest { @Test public void testEnvVars() throws Exception { - FeatureConfiguration configuration = buildFeatures( - "feature {", - " name: 'a'", - " env_set {", - " action: 'c++-compile'", - " env_entry { key: 'foo', value: 'bar' }", - " env_entry { key: 'cat', value: 'meow' }", - " }", - " flag_set {", - " action: 'c++-compile'", - " flag_group { flag: '-a-c++-compile' }", - " }", - "}", - "feature {", - " name: 'b'", - " env_set {", - " action: 'c++-compile'", - " env_entry { key: 'dog', value: 'woof' }", - " }", - "}", - "feature {", - " name: 'c'", - " env_set {", - " action: 'c++-compile'", - " env_entry { key: 'doNotInclude', value: 'doNotIncludePlease' }", - " }", - "}").getFeatureConfiguration("a", "b"); + FeatureConfiguration configuration = + buildFeatures( + "feature {", + " name: 'a'", + " env_set {", + " action: 'c++-compile'", + " env_entry { key: 'foo', value: 'bar' }", + " env_entry { key: 'cat', value: 'meow' }", + " }", + " flag_set {", + " action: 'c++-compile'", + " flag_group { flag: '-a-c++-compile' }", + " }", + "}", + "feature {", + " name: 'b'", + " env_set {", + " action: 'c++-compile'", + " env_entry { key: 'dog', value: 'woof' }", + " }", + "}", + "feature {", + " name: 'c'", + " env_set {", + " action: 'c++-compile'", + " env_entry { key: 'doNotInclude', value: 'doNotIncludePlease' }", + " }", + "}") + .getFeatureConfiguration(assumptionsFor("a", "b")); Map<String, String> env = configuration.getEnvironmentVariables( CppCompileAction.CPP_COMPILE, createVariables()); assertThat(env).containsExactly("foo", "bar", "cat", "meow", "dog", "woof").inOrder(); @@ -192,14 +207,16 @@ public class CcToolchainFeaturesTest { private List<String> getCommandLineForFlagGroups(String groups, Variables variables) throws Exception { - FeatureConfiguration configuration = buildFeatures( - "feature {", - " name: 'a'", - " flag_set {", - " action: 'c++-compile'", - " " + groups, - " }", - "}").getFeatureConfiguration("a"); + FeatureConfiguration configuration = + buildFeatures( + "feature {", + " name: 'a'", + " flag_set {", + " action: 'c++-compile'", + " " + groups, + " }", + "}") + .getFeatureConfiguration(assumptionsFor("a")); return configuration.getCommandLine(CppCompileAction.CPP_COMPILE, variables); } @@ -997,7 +1014,7 @@ public class CcToolchainFeaturesTest { " flag_group { flag: 'unconditional' }", " }", "}") - .getFeatureConfiguration("a"); + .getFeatureConfiguration(assumptionsFor("a")); assertThat(configuration.getCommandLine(CppCompileAction.CPP_COMPILE, createVariables())) .containsExactly("unconditional"); @@ -1031,14 +1048,20 @@ public class CcToolchainFeaturesTest { "}", "feature { name: 'b' implies: 'a' }"); assertThat(getEnabledFeatures(features, "b")).containsExactly("a", "b"); - assertThat(features.getFeatureConfiguration("b").getCommandLine(CppCompileAction.CPP_COMPILE, - createVariables("v", "1"))).containsExactly("-f", "1"); + assertThat( + features + .getFeatureConfiguration(assumptionsFor("b")) + .getCommandLine(CppCompileAction.CPP_COMPILE, createVariables("v", "1"))) + .containsExactly("-f", "1"); byte[] serialized = TestUtils.serializeObject(features); CcToolchainFeatures deserialized = (CcToolchainFeatures) TestUtils.deserializeObject(serialized); assertThat(getEnabledFeatures(deserialized, "b")).containsExactly("a", "b"); - assertThat(features.getFeatureConfiguration("b").getCommandLine(CppCompileAction.CPP_COMPILE, - createVariables("v", "1"))).containsExactly("-f", "1"); + assertThat( + features + .getFeatureConfiguration(assumptionsFor("b")) + .getCommandLine(CppCompileAction.CPP_COMPILE, createVariables("v", "1"))) + .containsExactly("-f", "1"); } @Test @@ -1065,12 +1088,12 @@ public class CcToolchainFeaturesTest { "feature {name: 'b'}"); assertThat( features - .getFeatureConfiguration("a", "b") + .getFeatureConfiguration(assumptionsFor("a", "b")) .getCommandLine(CppCompileAction.CPP_COMPILE, createVariables())) .containsExactly("dummy_flag"); assertThat( features - .getFeatureConfiguration("a") + .getFeatureConfiguration(assumptionsFor("a")) .getCommandLine(CppCompileAction.CPP_COMPILE, createVariables())) .doesNotContain("dummy_flag"); } @@ -1093,17 +1116,17 @@ public class CcToolchainFeaturesTest { "feature {name: 'c'}"); assertThat( features - .getFeatureConfiguration("a", "b", "c") + .getFeatureConfiguration(assumptionsFor("a", "b", "c")) .getCommandLine(CppCompileAction.CPP_COMPILE, createVariables())) .containsExactly("dummy_flag"); assertThat( features - .getFeatureConfiguration("a", "b") + .getFeatureConfiguration(assumptionsFor("a", "b")) .getCommandLine(CppCompileAction.CPP_COMPILE, createVariables())) .doesNotContain("dummy_flag"); assertThat( features - .getFeatureConfiguration("a") + .getFeatureConfiguration(assumptionsFor("a")) .getCommandLine(CppCompileAction.CPP_COMPILE, createVariables())) .doesNotContain("dummy_flag"); } @@ -1129,17 +1152,17 @@ public class CcToolchainFeaturesTest { "feature {name: 'c2'}"); assertThat( features - .getFeatureConfiguration("a", "b1", "c1", "b2", "c2") + .getFeatureConfiguration(assumptionsFor("a", "b1", "c1", "b2", "c2")) .getCommandLine(CppCompileAction.CPP_COMPILE, createVariables())) .containsExactly("dummy_flag"); assertThat( features - .getFeatureConfiguration("a", "b1", "c1") + .getFeatureConfiguration(assumptionsFor("a", "b1", "c1")) .getCommandLine(CppCompileAction.CPP_COMPILE, createVariables())) .containsExactly("dummy_flag"); assertThat( features - .getFeatureConfiguration("a", "b1", "b2") + .getFeatureConfiguration(assumptionsFor("a", "b1", "b2")) .getCommandLine(CppCompileAction.CPP_COMPILE, createVariables())) .doesNotContain("dummy_flag"); } @@ -1162,7 +1185,7 @@ public class CcToolchainFeaturesTest { "}"); FeatureConfiguration featureConfiguration = - toolchainFeatures.getFeatureConfiguration("activates-action-a"); + toolchainFeatures.getFeatureConfiguration(assumptionsFor("activates-action-a")); assertThat(featureConfiguration.actionIsConfigured("action-a")).isTrue(); } @@ -1185,11 +1208,11 @@ public class CcToolchainFeaturesTest { "}"); FeatureConfiguration featureConfigurationWithoutAction = - toolchainFeatures.getFeatureConfiguration("requires-action-a"); + toolchainFeatures.getFeatureConfiguration(assumptionsFor("requires-action-a")); assertThat(featureConfigurationWithoutAction.isEnabled("requires-action-a")).isFalse(); FeatureConfiguration featureConfigurationWithAction = - toolchainFeatures.getFeatureConfiguration("action-a", "requires-action-a"); + toolchainFeatures.getFeatureConfiguration(assumptionsFor("action-a", "requires-action-a")); assertThat(featureConfigurationWithAction.isEnabled("requires-action-a")).isTrue(); } @@ -1208,7 +1231,7 @@ public class CcToolchainFeaturesTest { " name: 'activates-action-a'", " implies: 'action-a'", "}") - .getFeatureConfiguration("activates-action-a"); + .getFeatureConfiguration(assumptionsFor("activates-action-a")); PathFragment crosstoolPath = PathFragment.create("crosstool/"); PathFragment toolPath = configuration.getToolForAction("action-a").getToolPath(crosstoolPath); assertThat(toolPath.toString()).isEqualTo("crosstool/toolchain/a"); @@ -1254,7 +1277,8 @@ public class CcToolchainFeaturesTest { PathFragment crosstoolPath = PathFragment.create("crosstool/"); FeatureConfiguration featureAConfiguration = - toolchainFeatures.getFeatureConfiguration("feature-a", "activates-action-a"); + toolchainFeatures.getFeatureConfiguration( + assumptionsFor("feature-a", "activates-action-a")); assertThat( featureAConfiguration .getToolForAction("action-a") @@ -1263,7 +1287,8 @@ public class CcToolchainFeaturesTest { .isEqualTo("crosstool/toolchain/feature-a"); FeatureConfiguration featureBConfiguration = - toolchainFeatures.getFeatureConfiguration("feature-b", "activates-action-a"); + toolchainFeatures.getFeatureConfiguration( + assumptionsFor("feature-b", "activates-action-a")); assertThat( featureBConfiguration .getToolForAction("action-a") @@ -1272,7 +1297,8 @@ public class CcToolchainFeaturesTest { .isEqualTo("crosstool/toolchain/feature-b"); FeatureConfiguration featureAAndBConfiguration = - toolchainFeatures.getFeatureConfiguration("feature-a", "feature-b", "activates-action-a"); + toolchainFeatures.getFeatureConfiguration( + assumptionsFor("feature-a", "feature-b", "activates-action-a")); assertThat( featureAAndBConfiguration .getToolForAction("action-a") @@ -1281,7 +1307,7 @@ public class CcToolchainFeaturesTest { .isEqualTo("crosstool/toolchain/features-a-and-b"); FeatureConfiguration noFeaturesConfiguration = - toolchainFeatures.getFeatureConfiguration("activates-action-a"); + toolchainFeatures.getFeatureConfiguration(assumptionsFor("activates-action-a")); assertThat( noFeaturesConfiguration .getToolForAction("action-a") @@ -1313,7 +1339,7 @@ public class CcToolchainFeaturesTest { PathFragment crosstoolPath = PathFragment.create("crosstool/"); FeatureConfiguration noFeaturesConfiguration = - toolchainFeatures.getFeatureConfiguration("activates-action-a"); + toolchainFeatures.getFeatureConfiguration(assumptionsFor("activates-action-a")); try { noFeaturesConfiguration.getToolForAction("action-a").getToolPath(crosstoolPath); @@ -1339,7 +1365,7 @@ public class CcToolchainFeaturesTest { "}"); FeatureConfiguration featureConfiguration = - toolchainFeatures.getFeatureConfiguration("action-a"); + toolchainFeatures.getFeatureConfiguration(assumptionsFor("action-a")); assertThat(featureConfiguration.actionIsConfigured("action-a")).isTrue(); } @@ -1362,7 +1388,7 @@ public class CcToolchainFeaturesTest { "}"); FeatureConfiguration featureConfiguration = - toolchainFeatures.getFeatureConfiguration("action-a"); + toolchainFeatures.getFeatureConfiguration(assumptionsFor("action-a")); assertThat(featureConfiguration.isEnabled("activated-feature")).isTrue(); } @@ -1416,7 +1442,7 @@ public class CcToolchainFeaturesTest { " flag_group {flag: 'foo'}", " }", "}") - .getFeatureConfiguration("c++-compile"); + .getFeatureConfiguration(assumptionsFor("c++-compile")); List<String> commandLine = featureConfiguration.getCommandLine("c++-compile", createVariables()); assertThat(commandLine).contains("foo"); @@ -1435,7 +1461,7 @@ public class CcToolchainFeaturesTest { " flag_group {flag: 'foo'}", " }", "}") - .getFeatureConfiguration("c++-compile"); + .getFeatureConfiguration(assumptionsFor("c++-compile")); fail("Should throw InvalidConfigurationException"); } catch (InvalidConfigurationException e) { assertThat(e) @@ -1475,14 +1501,16 @@ public class CcToolchainFeaturesTest { public void testProvidesCollision() throws Exception { try { buildFeatures( - "feature {", - " name: 'a'", - " provides: 'provides_string'", - "}", - "feature {", - " name: 'b'", - " provides: 'provides_string'", - "}").getFeatureConfiguration("a", "b"); + "feature {", + " name: 'a'", + " provides: 'provides_string'", + "}", + "feature {", + " name: 'b'", + " provides: 'provides_string'", + "}") + .getFeatureConfiguration( + FeatureSpecification.create(ImmutableSet.of("a", "b"), ImmutableSet.<String>of())); fail("Should throw CollidingProvidesException on collision, instead did not throw."); } catch (Exception e) { assertThat(e).hasMessageThat().contains("a b"); diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java index 20814450e6..fb8ebbbe8f 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppLinkActionTest.java @@ -89,12 +89,15 @@ public class CppLinkActionTest extends BuildViewTestCase { "dynamic_library_linker_tool", true)) .getFeatureConfiguration( - Link.LinkTargetType.EXECUTABLE.getActionName(), - Link.LinkTargetType.DYNAMIC_LIBRARY.getActionName(), - Link.LinkTargetType.STATIC_LIBRARY.getActionName(), - Link.LinkTargetType.PIC_STATIC_LIBRARY.getActionName(), - Link.LinkTargetType.ALWAYS_LINK_STATIC_LIBRARY.getActionName(), - Link.LinkTargetType.ALWAYS_LINK_PIC_STATIC_LIBRARY.getActionName()); + FeatureSpecification.create( + ImmutableSet.of( + Link.LinkTargetType.EXECUTABLE.getActionName(), + Link.LinkTargetType.DYNAMIC_LIBRARY.getActionName(), + Link.LinkTargetType.STATIC_LIBRARY.getActionName(), + Link.LinkTargetType.PIC_STATIC_LIBRARY.getActionName(), + Link.LinkTargetType.ALWAYS_LINK_STATIC_LIBRARY.getActionName(), + Link.LinkTargetType.ALWAYS_LINK_PIC_STATIC_LIBRARY.getActionName()), + ImmutableSet.<String>of())); } @Test @@ -115,7 +118,10 @@ public class CppLinkActionTest extends BuildViewTestCase { " tool_path: 'toolchain/mock_tool'", " }", "}") - .getFeatureConfiguration("a", Link.LinkTargetType.EXECUTABLE.getActionName()); + .getFeatureConfiguration( + FeatureSpecification.create( + ImmutableSet.of("a", Link.LinkTargetType.EXECUTABLE.getActionName()), + ImmutableSet.<String>of())); CppLinkAction linkAction = createLinkBuilder( @@ -233,7 +239,8 @@ public class CppLinkActionTest extends BuildViewTestCase { " env_entry { key: 'foo', value: 'bar' }", " }", "}") - .getFeatureConfiguration("a"); + .getFeatureConfiguration( + FeatureSpecification.create(ImmutableSet.of("a"), ImmutableSet.<String>of())); CppLinkAction linkAction = createLinkBuilder( @@ -568,9 +575,12 @@ public class CppLinkActionTest extends BuildViewTestCase { " implies: 'dynamic_library_linker_tool'", "}") .getFeatureConfiguration( - "build_interface_libraries", - "dynamic_library_linker_tool", - LinkTargetType.DYNAMIC_LIBRARY.getActionName()); + FeatureSpecification.create( + ImmutableSet.of( + "build_interface_libraries", + "dynamic_library_linker_tool", + LinkTargetType.DYNAMIC_LIBRARY.getActionName()), + ImmutableSet.<String>of())); CppLinkActionBuilder builder = createLinkBuilder( LinkTargetType.DYNAMIC_LIBRARY, diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/LinkBuildVariablesTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/LinkBuildVariablesTest.java index 004347cdc9..fcdbdaf87b 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/LinkBuildVariablesTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/LinkBuildVariablesTest.java @@ -16,6 +16,7 @@ package com.google.devtools.build.lib.rules.cpp; import static com.google.common.truth.Truth.assertThat; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.ConfiguredTarget; @@ -78,7 +79,8 @@ public class LinkBuildVariablesTest extends BuildViewTestCase { " }", " }", "}") - .getFeatureConfiguration("a"); + .getFeatureConfiguration( + FeatureSpecification.create(ImmutableSet.of("a"), ImmutableSet.<String>of())); return mockFeatureConfiguration.getCommandLine("foo", variables); } |