blob: f95810383ee03fcb01336dd058d409080568c9a9 [file] [log] [blame]
Michael Staib5e573fd2016-01-27 00:33:29 +00001// Copyright 2014 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.analysis;
15
John Cater1f6758f2020-05-21 08:41:53 -070016import com.google.auto.value.AutoValue;
tomlua155b532017-11-08 20:12:47 +010017import com.google.common.base.Preconditions;
Googler3cc6cc32020-04-29 10:50:38 -070018import com.google.common.collect.ImmutableList;
Michael Staib5e573fd2016-01-27 00:33:29 +000019import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
gregcebe55e112018-01-30 11:04:53 -080020import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
Michael Staib5e573fd2016-01-27 00:33:29 +000021import com.google.devtools.build.lib.cmdline.Label;
Dmitry Lomov15756522016-12-16 16:52:37 +000022import com.google.devtools.build.lib.packages.AspectDescriptor;
John Cater5fa85c82020-05-26 10:52:30 -070023import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey;
Michael Staib5e573fd2016-01-27 00:33:29 +000024import javax.annotation.Nullable;
25
26/**
27 * A dependency of a configured target through a label.
28 *
John Cater2a546592020-05-19 04:48:52 -070029 * <p>All instances have an explicit configuration, which includes the target and the configuration
30 * of the dependency configured target and any aspects that may be required, as well as the
31 * configurations for these aspects and transition keys. {@link Dependency#getTransitionKeys}
32 * provides some more context on transition keys.
Michael Staib5e573fd2016-01-27 00:33:29 +000033 *
34 * <p>Note that the presence of an aspect here does not necessarily mean that it will be created.
35 * They will be filtered based on the {@link TransitiveInfoProvider} instances their associated
Googler46b285a2020-03-06 13:33:24 -080036 * configured targets have (we cannot do that here because the configured targets are not available
37 * yet). No error or warning is reported in this case, because it is expected that rules sometimes
38 * over-approximate the providers they supply in their definitions.
Michael Staib5e573fd2016-01-27 00:33:29 +000039 */
John Cater1f6758f2020-05-21 08:41:53 -070040@AutoValue
Michael Staib5e573fd2016-01-27 00:33:29 +000041public abstract class Dependency {
John Cater696e3022020-05-19 10:19:09 -070042 /** Builder to assist in creating dependency instances. */
John Cater1f6758f2020-05-21 08:41:53 -070043 @AutoValue.Builder
44 public abstract static class Builder {
45 /** Sets the label of the target this dependency points to. */
46 public abstract Builder setLabel(Label label);
Michael Staib5e573fd2016-01-27 00:33:29 +000047
John Cater1f6758f2020-05-21 08:41:53 -070048 /** Sets the configuration intended for this dependency. */
49 public abstract Builder setConfiguration(BuildConfiguration configuration);
John Cater696e3022020-05-19 10:19:09 -070050
51 /** Explicitly set the configuration for this dependency to null. */
52 public Builder withNullConfiguration() {
53 return setConfiguration(null);
54 }
55
56 /** Add aspects to this Dependency. The same configuration is applied to all aspects. */
John Cater1f6758f2020-05-21 08:41:53 -070057 public abstract Builder setAspects(AspectCollection aspects);
58
59 /** Sets the keys of a configuration transition. */
60 public Builder setTransitionKey(String key) {
jcaterbd864ef2020-06-05 07:34:16 -070061 if (key.isEmpty()) {
62 // Ignore empty keys.
63 return this;
64 }
John Cater1f6758f2020-05-21 08:41:53 -070065 return setTransitionKeys(ImmutableList.of(key));
John Cater696e3022020-05-19 10:19:09 -070066 }
67
John Cater1f6758f2020-05-21 08:41:53 -070068 /** Sets the keys of a configuration transition. */
69 public abstract Builder setTransitionKeys(ImmutableList<String> keys);
John Cater696e3022020-05-19 10:19:09 -070070
John Catere9137b62020-06-10 14:16:21 -070071 /**
twigg7978f362021-10-20 14:29:46 -070072 * Sets the execution platform {@link Label} that this dependency should use as an override for
73 * toolchain resolution.
John Catere9137b62020-06-10 14:16:21 -070074 */
twigg7978f362021-10-20 14:29:46 -070075 public abstract Builder setExecutionPlatformLabel(@Nullable Label executionPlatformLabel);
John Catere9137b62020-06-10 14:16:21 -070076
John Cater1f6758f2020-05-21 08:41:53 -070077 // Not public.
78 abstract Dependency autoBuild();
John Cater696e3022020-05-19 10:19:09 -070079
80 /** Returns the full Dependency instance. */
81 public Dependency build() {
John Cater1f6758f2020-05-21 08:41:53 -070082 Dependency dependency = autoBuild();
83 if (dependency.getConfiguration() == null) {
84 Preconditions.checkState(
85 dependency.getAspects().equals(AspectCollection.EMPTY),
86 "Dependency with null Configuration cannot have aspects");
John Cater696e3022020-05-19 10:19:09 -070087 }
John Cater1f6758f2020-05-21 08:41:53 -070088 return dependency;
John Cater696e3022020-05-19 10:19:09 -070089 }
jcaterbd864ef2020-06-05 07:34:16 -070090
91 // Added to enable copy, below. Should not be accessible to other classes.
92 protected abstract Label getLabel();
93
94 @Nullable
95 protected abstract BuildConfiguration getConfiguration();
96
97 protected abstract AspectCollection getAspects();
98
99 protected abstract ImmutableList<String> getTransitionKeys();
100
101 /** Returns a copy of this Builder, with the values the same. */
102 public Builder copy() {
103 return Dependency.builder()
104 .setLabel(getLabel())
105 .setConfiguration(getConfiguration())
106 .setAspects(getAspects())
107 .setTransitionKeys(getTransitionKeys());
108 }
Michael Staib5e573fd2016-01-27 00:33:29 +0000109 }
110
John Cater696e3022020-05-19 10:19:09 -0700111 /** Returns a new {@link Builder} to create {@link Dependency} instances. */
112 public static Builder builder() {
John Cater1f6758f2020-05-21 08:41:53 -0700113 return new AutoValue_Dependency.Builder()
114 .setAspects(AspectCollection.EMPTY)
115 .setTransitionKeys(ImmutableList.of());
Michael Staib5e573fd2016-01-27 00:33:29 +0000116 }
117
118 /** Returns the label of the target this dependency points to. */
John Cater1f6758f2020-05-21 08:41:53 -0700119 public abstract Label getLabel();
Michael Staib5e573fd2016-01-27 00:33:29 +0000120
John Cater1f6758f2020-05-21 08:41:53 -0700121 /** Returns the explicit configuration intended for this dependency. */
Michael Staib5e573fd2016-01-27 00:33:29 +0000122 @Nullable
123 public abstract BuildConfiguration getConfiguration();
124
125 /**
Michael Staib5e573fd2016-01-27 00:33:29 +0000126 * Returns the set of aspects which should be evaluated and combined with the configured target
127 * pointed to by this dependency.
128 *
Dmitry Lomove851fe22017-02-14 23:11:23 +0000129 * @see #getAspectConfiguration(AspectDescriptor)
Michael Staib5e573fd2016-01-27 00:33:29 +0000130 */
Dmitry Lomove851fe22017-02-14 23:11:23 +0000131 public abstract AspectCollection getAspects();
Michael Staib5e573fd2016-01-27 00:33:29 +0000132
John Cater696e3022020-05-19 10:19:09 -0700133 /** Returns the configuration an aspect should be evaluated with. */
John Cater1f6758f2020-05-21 08:41:53 -0700134 @Nullable
135 public BuildConfiguration getAspectConfiguration(AspectDescriptor aspect) {
136 return getConfiguration();
137 }
Michael Staib5e573fd2016-01-27 00:33:29 +0000138
139 /**
John Cater1f6758f2020-05-21 08:41:53 -0700140 * Returns the keys of a configuration transition, if any exist, associated with this dependency.
141 * See {@link ConfigurationTransition#apply} for more details. Normally, this returns an empty
142 * list, when there was no configuration transition in effect, or one with a single entry, when
143 * there was a specific configuration transition result that led to this. It may also return a
144 * list with multiple entries if the dependency has a null configuration, yet the outgoing edge
145 * has a split transition. In such cases all transition keys returned by the transition are tagged
146 * to the dependency.
Googler46b285a2020-03-06 13:33:24 -0800147 */
Googler3cc6cc32020-04-29 10:50:38 -0700148 public abstract ImmutableList<String> getTransitionKeys();
John Cater5fa85c82020-05-26 10:52:30 -0700149
John Catere9137b62020-06-10 14:16:21 -0700150 /**
twigg7978f362021-10-20 14:29:46 -0700151 * Returns the execution platform {@link Label} that this dependency should use as an override for
152 * toolchain resolution.
John Catere9137b62020-06-10 14:16:21 -0700153 */
154 @Nullable
twigg7978f362021-10-20 14:29:46 -0700155 public abstract Label getExecutionPlatformLabel();
John Catere9137b62020-06-10 14:16:21 -0700156
John Cater5fa85c82020-05-26 10:52:30 -0700157 /** Returns the ConfiguredTargetKey needed to fetch this dependency. */
158 public ConfiguredTargetKey getConfiguredTargetKey() {
John Catere9137b62020-06-10 14:16:21 -0700159 ConfiguredTargetKey.Builder configuredTargetKeyBuilder =
160 ConfiguredTargetKey.builder().setLabel(getLabel()).setConfiguration(getConfiguration());
twigg7978f362021-10-20 14:29:46 -0700161 if (getExecutionPlatformLabel() != null) {
162 configuredTargetKeyBuilder.setExecutionPlatformLabel(getExecutionPlatformLabel());
John Catere9137b62020-06-10 14:16:21 -0700163 }
164 return configuredTargetKeyBuilder.build();
John Cater5fa85c82020-05-26 10:52:30 -0700165 }
Michael Staib5e573fd2016-01-27 00:33:29 +0000166}