aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigRuleClasses.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/analysis/config/ConfigRuleClasses.java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/config/ConfigRuleClasses.java204
1 files changed, 204 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigRuleClasses.java b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigRuleClasses.java
new file mode 100644
index 0000000000..6ee4ccefb5
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/ConfigRuleClasses.java
@@ -0,0 +1,204 @@
+// Copyright 2014 Google Inc. 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.config;
+
+import static com.google.devtools.build.lib.packages.Attribute.attr;
+import static com.google.devtools.build.lib.packages.Type.STRING_DICT;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.BaseRuleClasses;
+import com.google.devtools.build.lib.analysis.BlazeRule;
+import com.google.devtools.build.lib.analysis.RuleDefinition;
+import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
+import com.google.devtools.build.lib.packages.RuleClass;
+import com.google.devtools.build.lib.packages.Type;
+
+/**
+ * Definitions for rule classes that specify or manipulate configuration settings.
+ *
+ * <p>These are not "traditional" rule classes in that they can't be requested as top-level
+ * targets and don't translate input artifacts into output artifacts. Instead, they affect
+ * how *other* rules work. See individual class comments for details.
+ */
+public class ConfigRuleClasses {
+
+ private static final String NONCONFIGURABLE_ATTRIBUTE_REASON =
+ "part of a rule class that *triggers* configurable behavior";
+
+ /**
+ * Common settings for all configurability rules.
+ */
+ @BlazeRule(name = "$config_base_rule",
+ type = RuleClass.Builder.RuleClassType.ABSTRACT,
+ ancestors = { BaseRuleClasses.BaseRule.class })
+ public static final class ConfigBaseRule implements RuleDefinition {
+ @Override
+ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
+ return builder
+ .override(attr("tags", Type.STRING_LIST)
+ // No need to show up in ":all", etc. target patterns.
+ .value(ImmutableList.of("manual"))
+ .nonconfigurable(NONCONFIGURABLE_ATTRIBUTE_REASON))
+ .build();
+ }
+ }
+
+ /**
+ * A named "partial configuration setting" that specifies a set of command-line
+ * "flag=value" bindings.
+ *
+ * <p>For example:
+ * <pre>
+ * config_setting(
+ * name = 'foo',
+ * values = {
+ * 'flag1': 'aValue'
+ * 'flag2': 'bValue'
+ * })
+ * </pre>
+ *
+ * <p>declares a setting that binds command-line flag <pre>flag1</pre> to value
+ * <pre>aValue</pre> and <pre>flag2</pre> to <pre>bValue</pre>.
+ *
+ * <p>This is used by configurable attributes to determine which branch to
+ * follow based on which <pre>config_setting</pre> instance matches all its
+ * flag values in the configurable attribute owner's configuration.
+ *
+ * <p>This rule isn't accessed through the standard {@link RuleContext#getPrerequisites}
+ * interface. This is because Bazel constructs a rule's configured attribute map *before*
+ * its {@link RuleContext} is created (in fact, the map is an input to the context's
+ * constructor). And the config_settings referenced by the rule's configurable attributes are
+ * themselves inputs to that map. So Bazel has special logic to read and properly apply
+ * config_setting instances. See {@link ConfiguredTargetFunction#getConfigConditions} for details.
+ */
+ @BlazeRule(name = "config_setting",
+ type = RuleClass.Builder.RuleClassType.NORMAL,
+ ancestors = { ConfigBaseRule.class },
+ factoryClass = ConfigSetting.class)
+ public static final class ConfigSettingRule implements RuleDefinition {
+ /**
+ * The name of the attribute that declares flag bindings.
+ */
+ public static final String SETTINGS_ATTRIBUTE = "values";
+
+ @Override
+ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) {
+ return builder
+ /* <!-- #BLAZE_RULE(config_setting).ATTRIBUTE(values) -->
+ The set of configuration values that match this rule (expressed as Blaze flags)
+
+ <i>(Dictionary mapping flags to expected values, both expressed as strings;
+ mandatory)</i>
+
+ <p>This rule inherits the configuration of the configured target that
+ references it in a <code>select</code> statement. It is considered to
+ "match" a Blaze invocation if, for every entry in the dictionary, its
+ configuration matches the entry's expected value. For example
+ <code>values = {"compilation_mode": "opt"}</code> matches the invocations
+ <code>blaze build --compilation_mode=opt ...</code> and
+ <code>blaze build -c opt ...</code> on target-configured rules.
+ </p>
+
+ <p>For convenience's sake, configuration values are specified as Blaze flags (without
+ the preceding <code>"--"</code>). But keep in mind that the two are not the same. This
+ is because targets can be built in multiple configurations within the same
+ build. For example, a host configuration's "cpu" matches the value of
+ <code>--host_cpu</code>, not <code>--cpu</code>. So different instances of the
+ same <code>config_setting</code> may match the same invocation differently
+ depending on the configuration of the rule using them.
+ </p>
+
+ <p>If a flag is not explicitly set at the command line, its default value is used.
+ If a key appears multiple times in the dictionary, only the last instance is used.
+ If a key references a flag that can be set multiple times on the command line (e.g.
+ <code>blaze build --copt=foo --copt=bar --copt=baz ...</code>), a match occurs if
+ *any* of those settings match.
+ <p>
+
+ <p>This attribute cannot be empty.
+ </p>
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(attr(SETTINGS_ATTRIBUTE, STRING_DICT).mandatory()
+ .nonconfigurable(NONCONFIGURABLE_ATTRIBUTE_REASON))
+ .build();
+ }
+ }
+
+/*<!-- #BLAZE_RULE (NAME = config_setting, TYPE = OTHER, FAMILY = General)[GENERIC_RULE] -->
+
+${ATTRIBUTE_SIGNATURE}
+
+<p>
+ Matches an expected configuration state (expressed as Blaze flags) for the purpose of triggering
+ configurable attributes. See <a href="#select">select</a> for how to consume this rule and
+ <a href="#configurable-attributes">Configurable attributes</a> for an overview of
+ the general feature.
+
+${ATTRIBUTE_DEFINITION}
+
+<h4 id="config_setting_examples">Examples</h4>
+
+<p>The following matches any Blaze invocation that specifies <code>--compilation_mode=opt</code>
+ or <code>-c opt</code> (either explicitly at the command line or implicitly from .blazerc
+ files, etc.), when applied to a target configuration rule:
+</p>
+
+<pre class="code">
+config_setting(
+ name = "simple",
+ values = {"compilation_mode": "opt"}
+)
+</pre>
+
+<p>The following matches any Blaze invocation that builds for ARM and applies a custom define
+ (e.g. <code>blaze build --cpu=armeabi --define FOO=bar ...</code>), , when applied to a target
+ configuration rule:
+</p>
+
+<pre class="code">
+config_setting(
+ name = "two_conditions",
+ values = {
+ "cpu": "armeabi",
+ "define": "FOO=bar"
+ }
+)
+</pre>
+
+<h4 id="config_setting_notes">Notes</h4>
+
+<p>See <a href="#select">select</a> for policies on what happens depending on how many rules match
+ an invocation.
+</p>
+
+<p>For flags that support shorthand forms (e.g. <code>--compilation_mode</code> vs.
+ <code>-c</code>), <code>values</code> definitions must use the full form. These automatically
+ match invocations using either form.
+</p>
+
+<p>The currently endorsed method for creating custom conditions that can't be expressed through
+ dedicated build flags is through the --define flag. Use this flag with caution: it's not ideal
+ and only endorsed for lack of a currently better workaround. See the
+ <a href="#configurable-attributes">Configurable attributes</a> section for more discussion.
+</p>
+
+<p>Try to consolidate <code>config_setting</code> definitions as much as possible. In other words,
+ define <code>//common/conditions:foo</code> in one common package instead of repeating separate
+ instances in <code>//project1:foo</code>, <code>//project2:foo</code>, etc. that all mean the
+ same thing.
+</p>
+
+<!-- #END_BLAZE_RULE -->*/
+}