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 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 17 | import static com.google.devtools.build.lib.packages.Attribute.attr; |
Lukacs Berki | ffa73ad | 2015-09-18 11:40:12 +0000 | [diff] [blame] | 18 | import static com.google.devtools.build.lib.packages.BuildType.DISTRIBUTIONS; |
| 19 | import static com.google.devtools.build.lib.packages.BuildType.LABEL; |
| 20 | import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; |
| 21 | import static com.google.devtools.build.lib.packages.BuildType.LICENSE; |
| 22 | import static com.google.devtools.build.lib.packages.BuildType.NODEP_LABEL_LIST; |
| 23 | import static com.google.devtools.build.lib.syntax.Type.BOOLEAN; |
| 24 | import static com.google.devtools.build.lib.syntax.Type.INTEGER; |
| 25 | import static com.google.devtools.build.lib.syntax.Type.STRING; |
| 26 | import static com.google.devtools.build.lib.syntax.Type.STRING_LIST; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 27 | |
Carmi Grushko | eaaa9d0d | 2015-11-17 01:54:45 +0000 | [diff] [blame] | 28 | import com.google.common.annotations.VisibleForTesting; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 29 | import com.google.common.collect.ImmutableList; |
Ulf Adams | 37590dc | 2016-10-14 11:52:00 +0000 | [diff] [blame] | 30 | import com.google.common.collect.ImmutableSet; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 31 | import com.google.devtools.build.lib.analysis.config.BuildConfiguration; |
gregce | 490b095 | 2017-07-06 18:44:38 -0400 | [diff] [blame] | 32 | import com.google.devtools.build.lib.analysis.config.HostTransition; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 33 | import com.google.devtools.build.lib.analysis.config.RunUnder; |
| 34 | import com.google.devtools.build.lib.analysis.constraints.EnvironmentRule; |
ulfjack | ab21d18 | 2017-08-10 15:36:14 +0200 | [diff] [blame] | 35 | import com.google.devtools.build.lib.analysis.test.TestConfiguration; |
dbabkin | 708b957 | 2018-06-07 02:31:16 -0700 | [diff] [blame] | 36 | import com.google.devtools.build.lib.cmdline.Label; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 37 | import com.google.devtools.build.lib.packages.Attribute; |
janakr | a56a6ad | 2018-02-02 15:52:22 -0800 | [diff] [blame] | 38 | import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; |
| 39 | import com.google.devtools.build.lib.packages.Attribute.LabelListLateBoundDefault; |
dbabkin | 708b957 | 2018-06-07 02:31:16 -0700 | [diff] [blame] | 40 | import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault.Resolver; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 41 | import com.google.devtools.build.lib.packages.AttributeMap; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 42 | import com.google.devtools.build.lib.packages.RuleClass; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 43 | import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; |
jcater | d7ce626 | 2018-06-13 10:17:30 -0700 | [diff] [blame] | 44 | import com.google.devtools.build.lib.packages.RuleClass.ExecutionPlatformConstraintsAllowed; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 45 | import com.google.devtools.build.lib.packages.TestSize; |
janakr | 8688b68 | 2018-03-26 09:07:11 -0700 | [diff] [blame] | 46 | import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; |
Lukacs Berki | ffa73ad | 2015-09-18 11:40:12 +0000 | [diff] [blame] | 47 | import com.google.devtools.build.lib.syntax.Type; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 48 | import com.google.devtools.build.lib.util.FileTypeSet; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 49 | |
| 50 | /** |
| 51 | * Rule class definitions used by (almost) every rule. |
| 52 | */ |
| 53 | public class BaseRuleClasses { |
janakr | 8688b68 | 2018-03-26 09:07:11 -0700 | [diff] [blame] | 54 | @AutoCodec @AutoCodec.VisibleForSerialization |
| 55 | static final Attribute.ComputedDefault testonlyDefault = |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 56 | new Attribute.ComputedDefault() { |
| 57 | @Override |
| 58 | public Object getDefault(AttributeMap rule) { |
| 59 | return rule.getPackageDefaultTestOnly(); |
| 60 | } |
| 61 | }; |
| 62 | |
janakr | 8688b68 | 2018-03-26 09:07:11 -0700 | [diff] [blame] | 63 | @AutoCodec @AutoCodec.VisibleForSerialization |
| 64 | static final Attribute.ComputedDefault deprecationDefault = |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 65 | new Attribute.ComputedDefault() { |
| 66 | @Override |
| 67 | public Object getDefault(AttributeMap rule) { |
| 68 | return rule.getPackageDefaultDeprecation(); |
| 69 | } |
| 70 | }; |
| 71 | |
mstaib | 807a9b2 | 2017-09-19 17:06:32 +0200 | [diff] [blame] | 72 | // TODO(b/65746853): provide a way to do this without passing the entire configuration |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 73 | /** |
| 74 | * Implementation for the :action_listener attribute. |
mstaib | 807a9b2 | 2017-09-19 17:06:32 +0200 | [diff] [blame] | 75 | * |
| 76 | * <p>action_listeners are special rules; they tell the build system to add extra_actions to |
| 77 | * existing rules. As such they need an edge to every ConfiguredTarget with the limitation that |
| 78 | * they only run on the target configuration and should not operate on action_listeners and |
| 79 | * extra_actions themselves (to avoid cycles). |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 80 | */ |
janakr | 8688b68 | 2018-03-26 09:07:11 -0700 | [diff] [blame] | 81 | @AutoCodec @VisibleForTesting |
janakr | a56a6ad | 2018-02-02 15:52:22 -0800 | [diff] [blame] | 82 | static final LabelListLateBoundDefault<?> ACTION_LISTENER = |
| 83 | LabelListLateBoundDefault.fromTargetConfiguration( |
mstaib | 807a9b2 | 2017-09-19 17:06:32 +0200 | [diff] [blame] | 84 | BuildConfiguration.class, |
mstaib | 807a9b2 | 2017-09-19 17:06:32 +0200 | [diff] [blame] | 85 | (rule, attributes, configuration) -> configuration.getActionListeners()); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 86 | |
dbabkin | 708b957 | 2018-06-07 02:31:16 -0700 | [diff] [blame] | 87 | public static final String DEFAULT_COVERAGE_SUPPORT_VALUE = "//tools/test:coverage_support"; |
| 88 | |
| 89 | @AutoCodec |
| 90 | static final Resolver<TestConfiguration, Label> COVERAGE_SUPPORT_CONFIGURATION_RESOLVER = |
| 91 | (rule, attributes, configuration) -> configuration.getCoverageSupport(); |
| 92 | |
| 93 | public static LabelLateBoundDefault<TestConfiguration> coverageSupportAttribute( |
| 94 | Label defaultValue) { |
| 95 | return LabelLateBoundDefault.fromTargetConfiguration( |
| 96 | TestConfiguration.class, defaultValue, COVERAGE_SUPPORT_CONFIGURATION_RESOLVER); |
| 97 | } |
| 98 | |
dbabkin | 2df3234 | 2018-06-07 05:19:54 -0700 | [diff] [blame] | 99 | public static final String DEFAULT_COVERAGE_REPORT_GENERATOR_VALUE = |
| 100 | "//tools/test:coverage_report_generator"; |
| 101 | |
| 102 | @AutoCodec |
| 103 | static final Resolver<TestConfiguration, Label> COVERAGE_REPORT_GENERATOR_CONFIGURATION_RESOLVER = |
| 104 | (rule, attributes, configuration) -> configuration.getCoverageReportGenerator(); |
| 105 | |
| 106 | public static LabelLateBoundDefault<TestConfiguration> coverageReportGeneratorAttribute( |
| 107 | Label defaultValue) { |
| 108 | return LabelLateBoundDefault.fromTargetConfiguration( |
| 109 | TestConfiguration.class, defaultValue, COVERAGE_REPORT_GENERATOR_CONFIGURATION_RESOLVER); |
| 110 | } |
| 111 | |
mstaib | 807a9b2 | 2017-09-19 17:06:32 +0200 | [diff] [blame] | 112 | // TODO(b/65746853): provide a way to do this without passing the entire configuration |
| 113 | /** Implementation for the :run_under attribute. */ |
janakr | 8688b68 | 2018-03-26 09:07:11 -0700 | [diff] [blame] | 114 | @AutoCodec |
janakr | a56a6ad | 2018-02-02 15:52:22 -0800 | [diff] [blame] | 115 | public static final LabelLateBoundDefault<?> RUN_UNDER = |
| 116 | LabelLateBoundDefault.fromTargetConfiguration( |
mstaib | 807a9b2 | 2017-09-19 17:06:32 +0200 | [diff] [blame] | 117 | BuildConfiguration.class, |
| 118 | null, |
| 119 | (rule, attributes, configuration) -> { |
| 120 | RunUnder runUnder = configuration.getRunUnder(); |
| 121 | return runUnder != null ? runUnder.getLabel() : null; |
| 122 | }); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 123 | |
| 124 | /** |
| 125 | * A base rule for all test rules. |
| 126 | */ |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 127 | public static final class TestBaseRule implements RuleDefinition { |
| 128 | @Override |
jcater | 3674591 | 2018-05-01 13:20:00 -0700 | [diff] [blame] | 129 | public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 130 | return builder |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 131 | .requiresConfigurationFragments(TestConfiguration.class) |
| 132 | .add( |
| 133 | attr("size", STRING) |
| 134 | .value("medium") |
| 135 | .taggable() |
| 136 | .nonconfigurable("policy decision: should be consistent across configurations")) |
| 137 | .add( |
| 138 | attr("timeout", STRING) |
| 139 | .taggable() |
| 140 | .nonconfigurable("policy decision: should be consistent across configurations") |
| 141 | .value( |
| 142 | new Attribute.ComputedDefault() { |
| 143 | @Override |
| 144 | public Object getDefault(AttributeMap rule) { |
| 145 | TestSize size = TestSize.getTestSize(rule.get("size", Type.STRING)); |
| 146 | if (size != null) { |
| 147 | String timeout = size.getDefaultTimeout().toString(); |
| 148 | if (timeout != null) { |
| 149 | return timeout; |
| 150 | } |
| 151 | } |
| 152 | return "illegal"; |
| 153 | } |
| 154 | })) |
| 155 | .add( |
| 156 | attr("flaky", BOOLEAN) |
| 157 | .value(false) |
| 158 | .taggable() |
| 159 | .nonconfigurable("policy decision: should be consistent across configurations")) |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 160 | .add(attr("shard_count", INTEGER).value(-1)) |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 161 | .add( |
| 162 | attr("local", BOOLEAN) |
| 163 | .value(false) |
| 164 | .taggable() |
| 165 | .nonconfigurable("policy decision: should be consistent across configurations")) |
Greg Estren | 547295a | 2016-08-18 22:01:29 +0000 | [diff] [blame] | 166 | .add(attr("args", STRING_LIST)) |
Lukacs Berki | 8f460f3 | 2016-06-29 09:14:10 +0000 | [diff] [blame] | 167 | // Input files for every test action |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 168 | .add( |
Laszlo Csomor | 9a93377 | 2018-08-14 08:29:29 -0700 | [diff] [blame] | 169 | attr("$test_wrapper", LABEL) |
| 170 | .cfg(HostTransition.INSTANCE) |
| 171 | .singleArtifact() |
| 172 | .value(env.getToolsLabel("//tools/test:test_wrapper"))) |
| 173 | .add( |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 174 | attr("$test_runtime", LABEL_LIST) |
gregce | 676a957 | 2017-12-21 11:33:32 -0800 | [diff] [blame] | 175 | .cfg(HostTransition.INSTANCE) |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 176 | .value(ImmutableList.of(env.getToolsLabel("//tools/test:runtime")))) |
hlopko | 8820d3a | 2018-06-15 09:10:05 -0700 | [diff] [blame] | 177 | .add( |
| 178 | attr("$test_setup_script", LABEL) |
| 179 | .cfg(HostTransition.INSTANCE) |
| 180 | .singleArtifact() |
| 181 | .value(env.getToolsLabel("//tools/test:test_setup"))) |
| 182 | .add( |
ulfjack | 0858ae1 | 2018-07-27 02:37:53 -0700 | [diff] [blame] | 183 | attr("$xml_generator_script", LABEL) |
| 184 | .cfg(HostTransition.INSTANCE) |
| 185 | .singleArtifact() |
| 186 | .value(env.getToolsLabel("//tools/test:test_xml_generator"))) |
| 187 | .add( |
hlopko | 8820d3a | 2018-06-15 09:10:05 -0700 | [diff] [blame] | 188 | attr("$collect_coverage_script", LABEL) |
| 189 | .cfg(HostTransition.INSTANCE) |
| 190 | .singleArtifact() |
| 191 | .value(env.getToolsLabel("//tools/test:collect_coverage"))) |
Lukacs Berki | 8f460f3 | 2016-06-29 09:14:10 +0000 | [diff] [blame] | 192 | // Input files for test actions collecting code coverage |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 193 | .add( |
dbabkin | 708b957 | 2018-06-07 02:31:16 -0700 | [diff] [blame] | 194 | attr(":coverage_support", LABEL) |
| 195 | .value( |
| 196 | coverageSupportAttribute(env.getToolsLabel(DEFAULT_COVERAGE_SUPPORT_VALUE)))) |
Lukacs Berki | 8f460f3 | 2016-06-29 09:14:10 +0000 | [diff] [blame] | 197 | // Used in the one-per-build coverage report generation action. |
tomlu | a08bb89 | 2017-08-03 03:23:48 +0200 | [diff] [blame] | 198 | .add( |
dbabkin | 2df3234 | 2018-06-07 05:19:54 -0700 | [diff] [blame] | 199 | attr(":coverage_report_generator", LABEL) |
gregce | 676a957 | 2017-12-21 11:33:32 -0800 | [diff] [blame] | 200 | .cfg(HostTransition.INSTANCE) |
dbabkin | 2df3234 | 2018-06-07 05:19:54 -0700 | [diff] [blame] | 201 | .value( |
| 202 | coverageReportGeneratorAttribute( |
elenairina | 9438d10 | 2018-07-06 03:06:21 -0700 | [diff] [blame] | 203 | env.getToolsLabel(DEFAULT_COVERAGE_REPORT_GENERATOR_VALUE)))) |
hlopko | 8820d3a | 2018-06-15 09:10:05 -0700 | [diff] [blame] | 204 | // The target itself and run_under both run on the same machine. |
| 205 | .add(attr(":run_under", LABEL).value(RUN_UNDER).skipPrereqValidatorCheck()) |
jcater | d7ce626 | 2018-06-13 10:17:30 -0700 | [diff] [blame] | 206 | .executionPlatformConstraintsAllowed(ExecutionPlatformConstraintsAllowed.PER_TARGET) |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 207 | .build(); |
| 208 | } |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 209 | |
| 210 | @Override |
| 211 | public Metadata getMetadata() { |
| 212 | return RuleDefinition.Metadata.builder() |
| 213 | .name("$test_base_rule") |
| 214 | .type(RuleClassType.ABSTRACT) |
lberki | 3c1c8e9 | 2017-07-13 12:25:47 +0200 | [diff] [blame] | 215 | .ancestors(RootRule.class, MakeVariableExpandingRule.class) |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 216 | .build(); |
| 217 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 218 | } |
| 219 | |
| 220 | /** |
mstaib | 188b578 | 2018-05-16 10:13:51 -0700 | [diff] [blame] | 221 | * The attribute used to list the configuration properties used by a target and its transitive |
| 222 | * dependencies. Currently only supports config_feature_flag. |
| 223 | */ |
| 224 | public static final String TAGGED_TRIMMING_ATTR = "transitive_configs"; |
| 225 | |
| 226 | /** |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 227 | * Share common attributes across both base and Skylark base rules. |
| 228 | */ |
| 229 | public static RuleClass.Builder commonCoreAndSkylarkAttributes(RuleClass.Builder builder) { |
cpeyser | d852e48 | 2017-09-07 22:16:06 +0200 | [diff] [blame] | 230 | return PlatformSemantics.platformAttributes(builder) |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 231 | // The visibility attribute is special: it is a nodep label, and loading the |
| 232 | // necessary package groups is handled by {@link LabelVisitor#visitTargetVisibility}. |
| 233 | // Package groups always have the null configuration so that they are not duplicated |
| 234 | // needlessly. |
cpeyser | d852e48 | 2017-09-07 22:16:06 +0200 | [diff] [blame] | 235 | .add( |
| 236 | attr("visibility", NODEP_LABEL_LIST) |
| 237 | .orderIndependent() |
gregce | 676a957 | 2017-12-21 11:33:32 -0800 | [diff] [blame] | 238 | .cfg(HostTransition.INSTANCE) |
cpeyser | d852e48 | 2017-09-07 22:16:06 +0200 | [diff] [blame] | 239 | .nonconfigurable( |
| 240 | "special attribute integrated more deeply into Bazel's core logic")) |
| 241 | .add( |
mstaib | 188b578 | 2018-05-16 10:13:51 -0700 | [diff] [blame] | 242 | attr(TAGGED_TRIMMING_ATTR, NODEP_LABEL_LIST) |
| 243 | .orderIndependent() |
| 244 | .nonconfigurable("Used in determining configuration")) |
| 245 | .add( |
cpeyser | d852e48 | 2017-09-07 22:16:06 +0200 | [diff] [blame] | 246 | attr("deprecation", STRING) |
| 247 | .value(deprecationDefault) |
| 248 | .nonconfigurable("Used in core loading phase logic with no access to configs")) |
| 249 | .add( |
| 250 | attr("tags", STRING_LIST) |
| 251 | .orderIndependent() |
| 252 | .taggable() |
| 253 | .nonconfigurable("low-level attribute, used in TargetUtils without configurations")) |
| 254 | .add( |
| 255 | attr("generator_name", STRING) |
| 256 | .undocumented("internal") |
| 257 | .nonconfigurable("static structure of a rule")) |
| 258 | .add( |
| 259 | attr("generator_function", STRING) |
| 260 | .undocumented("internal") |
| 261 | .nonconfigurable("static structure of a rule")) |
| 262 | .add( |
| 263 | attr("generator_location", STRING) |
| 264 | .undocumented("internal") |
| 265 | .nonconfigurable("static structure of a rule")) |
| 266 | .add( |
| 267 | attr("testonly", BOOLEAN) |
| 268 | .value(testonlyDefault) |
| 269 | .nonconfigurable("policy decision: rules testability should be consistent")) |
Manuel Klimek | 6d9fb36 | 2015-04-30 12:50:55 +0000 | [diff] [blame] | 270 | .add(attr("features", STRING_LIST).orderIndependent()) |
gregce | 676a957 | 2017-12-21 11:33:32 -0800 | [diff] [blame] | 271 | .add(attr(":action_listener", LABEL_LIST) |
| 272 | .cfg(HostTransition.INSTANCE) |
| 273 | .value(ACTION_LISTENER)) |
cpeyser | d852e48 | 2017-09-07 22:16:06 +0200 | [diff] [blame] | 274 | .add( |
| 275 | attr(RuleClass.COMPATIBLE_ENVIRONMENT_ATTR, LABEL_LIST) |
| 276 | .allowedRuleClasses(EnvironmentRule.RULE_NAME) |
gregce | 676a957 | 2017-12-21 11:33:32 -0800 | [diff] [blame] | 277 | .cfg(HostTransition.INSTANCE) |
cpeyser | d852e48 | 2017-09-07 22:16:06 +0200 | [diff] [blame] | 278 | .allowedFileTypes(FileTypeSet.NO_FILE) |
| 279 | .dontCheckConstraints() |
| 280 | .nonconfigurable( |
| 281 | "special logic for constraints and select: see ConstraintSemantics")) |
| 282 | .add( |
| 283 | attr(RuleClass.RESTRICTED_ENVIRONMENT_ATTR, LABEL_LIST) |
| 284 | .allowedRuleClasses(EnvironmentRule.RULE_NAME) |
gregce | 676a957 | 2017-12-21 11:33:32 -0800 | [diff] [blame] | 285 | .cfg(HostTransition.INSTANCE) |
cpeyser | d852e48 | 2017-09-07 22:16:06 +0200 | [diff] [blame] | 286 | .allowedFileTypes(FileTypeSet.NO_FILE) |
| 287 | .dontCheckConstraints() |
| 288 | .nonconfigurable( |
| 289 | "special logic for constraints and select: see ConstraintSemantics")); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 290 | } |
| 291 | |
Googler | 015e595 | 2017-02-14 09:45:30 +0000 | [diff] [blame] | 292 | public static RuleClass.Builder nameAttribute(RuleClass.Builder builder) { |
| 293 | return builder.add(attr("name", STRING).nonconfigurable("Rule name")); |
| 294 | } |
| 295 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 296 | /** |
Googler | 015e595 | 2017-02-14 09:45:30 +0000 | [diff] [blame] | 297 | * Ancestor of every rule. |
| 298 | * |
| 299 | * <p>Adds the name attribute to every rule. |
| 300 | */ |
| 301 | public static final class RootRule implements RuleDefinition { |
| 302 | |
| 303 | @Override |
jcater | 3674591 | 2018-05-01 13:20:00 -0700 | [diff] [blame] | 304 | public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) { |
Googler | 015e595 | 2017-02-14 09:45:30 +0000 | [diff] [blame] | 305 | return nameAttribute(builder).build(); |
| 306 | } |
| 307 | |
| 308 | @Override |
| 309 | public Metadata getMetadata() { |
| 310 | return RuleDefinition.Metadata.builder() |
| 311 | .name("$root_rule") |
| 312 | .type(RuleClassType.ABSTRACT) |
| 313 | .build(); |
| 314 | } |
| 315 | } |
| 316 | |
| 317 | /** |
| 318 | * Common parts of some rules. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 319 | */ |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 320 | public static final class BaseRule implements RuleDefinition { |
| 321 | @Override |
| 322 | public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { |
| 323 | return commonCoreAndSkylarkAttributes(builder) |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 324 | // Aggregates the labels of all {@link ConfigRuleClasses} rules this rule uses (e.g. |
| 325 | // keys for configurable attributes). This is specially populated in |
| 326 | // {@RuleClass#populateRuleAttributeValues}. |
| 327 | // |
| 328 | // This attribute is not needed for actual builds. Its main purpose is so query's |
| 329 | // proto/XML output includes the labels of config dependencies, so, e.g., depserver |
| 330 | // reverse dependency lookups remain accurate. These can't just be added to the |
| 331 | // attribute definitions proto/XML queries already output because not all attributes |
| 332 | // contain labels. |
| 333 | // |
| 334 | // Builds and Blaze-interactive queries don't need this because they find dependencies |
| 335 | // through direct Rule label visitation, which already factors these in. |
| 336 | .add(attr("$config_dependencies", LABEL_LIST) |
| 337 | .nonconfigurable("not intended for actual builds")) |
| 338 | .add(attr("licenses", LICENSE) |
| 339 | .nonconfigurable("Used in core loading phase logic with no access to configs")) |
| 340 | .add(attr("distribs", DISTRIBUTIONS) |
| 341 | .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] | 342 | .build(); |
| 343 | } |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 344 | |
| 345 | @Override |
| 346 | public Metadata getMetadata() { |
| 347 | return RuleDefinition.Metadata.builder() |
| 348 | .name("$base_rule") |
| 349 | .type(RuleClassType.ABSTRACT) |
Googler | 015e595 | 2017-02-14 09:45:30 +0000 | [diff] [blame] | 350 | .ancestors(RootRule.class) |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 351 | .build(); |
| 352 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 353 | } |
| 354 | |
| 355 | /** |
lberki | 3c1c8e9 | 2017-07-13 12:25:47 +0200 | [diff] [blame] | 356 | * A rule that contains a {@code variables=} attribute to allow referencing Make variables. |
| 357 | */ |
| 358 | public static final class MakeVariableExpandingRule implements RuleDefinition { |
| 359 | @Override |
jcater | 3674591 | 2018-05-01 13:20:00 -0700 | [diff] [blame] | 360 | public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { |
lberki | 3c1c8e9 | 2017-07-13 12:25:47 +0200 | [diff] [blame] | 361 | return builder |
| 362 | /* <!-- #BLAZE_RULE($make_variable_expanding_rule).ATTRIBUTE(toolchains) --> |
| 363 | The set of toolchains that supply <a href="${link make-variables}">"Make variables"</a> |
| 364 | that this target can use in some of its attributes. Some rules have toolchains whose Make |
| 365 | variables they can use by default. |
| 366 | <!-- #END_BLAZE_RULE.ATTRIBUTE --> */ |
| 367 | .add(attr("toolchains", LABEL_LIST) |
| 368 | .allowedFileTypes(FileTypeSet.NO_FILE) |
jcater | 191238f | 2018-06-19 10:17:16 -0700 | [diff] [blame] | 369 | .mandatoryProviders(ImmutableList.of(TemplateVariableInfo.PROVIDER.id())) |
| 370 | .dontCheckConstraints()) |
lberki | 3c1c8e9 | 2017-07-13 12:25:47 +0200 | [diff] [blame] | 371 | .build(); |
| 372 | } |
| 373 | |
| 374 | @Override |
| 375 | public Metadata getMetadata() { |
| 376 | return RuleDefinition.Metadata.builder() |
| 377 | .name("$make_variable_expanding_rule") |
| 378 | .type(RuleClassType.ABSTRACT) |
| 379 | .build(); |
| 380 | } |
| 381 | } |
| 382 | |
| 383 | /** |
Googler | 015e595 | 2017-02-14 09:45:30 +0000 | [diff] [blame] | 384 | * Common ancestor class for some rules. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 385 | */ |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 386 | public static final class RuleBase implements RuleDefinition { |
| 387 | @Override |
jcater | 3674591 | 2018-05-01 13:20:00 -0700 | [diff] [blame] | 388 | public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 389 | return builder |
| 390 | .add(attr("deps", LABEL_LIST).legacyAllowAnyFileType()) |
hlopko | 8820d3a | 2018-06-15 09:10:05 -0700 | [diff] [blame] | 391 | .add( |
| 392 | attr("data", LABEL_LIST) |
| 393 | .allowedFileTypes(FileTypeSet.ANY_FILE) |
| 394 | .dontCheckConstraints()) |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 395 | .build(); |
| 396 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 397 | |
Googler | 5850503 | 2015-03-19 16:12:34 +0000 | [diff] [blame] | 398 | @Override |
| 399 | public Metadata getMetadata() { |
| 400 | return RuleDefinition.Metadata.builder() |
| 401 | .name("$rule") |
| 402 | .type(RuleClassType.ABSTRACT) |
| 403 | .ancestors(BaseRule.class) |
| 404 | .build(); |
| 405 | } |
| 406 | } |
Ulf Adams | 37590dc | 2016-10-14 11:52:00 +0000 | [diff] [blame] | 407 | |
| 408 | public static final ImmutableSet<String> ALLOWED_RULE_CLASSES = |
| 409 | ImmutableSet.of("filegroup", "genrule", "Fileset"); |
| 410 | |
| 411 | /** A base rule for all binary rules. */ |
| 412 | public static final class BinaryBaseRule implements RuleDefinition { |
| 413 | @Override |
jcater | 3674591 | 2018-05-01 13:20:00 -0700 | [diff] [blame] | 414 | public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { |
Ulf Adams | 37590dc | 2016-10-14 11:52:00 +0000 | [diff] [blame] | 415 | return builder |
| 416 | .add(attr("args", STRING_LIST)) |
| 417 | .add(attr("output_licenses", LICENSE)) |
| 418 | .add( |
| 419 | attr("$is_executable", BOOLEAN) |
| 420 | .value(true) |
| 421 | .nonconfigurable("Called from RunCommand.isExecutable, which takes a Target")) |
| 422 | .build(); |
| 423 | } |
| 424 | |
| 425 | @Override |
| 426 | public Metadata getMetadata() { |
| 427 | return RuleDefinition.Metadata.builder() |
| 428 | .name("$binary_base_rule") |
| 429 | .type(RuleClassType.ABSTRACT) |
lberki | 3c1c8e9 | 2017-07-13 12:25:47 +0200 | [diff] [blame] | 430 | .ancestors(RootRule.class, MakeVariableExpandingRule.class) |
Ulf Adams | 37590dc | 2016-10-14 11:52:00 +0000 | [diff] [blame] | 431 | .build(); |
| 432 | } |
| 433 | } |
| 434 | |
| 435 | /** Rule class for rules in error. */ |
| 436 | public static final class ErrorRule implements RuleDefinition { |
| 437 | @Override |
jcater | 3674591 | 2018-05-01 13:20:00 -0700 | [diff] [blame] | 438 | public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { |
Ulf Adams | 37590dc | 2016-10-14 11:52:00 +0000 | [diff] [blame] | 439 | return builder.publicByDefault().build(); |
| 440 | } |
| 441 | |
| 442 | @Override |
| 443 | public Metadata getMetadata() { |
| 444 | return RuleDefinition.Metadata.builder() |
| 445 | .name("$error_rule") |
| 446 | .type(RuleClassType.ABSTRACT) |
| 447 | .ancestors(BaseRuleClasses.BaseRule.class) |
| 448 | .build(); |
| 449 | } |
| 450 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 451 | } |