diff options
author | Ulf Adams <ulfjack@google.com> | 2015-08-06 11:51:17 +0000 |
---|---|---|
committer | David Chen <dzc@google.com> | 2015-08-06 22:14:04 +0000 |
commit | 71423eb5cee46874066bccdacb36169faa404118 (patch) | |
tree | 5ae8115ace8621f98cc748847871dd8f1ed3784a /src/main/java/com/google/devtools | |
parent | 082c05499d4d9c654d288416ed6afefcf81cc090 (diff) |
Refactor the missing fragment handling code to use a policy enum.
Flip the handling such that analysis failure is the default, rather than
execution failure (fail action creation).
--
MOS_MIGRATED_REVID=100020812
Diffstat (limited to 'src/main/java/com/google/devtools')
3 files changed, 49 insertions, 19 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java index f582cb62c8..b875a9db2b 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredTargetFactory.java @@ -40,6 +40,7 @@ import com.google.devtools.build.lib.packages.PackageGroupsRuleVisibility; import com.google.devtools.build.lib.packages.PackageSpecification; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.packages.RuleClass.MissingFragmentPolicy; import com.google.devtools.build.lib.packages.RuleVisibility; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.rules.SkylarkRuleConfiguredTargetBuilder; @@ -225,9 +226,12 @@ public final class ConfiguredTargetFactory { return null; } if (!rule.getRuleClassObject().getRequiredConfigurationFragments().isEmpty()) { - if (!configuration.hasAllFragments( - rule.getRuleClassObject().getRequiredConfigurationFragments())) { - if (rule.getRuleClassObject().failIfMissingConfigurationFragment()) { + MissingFragmentPolicy missingFragmentPolicy = + rule.getRuleClassObject().missingFragmentPolicy(); + if (missingFragmentPolicy != MissingFragmentPolicy.IGNORE + && !configuration.hasAllFragments( + rule.getRuleClassObject().getRequiredConfigurationFragments())) { + if (missingFragmentPolicy == MissingFragmentPolicy.FAIL_ANALYSIS) { ruleContext.ruleError(missingFragmentError(ruleContext)); return null; } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java index 63c485ef0f..dd09bea69b 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCppRuleClasses.java @@ -627,7 +627,6 @@ public class BazelCppRuleClasses { public RuleClass build(Builder builder, RuleDefinitionEnvironment env) { return builder .requiresConfigurationFragments(CppConfiguration.class) - .failIfMissingConfigurationFragment() /*<!-- #BLAZE_RULE(cc_binary).IMPLICIT_OUTPUTS --> <ul> <li><code><var>name</var>.stripped</code> (only built if explicitly requested): A stripped @@ -773,7 +772,6 @@ public class BazelCppRuleClasses { // deps, data, linkopts, defines, srcs; override here too? .requiresConfigurationFragments(CppConfiguration.class) - .failIfMissingConfigurationFragment() /*<!-- #BLAZE_RULE(cc_library).ATTRIBUTE(alwayslink) --> If 1, any binary that depends (directly or indirectly) on this C++ library will link in all the object files for the files listed in diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java index e7cbf9edec..e2bd958b48 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java @@ -183,6 +183,33 @@ public final class RuleClass { }; /** + * How to handle the case if the configuration is missing fragments that are required according + * to the rule class. + */ + public enum MissingFragmentPolicy { + /** + * Some rules are monolithic across languages, and we want them to continue to work even when + * individual languages are disabled. Use this policy if the rule implementation is handling + * missing fragments. + */ + IGNORE, + + /** + * Use this policy to generate fail actions for the target rather than failing the analysis + * outright. Again, this is used when rules are monolithic across languages, but we still need + * to analyze the dependent libraries. (Instead of this mechanism, consider annotating + * attributes as unused if certain fragments are unavailable.) + */ + CREATE_FAIL_ACTIONS, + + /** + * Use this policy to fail the analysis of that target with an error message; this is the + * default. + */ + FAIL_ANALYSIS; + } + + /** * For Bazel's constraint system: the attribute that declares the set of environments a rule * supports, overriding the defaults for their respective groups. */ @@ -461,7 +488,7 @@ public final class RuleClass { NO_EXTERNAL_BINDINGS; private SkylarkEnvironment ruleDefinitionEnvironment = null; private Set<Class<?>> configurationFragments = new LinkedHashSet<>(); - private boolean failIfMissingConfigurationFragment; + private MissingFragmentPolicy missingFragmentPolicy = MissingFragmentPolicy.FAIL_ANALYSIS; private boolean supportsConstraintChecking = true; private final Map<String, Attribute> attributes = new LinkedHashMap<>(); @@ -489,7 +516,7 @@ public final class RuleClass { setPreferredDependencyPredicate(parent.preferredDependencyPredicate); } configurationFragments.addAll(parent.requiredConfigurationFragments); - failIfMissingConfigurationFragment |= parent.failIfMissingConfigurationFragment; + missingFragmentPolicy = parent.missingFragmentPolicy; supportsConstraintChecking = parent.supportsConstraintChecking; for (Attribute attribute : parent.getAttributes()) { @@ -548,7 +575,7 @@ public final class RuleClass { configuredTargetFactory, validityPredicate, preferredDependencyPredicate, ImmutableSet.copyOf(advertisedProviders), configuredTargetFunction, externalBindingsFunction, - ruleDefinitionEnvironment, configurationFragments, failIfMissingConfigurationFragment, + ruleDefinitionEnvironment, configurationFragments, missingFragmentPolicy, supportsConstraintChecking, attributes.values().toArray(new Attribute[0])); } @@ -565,8 +592,12 @@ public final class RuleClass { return this; } - public Builder failIfMissingConfigurationFragment() { - this.failIfMissingConfigurationFragment = true; + /** + * Sets the policy for the case where the configuration is missing required fragments (see + * {@link #requiresConfigurationFragments}). + */ + public Builder setMissingFragmentPolicy(MissingFragmentPolicy missingFragmentPolicy) { + this.missingFragmentPolicy = missingFragmentPolicy; return this; } @@ -917,12 +948,9 @@ public final class RuleClass { private final ImmutableSet<Class<?>> requiredConfigurationFragments; /** - * Whether to fail during analysis if a configuration fragment is missing. The default behavior is - * to create fail actions for all declared outputs, i.e., to fail during execution, if any of the - * outputs is actually attempted to be built. + * What to do during analysis if a configuration fragment is missing. */ - private final boolean failIfMissingConfigurationFragment; - + private final MissingFragmentPolicy missingFragmentPolicy; /** * Determines whether instances of this rule should be checked for constraint compatibility @@ -965,7 +993,7 @@ public final class RuleClass { @Nullable BaseFunction configuredTargetFunction, Function<? super Rule, Map<String, Label>> externalBindingsFunction, @Nullable SkylarkEnvironment ruleDefinitionEnvironment, - Set<Class<?>> allowedConfigurationFragments, boolean failIfMissingConfigurationFragment, + Set<Class<?>> allowedConfigurationFragments, MissingFragmentPolicy missingFragmentPolicy, boolean supportsConstraintChecking, Attribute... attributes) { this.name = name; @@ -988,7 +1016,7 @@ public final class RuleClass { this.workspaceOnly = workspaceOnly; this.outputsDefaultExecutable = outputsDefaultExecutable; this.requiredConfigurationFragments = ImmutableSet.copyOf(allowedConfigurationFragments); - this.failIfMissingConfigurationFragment = failIfMissingConfigurationFragment; + this.missingFragmentPolicy = missingFragmentPolicy; this.supportsConstraintChecking = supportsConstraintChecking; // create the index: @@ -1158,8 +1186,8 @@ public final class RuleClass { /** * Whether to fail analysis if any of the required configuration fragments are missing. */ - public boolean failIfMissingConfigurationFragment() { - return failIfMissingConfigurationFragment; + public MissingFragmentPolicy missingFragmentPolicy() { + return missingFragmentPolicy; } /** |