blob: 4b92afea3906bc78dc9121cd42dd1f9702e1e8d2 [file] [log] [blame]
Lukacs Berki7894c182016-05-10 12:07:01 +00001// Copyright 2016 The Bazel Authors. All rights reserved.
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.
14package com.google.devtools.build.lib.rules;
15
16import static com.google.devtools.build.lib.packages.Attribute.ANY_RULE;
17import static com.google.devtools.build.lib.packages.Attribute.attr;
18import static com.google.devtools.build.lib.packages.BuildType.LABEL;
19
20import com.google.common.collect.ImmutableMap;
cparsonse2d200f2018-03-06 16:15:11 -080021import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
ulfjack90e2e982017-08-07 11:27:32 +020022import com.google.devtools.build.lib.analysis.AliasProvider;
Lukacs Berki7894c182016-05-10 12:07:01 +000023import com.google.devtools.build.lib.analysis.BaseRuleClasses;
24import com.google.devtools.build.lib.analysis.ConfiguredTarget;
ulfjack26d0e492017-08-07 13:42:33 +020025import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
Lukacs Berki7894c182016-05-10 12:07:01 +000026import com.google.devtools.build.lib.analysis.RuleContext;
27import com.google.devtools.build.lib.analysis.RuleDefinition;
28import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment;
jcaterf7d726f2020-04-13 10:34:54 -070029import com.google.devtools.build.lib.analysis.TransitionMode;
Lukacs Berki7894c182016-05-10 12:07:01 +000030import com.google.devtools.build.lib.analysis.VisibilityProvider;
31import com.google.devtools.build.lib.analysis.VisibilityProviderImpl;
hlopko71a213c2019-06-21 02:01:33 -070032import com.google.devtools.build.lib.analysis.config.CoreOptions;
Lukacs Berki7894c182016-05-10 12:07:01 +000033import com.google.devtools.build.lib.packages.RuleClass;
Lukacs Berki7894c182016-05-10 12:07:01 +000034import com.google.devtools.build.lib.util.FileTypeSet;
35
36/**
37 * Implementation of the <code>alias</code> rule.
38 */
39public class Alias implements RuleConfiguredTargetFactory {
juliexxiab63a4a92019-06-14 12:05:18 -070040
41 public static final String RULE_NAME = "alias";
42 public static final String ACTUAL_ATTRIBUTE_NAME = "actual";
43
Lukacs Berki7894c182016-05-10 12:07:01 +000044 @Override
Chris Parsons4dfb22c2016-05-23 17:39:42 +000045 public ConfiguredTarget create(RuleContext ruleContext)
cparsonse2d200f2018-03-06 16:15:11 -080046 throws InterruptedException, RuleErrorException, ActionConflictException {
jcaterf7d726f2020-04-13 10:34:54 -070047 ConfiguredTarget actual =
48 (ConfiguredTarget) ruleContext.getPrerequisite("actual", TransitionMode.TARGET);
hlopko71a213c2019-06-21 02:01:33 -070049
50 // TODO(b/129045294): Remove once the flag is flipped.
51 if (ruleContext.getLabel().getCanonicalForm().startsWith("@bazel_tools//platforms")
52 && ruleContext
53 .getConfiguration()
54 .getOptions()
55 .get(CoreOptions.class)
56 .usePlatformsRepoForConstraints) {
57 throw ruleContext.throwWithRuleError(
58 "Constraints from @bazel_tools//platforms have been "
59 + "removed. Please use constraints from @platforms repository embedded in "
60 + "Bazel, or preferably declare dependency on "
61 + "https://github.com/bazelbuild/platforms. See "
62 + "https://github.com/bazelbuild/bazel/issues/8622 for details.");
63 }
64
Lukacs Berki7894c182016-05-10 12:07:01 +000065 return new AliasConfiguredTarget(
vladmos632d9612017-07-07 13:01:00 -040066 ruleContext,
Lukacs Berki7894c182016-05-10 12:07:01 +000067 actual,
68 ImmutableMap.of(
vladmos632d9612017-07-07 13:01:00 -040069 AliasProvider.class,
70 AliasProvider.fromAliasRule(ruleContext.getLabel(), actual),
71 VisibilityProvider.class,
72 new VisibilityProviderImpl(ruleContext.getVisibility())));
Lukacs Berki7894c182016-05-10 12:07:01 +000073 }
74
75 /**
76 * Rule definition.
77 */
78 public static class AliasRule implements RuleDefinition {
79 @Override
jcater0a57d3d2018-05-01 20:33:18 -070080 public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) {
Lukacs Berki7894c182016-05-10 12:07:01 +000081 return builder
82 /*<!-- #BLAZE_RULE(alias).ATTRIBUTE(actual) -->
83 The target this alias refers to. It does not need to be a rule, it can also be an input
84 file.
85 <!-- #END_BLAZE_RULE.ATTRIBUTE -->*/
Lukacs Berki0ab1f5f2016-05-19 12:04:32 +000086 .removeAttribute("licenses")
87 .removeAttribute("distribs")
John Caterfd3bbf52017-12-21 13:49:56 -080088 .add(
juliexxiab63a4a92019-06-14 12:05:18 -070089 attr(ACTUAL_ATTRIBUTE_NAME, LABEL)
John Caterfd3bbf52017-12-21 13:49:56 -080090 .allowedFileTypes(FileTypeSet.ANY_FILE)
91 .allowedRuleClasses(ANY_RULE)
92 .mandatory())
Dmitry Lomov6cd98972017-03-01 15:44:00 +000093 .canHaveAnyProvider()
John Caterfd3bbf52017-12-21 13:49:56 -080094 // Aliases themselves do not need toolchains or an execution platform, so this is fine.
jcater01bb1f92019-06-17 12:09:11 -070095 // The actual target will resolve platforms and toolchains with no issues regardless of
96 // this setting.
97 .useToolchainResolution(false)
Lukacs Berki7894c182016-05-10 12:07:01 +000098 .build();
99 }
100
101 @Override
102 public Metadata getMetadata() {
103 return Metadata.builder()
juliexxiab63a4a92019-06-14 12:05:18 -0700104 .name(RULE_NAME)
Lukacs Berki7894c182016-05-10 12:07:01 +0000105 .factoryClass(Alias.class)
106 .ancestors(BaseRuleClasses.BaseRule.class)
107 .build();
108 }
109 }
110}
111
112/*<!-- #BLAZE_RULE (NAME = alias, TYPE = OTHER, FAMILY = General)[GENERIC_RULE] -->
113
114<p>
115 The <code>alias</code> rule creates another name a rule can be referred to as.
116</p>
117
118<p>
mstaib57fcbbd2018-12-20 07:46:23 -0800119 Aliasing only works for "regular" targets. In particular, <code>package_group</code>
Greg6be120d2019-10-11 05:53:22 -0700120 and <code>test_suite</code> cannot be aliased.
Lukacs Berki7894c182016-05-10 12:07:01 +0000121</p>
122
123<p>
Lukacs Berki0ab1f5f2016-05-19 12:04:32 +0000124 The alias rule has its own visibility declaration. In all other respects, it behaves
Lukacs Berki7894c182016-05-10 12:07:01 +0000125 like the rule it references with some minor exceptions:
126
127 <ul>
128 <li>
Googler8a92a752018-10-01 02:36:15 -0700129 Tests are not run if their alias is mentioned on the command line. To define an alias
130 that runs the referenced test, use a <a href="#test_suite"><code>test_suite</code></a>
131 rule with a single target in its <a href="#test_suite.tests"><code>tests</code></a>
132 attribute.
Lukacs Berki7894c182016-05-10 12:07:01 +0000133 </li>
134 <li>
135 When defining environment groups, the aliases to <code>environment</code> rules are not
136 supported. They are not supported in the <code>--target_environment</code> command line
137 option, either.
138 </li>
139 </ul>
140</p>
141
142<h4 id="alias_example">Examples</h4>
143
144<pre class="code">
145filegroup(
146 name = "data",
147 srcs = ["data.txt"],
148)
149
150alias(
Googler28bf8732017-02-01 04:58:32 +0000151 name = "other",
152 actual = ":data",
Lukacs Berki7894c182016-05-10 12:07:01 +0000153)
154</pre>
155
156<!-- #END_BLAZE_RULE -->*/