Damien Martin-Guillerez | f88f4d8 | 2015-09-25 13:56:55 +0000 | [diff] [blame] | 1 | // Copyright 2014 The Bazel Authors. All rights reserved. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | package com.google.devtools.build.lib.analysis; |
| 16 | |
| 17 | import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.DATA; |
| 18 | import static com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition.HOST; |
| 19 | import static com.google.devtools.build.lib.packages.Attribute.attr; |
Lukacs Berki | ffa73ad | 2015-09-18 11:40:12 +0000 | [diff] [blame] | 20 | import static com.google.devtools.build.lib.packages.BuildType.DISTRIBUTIONS; |
| 21 | import static com.google.devtools.build.lib.packages.BuildType.LABEL; |
| 22 | import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; |
| 23 | import static com.google.devtools.build.lib.packages.BuildType.LICENSE; |
| 24 | import static com.google.devtools.build.lib.packages.BuildType.NODEP_LABEL_LIST; |
| 25 | import static com.google.devtools.build.lib.syntax.Type.BOOLEAN; |
| 26 | import static com.google.devtools.build.lib.syntax.Type.INTEGER; |
| 27 | import static com.google.devtools.build.lib.syntax.Type.STRING; |
| 28 | import static com.google.devtools.build.lib.syntax.Type.STRING_LIST; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 29 | |
Carmi Grushko | eaaa9d0d | 2015-11-17 01:54:45 +0000 | [diff] [blame] | 30 | import com.google.common.annotations.VisibleForTesting; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 31 | import com.google.common.collect.ImmutableList; |
gregce | 490b095 | 2017-07-06 18:44:38 -0400 | [diff] [blame] | 32 | import com.google.common.collect.ImmutableMap; |
Ulf Adams | 37590dc | 2016-10-14 11:52:00 +0000 | [diff] [blame] | 33 | import com.google.common.collect.ImmutableSet; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 34 | import com.google.devtools.build.lib.analysis.config.BuildConfiguration; |
gregce | 490b095 | 2017-07-06 18:44:38 -0400 | [diff] [blame] | 35 | import com.google.devtools.build.lib.analysis.config.DynamicTransitionMapper; |
| 36 | import com.google.devtools.build.lib.analysis.config.HostTransition; |
| 37 | import com.google.devtools.build.lib.analysis.config.PatchTransition; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 38 | import com.google.devtools.build.lib.analysis.config.RunUnder; |
| 39 | import com.google.devtools.build.lib.analysis.constraints.EnvironmentRule; |
ulfjack | ab21d18 | 2017-08-10 15:36:14 +0200 | [diff] [blame] | 40 | import com.google.devtools.build.lib.analysis.test.TestConfiguration; |
Lukacs Berki | 6e91eb9 | 2015-09-21 09:12:37 +0000 | [diff] [blame] | 41 | import com.google.devtools.build.lib.cmdline.Label; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 42 | import com.google.devtools.build.lib.packages.Attribute; |
| 43 | import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel; |
| 44 | import com.google.devtools.build.lib.packages.Attribute.LateBoundLabelList; |
gregce | 490b095 | 2017-07-06 18:44:38 -0400 | [diff] [blame] | 45 | import com.google.devtools.build.lib.packages.Attribute.Transition; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 46 | import com.google.devtools.build.lib.packages.AttributeMap; |
| 47 | import com.google.devtools.build.lib.packages.Rule; |
| 48 | import com.google.devtools.build.lib.packages.RuleClass; |
| 49 | import com.google.devtools.build.lib.packages.RuleClass.Builder; |
| 50 | import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; |
| 51 | import com.google.devtools.build.lib.packages.TestSize; |
Lukacs Berki | ffa73ad | 2015-09-18 11:40:12 +0000 | [diff] [blame] | 52 | import com.google.devtools.build.lib.syntax.Type; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 53 | import com.google.devtools.build.lib.util.FileTypeSet; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 54 | import java.util.List; |
| 55 | |
| 56 | /** |
| 57 | * Rule class definitions used by (almost) every rule. |
| 58 | */ |
| 59 | public class BaseRuleClasses { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 60 | private static final Attribute.ComputedDefault testonlyDefault = |
| 61 | new Attribute.ComputedDefault() { |
| 62 | @Override |
| 63 | public Object getDefault(AttributeMap rule) { |
| 64 | return rule.getPackageDefaultTestOnly(); |
| 65 | } |
| 66 | }; |
| 67 | |
| 68 | private static final Attribute.ComputedDefault deprecationDefault = |
| 69 | new Attribute.ComputedDefault() { |
| 70 | @Override |
| 71 | public Object getDefault(AttributeMap rule) { |
| 72 | return rule.getPackageDefaultDeprecation(); |
| 73 | } |
| 74 | }; |
| 75 | |
| 76 | /** |
| 77 | * Implementation for the :action_listener attribute. |
| 78 | */ |
Carmi Grushko | eaaa9d0d | 2015-11-17 01:54:45 +0000 | [diff] [blame] | 79 | @VisibleForTesting |
| 80 | static final LateBoundLabelList<BuildConfiguration> ACTION_LISTENER = |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 81 | new LateBoundLabelList<BuildConfiguration>() { |
| 82 | @Override |
Lukacs Berki | 0dbe07f | 2016-04-19 10:22:08 +0000 | [diff] [blame] | 83 | public List<Label> resolve(Rule rule, AttributeMap attributes, |
Greg Estren | 33ec191 | 2016-02-10 15:57:58 +0000 | [diff] [blame] | 84 | BuildConfiguration configuration) { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 85 | // action_listeners are special rules; they tell the build system to add extra_actions to |
| 86 | // existing rules. As such they need an edge to every ConfiguredTarget with the limitation |
| 87 | // that they only run on the target configuration and should not operate on action_listeners |
| 88 | // and extra_actions themselves (to avoid cycles). |
| 89 | return configuration.getActionListeners(); |
| 90 | } |
| 91 | }; |
| 92 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 93 | /** |
| 94 | * Implementation for the :run_under attribute. |
| 95 | */ |
Lukacs Berki | 8f460f3 | 2016-06-29 09:14:10 +0000 | [diff] [blame] | 96 | public static final LateBoundLabel<BuildConfiguration> RUN_UNDER = |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 97 | new LateBoundLabel<BuildConfiguration>() { |
| 98 | @Override |
Lukacs Berki | 0dbe07f | 2016-04-19 10:22:08 +0000 | [diff] [blame] | 99 | public Label resolve(Rule rule, AttributeMap attributes, |
Greg Estren | 33ec191 | 2016-02-10 15:57:58 +0000 | [diff] [blame] | 100 | BuildConfiguration configuration) { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 101 | RunUnder runUnder = configuration.getRunUnder(); |
| 102 | return runUnder == null ? null : runUnder.getLabel(); |
| 103 | } |
| 104 | }; |
| 105 | |
| 106 | /** |
| 107 | * A base rule for all test rules. |
| 108 | */ |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 109 | public static final class TestBaseRule implements RuleDefinition { |
| 110 | @Override |
| 111 | public RuleClass build(Builder builder, RuleDefinitionEnvironment env) { |
| 112 | return builder |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 113 | .requiresConfigurationFragments(TestConfiguration.class) |
| 114 | .add( |
| 115 | attr("size", STRING) |
| 116 | .value("medium") |
| 117 | .taggable() |
| 118 | .nonconfigurable("policy decision: should be consistent across configurations")) |
| 119 | .add( |
| 120 | attr("timeout", STRING) |
| 121 | .taggable() |
| 122 | .nonconfigurable("policy decision: should be consistent across configurations") |
| 123 | .value( |
| 124 | new Attribute.ComputedDefault() { |
| 125 | @Override |
| 126 | public Object getDefault(AttributeMap rule) { |
| 127 | TestSize size = TestSize.getTestSize(rule.get("size", Type.STRING)); |
| 128 | if (size != null) { |
| 129 | String timeout = size.getDefaultTimeout().toString(); |
| 130 | if (timeout != null) { |
| 131 | return timeout; |
| 132 | } |
| 133 | } |
| 134 | return "illegal"; |
| 135 | } |
| 136 | })) |
| 137 | .add( |
| 138 | attr("flaky", BOOLEAN) |
| 139 | .value(false) |
| 140 | .taggable() |
| 141 | .nonconfigurable("policy decision: should be consistent across configurations")) |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 142 | .add(attr("shard_count", INTEGER).value(-1)) |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 143 | .add( |
| 144 | attr("local", BOOLEAN) |
| 145 | .value(false) |
| 146 | .taggable() |
| 147 | .nonconfigurable("policy decision: should be consistent across configurations")) |
Greg Estren | 547295a | 2016-08-18 22:01:29 +0000 | [diff] [blame] | 148 | .add(attr("args", STRING_LIST)) |
Lukacs Berki | 8f460f3 | 2016-06-29 09:14:10 +0000 | [diff] [blame] | 149 | // Input files for every test action |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 150 | .add( |
| 151 | attr("$test_runtime", LABEL_LIST) |
| 152 | .cfg(HOST) |
| 153 | .value(ImmutableList.of(env.getToolsLabel("//tools/test:runtime")))) |
Lukacs Berki | 8f460f3 | 2016-06-29 09:14:10 +0000 | [diff] [blame] | 154 | // Input files for test actions collecting code coverage |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 155 | .add( |
| 156 | attr("$coverage_support", LABEL) |
| 157 | .value(env.getLabel("//tools/defaults:coverage_support"))) |
Lukacs Berki | 8f460f3 | 2016-06-29 09:14:10 +0000 | [diff] [blame] | 158 | // Used in the one-per-build coverage report generation action. |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 159 | .add( |
| 160 | attr("$coverage_report_generator", LABEL) |
| 161 | .cfg(HOST) |
| 162 | .value(env.getLabel("//tools/defaults:coverage_report_generator")) |
| 163 | .singleArtifact()) |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 164 | |
| 165 | // The target itself and run_under both run on the same machine. We use the DATA config |
| 166 | // here because the run_under acts like a data dependency (e.g. no LIPO optimization). |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 167 | .add(attr(":run_under", LABEL).cfg(DATA).value(RUN_UNDER).skipPrereqValidatorCheck()) |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 168 | .build(); |
| 169 | } |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 170 | |
| 171 | @Override |
| 172 | public Metadata getMetadata() { |
| 173 | return RuleDefinition.Metadata.builder() |
| 174 | .name("$test_base_rule") |
| 175 | .type(RuleClassType.ABSTRACT) |
lberki | 3c1c8e9 | 2017-07-13 12:25:47 +0200 | [diff] [blame] | 176 | .ancestors(RootRule.class, MakeVariableExpandingRule.class) |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 177 | .build(); |
| 178 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 179 | } |
| 180 | |
| 181 | /** |
| 182 | * Share common attributes across both base and Skylark base rules. |
| 183 | */ |
| 184 | public static RuleClass.Builder commonCoreAndSkylarkAttributes(RuleClass.Builder builder) { |
cpeyser | 03755ea | 2017-08-28 22:43:32 +0200 | [diff] [blame^] | 185 | return builder |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 186 | // The visibility attribute is special: it is a nodep label, and loading the |
| 187 | // necessary package groups is handled by {@link LabelVisitor#visitTargetVisibility}. |
| 188 | // Package groups always have the null configuration so that they are not duplicated |
| 189 | // needlessly. |
cpeyser | 03755ea | 2017-08-28 22:43:32 +0200 | [diff] [blame^] | 190 | .add(attr("visibility", NODEP_LABEL_LIST).orderIndependent().cfg(HOST) |
| 191 | .nonconfigurable("special attribute integrated more deeply into Bazel's core logic")) |
| 192 | .add(attr("deprecation", STRING).value(deprecationDefault) |
| 193 | .nonconfigurable("Used in core loading phase logic with no access to configs")) |
| 194 | .add(attr("tags", STRING_LIST).orderIndependent().taggable() |
| 195 | .nonconfigurable("low-level attribute, used in TargetUtils without configurations")) |
| 196 | .add(attr("generator_name", STRING).undocumented("internal") |
| 197 | .nonconfigurable("static structure of a rule")) |
| 198 | .add(attr("generator_function", STRING).undocumented("internal") |
| 199 | .nonconfigurable("static structure of a rule")) |
| 200 | .add(attr("generator_location", STRING).undocumented("internal") |
| 201 | .nonconfigurable("static structure of a rule")) |
| 202 | .add(attr("testonly", BOOLEAN).value(testonlyDefault) |
| 203 | .nonconfigurable("policy decision: rules testability should be consistent")) |
Manuel Klimek | 6d9fb36 | 2015-04-30 12:50:55 +0000 | [diff] [blame] | 204 | .add(attr("features", STRING_LIST).orderIndependent()) |
Laurent Le Brun | d83e848 | 2015-07-13 14:34:44 +0000 | [diff] [blame] | 205 | .add(attr(":action_listener", LABEL_LIST).cfg(HOST).value(ACTION_LISTENER)) |
cpeyser | 03755ea | 2017-08-28 22:43:32 +0200 | [diff] [blame^] | 206 | .add(attr(RuleClass.COMPATIBLE_ENVIRONMENT_ATTR, LABEL_LIST) |
| 207 | .allowedRuleClasses(EnvironmentRule.RULE_NAME) |
| 208 | .cfg(Attribute.ConfigurationTransition.HOST) |
| 209 | .allowedFileTypes(FileTypeSet.NO_FILE) |
| 210 | .dontCheckConstraints() |
| 211 | .nonconfigurable("special logic for constraints and select: see ConstraintSemantics") |
| 212 | ) |
| 213 | .add(attr(RuleClass.RESTRICTED_ENVIRONMENT_ATTR, LABEL_LIST) |
| 214 | .allowedRuleClasses(EnvironmentRule.RULE_NAME) |
| 215 | .cfg(Attribute.ConfigurationTransition.HOST) |
| 216 | .allowedFileTypes(FileTypeSet.NO_FILE) |
| 217 | .dontCheckConstraints() |
| 218 | .nonconfigurable("special logic for constraints and select: see ConstraintSemantics") |
| 219 | ); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 220 | } |
| 221 | |
Googler | 015e595 | 2017-02-14 09:45:30 +0000 | [diff] [blame] | 222 | public static RuleClass.Builder nameAttribute(RuleClass.Builder builder) { |
| 223 | return builder.add(attr("name", STRING).nonconfigurable("Rule name")); |
| 224 | } |
| 225 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 226 | /** |
Googler | 015e595 | 2017-02-14 09:45:30 +0000 | [diff] [blame] | 227 | * Ancestor of every rule. |
| 228 | * |
| 229 | * <p>Adds the name attribute to every rule. |
| 230 | */ |
| 231 | public static final class RootRule implements RuleDefinition { |
| 232 | |
| 233 | @Override |
| 234 | public RuleClass build(Builder builder, RuleDefinitionEnvironment environment) { |
| 235 | return nameAttribute(builder).build(); |
| 236 | } |
| 237 | |
| 238 | @Override |
| 239 | public Metadata getMetadata() { |
| 240 | return RuleDefinition.Metadata.builder() |
| 241 | .name("$root_rule") |
| 242 | .type(RuleClassType.ABSTRACT) |
| 243 | .build(); |
| 244 | } |
| 245 | } |
| 246 | |
| 247 | /** |
| 248 | * Common parts of some rules. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 249 | */ |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 250 | public static final class BaseRule implements RuleDefinition { |
| 251 | @Override |
| 252 | public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { |
| 253 | return commonCoreAndSkylarkAttributes(builder) |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 254 | // Aggregates the labels of all {@link ConfigRuleClasses} rules this rule uses (e.g. |
| 255 | // keys for configurable attributes). This is specially populated in |
| 256 | // {@RuleClass#populateRuleAttributeValues}. |
| 257 | // |
| 258 | // This attribute is not needed for actual builds. Its main purpose is so query's |
| 259 | // proto/XML output includes the labels of config dependencies, so, e.g., depserver |
| 260 | // reverse dependency lookups remain accurate. These can't just be added to the |
| 261 | // attribute definitions proto/XML queries already output because not all attributes |
| 262 | // contain labels. |
| 263 | // |
| 264 | // Builds and Blaze-interactive queries don't need this because they find dependencies |
| 265 | // through direct Rule label visitation, which already factors these in. |
| 266 | .add(attr("$config_dependencies", LABEL_LIST) |
| 267 | .nonconfigurable("not intended for actual builds")) |
| 268 | .add(attr("licenses", LICENSE) |
| 269 | .nonconfigurable("Used in core loading phase logic with no access to configs")) |
| 270 | .add(attr("distribs", DISTRIBUTIONS) |
| 271 | .nonconfigurable("Used in core loading phase logic with no access to configs")) |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 272 | .build(); |
| 273 | } |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 274 | |
| 275 | @Override |
| 276 | public Metadata getMetadata() { |
| 277 | return RuleDefinition.Metadata.builder() |
| 278 | .name("$base_rule") |
| 279 | .type(RuleClassType.ABSTRACT) |
Googler | 015e595 | 2017-02-14 09:45:30 +0000 | [diff] [blame] | 280 | .ancestors(RootRule.class) |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 281 | .build(); |
| 282 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 283 | } |
| 284 | |
| 285 | /** |
lberki | 3c1c8e9 | 2017-07-13 12:25:47 +0200 | [diff] [blame] | 286 | * A rule that contains a {@code variables=} attribute to allow referencing Make variables. |
| 287 | */ |
| 288 | public static final class MakeVariableExpandingRule implements RuleDefinition { |
| 289 | @Override |
| 290 | public RuleClass build(Builder builder, RuleDefinitionEnvironment env) { |
| 291 | return builder |
| 292 | /* <!-- #BLAZE_RULE($make_variable_expanding_rule).ATTRIBUTE(toolchains) --> |
| 293 | The set of toolchains that supply <a href="${link make-variables}">"Make variables"</a> |
| 294 | that this target can use in some of its attributes. Some rules have toolchains whose Make |
| 295 | variables they can use by default. |
| 296 | <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ |
| 297 | .add(attr("toolchains", LABEL_LIST) |
| 298 | .allowedFileTypes(FileTypeSet.NO_FILE) |
dslomov | 375f95b | 2017-08-21 12:52:41 +0200 | [diff] [blame] | 299 | .mandatoryProviders(ImmutableList.of(MakeVariableInfo.PROVIDER.id()))) |
lberki | 3c1c8e9 | 2017-07-13 12:25:47 +0200 | [diff] [blame] | 300 | .build(); |
| 301 | } |
| 302 | |
| 303 | @Override |
| 304 | public Metadata getMetadata() { |
| 305 | return RuleDefinition.Metadata.builder() |
| 306 | .name("$make_variable_expanding_rule") |
| 307 | .type(RuleClassType.ABSTRACT) |
| 308 | .build(); |
| 309 | } |
| 310 | } |
| 311 | |
| 312 | /** |
Googler | 015e595 | 2017-02-14 09:45:30 +0000 | [diff] [blame] | 313 | * Common ancestor class for some rules. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 314 | */ |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 315 | public static final class RuleBase implements RuleDefinition { |
| 316 | @Override |
| 317 | public RuleClass build(Builder builder, RuleDefinitionEnvironment env) { |
| 318 | return builder |
| 319 | .add(attr("deps", LABEL_LIST).legacyAllowAnyFileType()) |
Greg Estren | 9d83784 | 2016-12-01 21:36:59 +0000 | [diff] [blame] | 320 | .add(attr("data", LABEL_LIST).cfg(DATA) |
| 321 | .allowedFileTypes(FileTypeSet.ANY_FILE) |
| 322 | .dontCheckConstraints()) |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 323 | .build(); |
| 324 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 325 | |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 326 | @Override |
| 327 | public Metadata getMetadata() { |
| 328 | return RuleDefinition.Metadata.builder() |
| 329 | .name("$rule") |
| 330 | .type(RuleClassType.ABSTRACT) |
| 331 | .ancestors(BaseRule.class) |
| 332 | .build(); |
| 333 | } |
| 334 | } |
Ulf Adams | 37590dc | 2016-10-14 11:52:00 +0000 | [diff] [blame] | 335 | |
| 336 | public static final ImmutableSet<String> ALLOWED_RULE_CLASSES = |
| 337 | ImmutableSet.of("filegroup", "genrule", "Fileset"); |
| 338 | |
| 339 | /** A base rule for all binary rules. */ |
| 340 | public static final class BinaryBaseRule implements RuleDefinition { |
| 341 | @Override |
| 342 | public RuleClass build(Builder builder, RuleDefinitionEnvironment env) { |
| 343 | return builder |
| 344 | .add(attr("args", STRING_LIST)) |
| 345 | .add(attr("output_licenses", LICENSE)) |
| 346 | .add( |
| 347 | attr("$is_executable", BOOLEAN) |
| 348 | .value(true) |
| 349 | .nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")) |
| 350 | .build(); |
| 351 | } |
| 352 | |
| 353 | @Override |
| 354 | public Metadata getMetadata() { |
| 355 | return RuleDefinition.Metadata.builder() |
| 356 | .name("$binary_base_rule") |
| 357 | .type(RuleClassType.ABSTRACT) |
lberki | 3c1c8e9 | 2017-07-13 12:25:47 +0200 | [diff] [blame] | 358 | .ancestors(RootRule.class, MakeVariableExpandingRule.class) |
Ulf Adams | 37590dc | 2016-10-14 11:52:00 +0000 | [diff] [blame] | 359 | .build(); |
| 360 | } |
| 361 | } |
| 362 | |
| 363 | /** Rule class for rules in error. */ |
| 364 | public static final class ErrorRule implements RuleDefinition { |
| 365 | @Override |
| 366 | public RuleClass build(Builder builder, RuleDefinitionEnvironment env) { |
| 367 | return builder.publicByDefault().build(); |
| 368 | } |
| 369 | |
| 370 | @Override |
| 371 | public Metadata getMetadata() { |
| 372 | return RuleDefinition.Metadata.builder() |
| 373 | .name("$error_rule") |
| 374 | .type(RuleClassType.ABSTRACT) |
| 375 | .ancestors(BaseRuleClasses.BaseRule.class) |
| 376 | .build(); |
| 377 | } |
| 378 | } |
gregce | 490b095 | 2017-07-06 18:44:38 -0400 | [diff] [blame] | 379 | |
| 380 | /** |
| 381 | * Declares the implementations for {@link Attribute.ConfigurationTransition} enums. |
| 382 | * |
| 383 | * <p>We can't put this in {@link Attribute} because that's in the {@code lib.packages} package, |
| 384 | * which has no access to configuration classes. |
| 385 | * |
| 386 | * <p>New transitions should extend {@link PatchTransition}, which avoids the need for this map. |
| 387 | */ |
| 388 | public static final ImmutableMap<Transition, Transition> DYNAMIC_TRANSITIONS_MAP = |
| 389 | ImmutableMap.of( |
| 390 | Attribute.ConfigurationTransition.NONE, DynamicTransitionMapper.SELF, |
| 391 | Attribute.ConfigurationTransition.NULL, DynamicTransitionMapper.SELF, |
| 392 | Attribute.ConfigurationTransition.HOST, HostTransition.INSTANCE |
| 393 | // Attribute.ConfigurationTransition.DATA is skipped because it's C++-specific. |
| 394 | // The C++ rule definitions handle its mapping. |
| 395 | ); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 396 | } |