blob: 4d82e0b96018824a3a25c1ec677f97f4d75675bd [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
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
15package com.google.devtools.build.lib.skyframe;
16
kmbb495a442021-08-25 19:45:28 -070017import static com.google.common.collect.ImmutableList.toImmutableList;
18
tomlua155b532017-11-08 20:12:47 +010019import com.google.common.base.Preconditions;
Googler602b7cd2022-06-06 05:13:12 -070020import com.google.common.base.Predicates;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010021import com.google.common.collect.ImmutableList;
cpeyserfb829992017-09-07 17:17:03 +020022import com.google.common.collect.ImmutableSet;
jhorvitz3cf2bca2021-11-23 14:29:10 -080023import com.google.common.collect.Lists;
janakr0175ce32018-02-26 15:54:57 -080024import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
ulfjack90e2e982017-08-07 11:27:32 +020025import com.google.devtools.build.lib.analysis.AliasProvider;
gregce4c3ef112017-09-20 23:43:14 +020026import com.google.devtools.build.lib.analysis.AspectResolver;
jcater44c99422020-04-20 15:52:18 -070027import com.google.devtools.build.lib.analysis.AspectValue;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010028import com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment;
ulfjack37407682019-09-17 06:30:49 -070029import com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment.MissingDepException;
Dmitry Lomovb487ac62015-11-09 13:09:12 +000030import com.google.devtools.build.lib.analysis.ConfiguredAspect;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010031import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory;
kmbb495a442021-08-25 19:45:28 -070032import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010033import com.google.devtools.build.lib.analysis.ConfiguredTarget;
janakr876deaa2021-02-17 07:49:48 -080034import com.google.devtools.build.lib.analysis.ConfiguredTargetValue;
kmbb495a442021-08-25 19:45:28 -070035import com.google.devtools.build.lib.analysis.Dependency;
36import com.google.devtools.build.lib.analysis.DependencyKey;
jcaterdad2dd32020-04-13 08:31:58 -070037import com.google.devtools.build.lib.analysis.DependencyKind;
jcater84ca5562020-04-06 14:35:46 -070038import com.google.devtools.build.lib.analysis.DuplicateException;
Googler602b7cd2022-06-06 05:13:12 -070039import com.google.devtools.build.lib.analysis.ExecGroupCollection;
jcater645c42b2021-05-12 09:35:48 -070040import com.google.devtools.build.lib.analysis.ExecGroupCollection.InvalidExecGroupException;
jcaterdad2dd32020-04-13 08:31:58 -070041import com.google.devtools.build.lib.analysis.InconsistentAspectOrderException;
John Catercdfa9ca2019-04-05 12:32:09 -070042import com.google.devtools.build.lib.analysis.ResolvedToolchainContext;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010043import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
juliexxia71a80dc2020-04-09 09:07:09 -070044import com.google.devtools.build.lib.analysis.ToolchainCollection;
jhorvitz33f76482021-10-28 10:13:26 -070045import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
gregce79989f92021-02-01 07:01:55 -080046import com.google.devtools.build.lib.analysis.config.ConfigConditions;
kmbb495a442021-08-25 19:45:28 -070047import com.google.devtools.build.lib.analysis.config.ConfigurationResolver;
jcater67181912020-04-08 10:46:29 -070048import com.google.devtools.build.lib.analysis.config.DependencyEvaluationException;
Ulf Adams25f03d82016-01-25 10:31:46 +000049import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
kmbb495a442021-08-25 19:45:28 -070050import com.google.devtools.build.lib.analysis.config.TransitionResolver;
51import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
52import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
gregce2aee44b2017-09-16 07:16:44 +020053import com.google.devtools.build.lib.analysis.configuredtargets.MergedConfiguredTarget;
Samuel Giddinseadadbd2020-08-17 08:00:05 -070054import com.google.devtools.build.lib.analysis.starlark.StarlarkTransition.TransitionException;
janakrd4ec9e22022-01-26 07:52:03 -080055import com.google.devtools.build.lib.bugreport.BugReport;
ulfjack904a8d62018-05-29 05:17:35 -070056import com.google.devtools.build.lib.causes.Cause;
57import com.google.devtools.build.lib.causes.LabelCause;
John Fielda97e17f2015-11-13 02:19:52 +000058import com.google.devtools.build.lib.cmdline.Label;
Ulf Adams84901732016-01-28 15:05:16 +000059import com.google.devtools.build.lib.collect.nestedset.NestedSet;
Marian Loburc62faba2015-09-09 10:08:06 +000060import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
jhorvitz564a6892021-11-18 20:29:24 -080061import com.google.devtools.build.lib.collect.nestedset.Order;
Ulf Adams9e16f0a2016-01-25 12:43:32 +000062import com.google.devtools.build.lib.events.Event;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010063import com.google.devtools.build.lib.events.StoredEventHandler;
Dmitry Lomov2eb8bdd2016-04-06 08:47:30 +000064import com.google.devtools.build.lib.packages.Aspect;
kmbb495a442021-08-25 19:45:28 -070065import com.google.devtools.build.lib.packages.Attribute;
Janak Ramakrishnan0a4c6e42015-09-17 00:37:58 +000066import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +000067import com.google.devtools.build.lib.packages.NativeAspectClass;
kmbb495a442021-08-25 19:45:28 -070068import com.google.devtools.build.lib.packages.NoSuchPackageException;
janakrf3e6f252018-01-18 07:45:12 -080069import com.google.devtools.build.lib.packages.NoSuchTargetException;
Ulf Adamsd55d7af2016-01-19 11:03:22 +000070import com.google.devtools.build.lib.packages.NoSuchThingException;
cparsons089148b2019-09-17 08:14:41 -070071import com.google.devtools.build.lib.packages.OutputFile;
Marian Loburc62faba2015-09-09 10:08:06 +000072import com.google.devtools.build.lib.packages.Package;
messa1bca1bd2021-05-14 00:48:19 -070073import com.google.devtools.build.lib.packages.Rule;
Greg Estren00049432015-08-25 16:43:47 +000074import com.google.devtools.build.lib.packages.RuleClassProvider;
gregce18694cd2020-05-12 15:40:05 -070075import com.google.devtools.build.lib.packages.StarlarkAspectClass;
gregced281df72020-05-11 12:27:06 -070076import com.google.devtools.build.lib.packages.StarlarkDefinedAspect;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010077import com.google.devtools.build.lib.packages.Target;
messa1bca1bd2021-05-14 00:48:19 -070078import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
tomlu72642a22017-10-18 06:23:14 +020079import com.google.devtools.build.lib.profiler.memory.CurrentRuleTracker;
lebab52a1902021-09-23 01:35:13 -070080import com.google.devtools.build.lib.skyframe.AspectKeyCreator.AspectKey;
brandjon771a0292020-05-26 12:04:16 -070081import com.google.devtools.build.lib.skyframe.BzlLoadFunction.BzlLoadFailedException;
nharmatabcd11ae2022-01-10 20:11:22 -080082import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ComputeDependenciesState;
Googler602b7cd2022-06-06 05:13:12 -070083import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ComputedToolchainContexts;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010084import com.google.devtools.build.lib.skyframe.SkyframeExecutor.BuildViewProvider;
Greg Estrend5353252016-08-11 22:13:31 +000085import com.google.devtools.build.lib.util.OrderedSetMultimap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010086import com.google.devtools.build.skyframe.SkyFunction;
nharmatabcd11ae2022-01-10 20:11:22 -080087import com.google.devtools.build.skyframe.SkyFunction.Environment.SkyKeyComputeState;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010088import com.google.devtools.build.skyframe.SkyFunctionException;
89import com.google.devtools.build.skyframe.SkyKey;
90import com.google.devtools.build.skyframe.SkyValue;
emilyguo8ca657c2022-02-25 10:36:22 -080091import com.google.devtools.build.skyframe.SkyframeLookupResult;
jhorvitz3cf2bca2021-11-23 14:29:10 -080092import java.util.LinkedHashSet;
93import java.util.List;
Googler602b7cd2022-06-06 05:13:12 -070094import java.util.Map;
jhorvitz564a6892021-11-18 20:29:24 -080095import java.util.Objects;
Googler602b7cd2022-06-06 05:13:12 -070096import java.util.Set;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010097import javax.annotation.Nullable;
messa1bca1bd2021-05-14 00:48:19 -070098import net.starlark.java.eval.StarlarkSemantics;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010099
100/**
101 * The Skyframe function that generates aspects.
Dmitry Lomove8040172016-04-06 14:53:43 +0000102 *
jhorvitz81395032021-05-05 08:48:08 -0700103 * <p>This class, together with {@link ConfiguredTargetFunction} drives the analysis phase. For more
ulfjack26d0e492017-08-07 13:42:33 +0200104 * information, see {@link com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory}.
Lukacs Berki2300cd62016-05-19 11:06:37 +0000105 *
jhorvitz81395032021-05-05 08:48:08 -0700106 * <p>{@link AspectFunction} takes a SkyKey containing an {@link AspectKey} [a tuple of (target
107 * label, configurations, aspect class and aspect parameters)], loads an {@link Aspect} from aspect
108 * class and aspect parameters, gets a {@link ConfiguredTarget} for label and configurations, and
109 * then creates a {@link ConfiguredAspect} for a given {@link AspectKey}.
Dmitry Lomove8040172016-04-06 14:53:43 +0000110 *
jhorvitz81395032021-05-05 08:48:08 -0700111 * <p>See {@link com.google.devtools.build.lib.packages.AspectClass} documentation for an overview
112 * of aspect-related classes
Lukacs Berki2300cd62016-05-19 11:06:37 +0000113 *
ulfjack26d0e492017-08-07 13:42:33 +0200114 * @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory
Lukacs Berki2300cd62016-05-19 11:06:37 +0000115 * @see com.google.devtools.build.lib.packages.AspectClass
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100116 */
jhorvitz81395032021-05-05 08:48:08 -0700117final class AspectFunction implements SkyFunction {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100118 private final BuildViewProvider buildViewProvider;
Greg Estren00049432015-08-25 16:43:47 +0000119 private final RuleClassProvider ruleClassProvider;
janakr931d2852017-12-15 13:48:29 -0800120 /**
121 * Indicates whether the set of packages transitively loaded for a given {@link AspectValue} will
122 * be needed for package root resolution later in the build. If not, they are not collected and
123 * stored.
124 */
125 private final boolean storeTransitivePackagesForPackageRootResolution;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100126
janakr93e3eea2017-03-30 22:09:37 +0000127 AspectFunction(
128 BuildViewProvider buildViewProvider,
129 RuleClassProvider ruleClassProvider,
jhorvitz81395032021-05-05 08:48:08 -0700130 boolean storeTransitivePackagesForPackageRootResolution) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100131 this.buildViewProvider = buildViewProvider;
Greg Estren00049432015-08-25 16:43:47 +0000132 this.ruleClassProvider = ruleClassProvider;
janakr931d2852017-12-15 13:48:29 -0800133 this.storeTransitivePackagesForPackageRootResolution =
134 storeTransitivePackagesForPackageRootResolution;
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000135 }
136
nharmatabcd11ae2022-01-10 20:11:22 -0800137 static class State implements SkyKeyComputeState {
138 /** Null if AspectFuncton is not storing this information. */
139 @Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution;
140
141 NestedSetBuilder<Cause> transitiveRootCauses = NestedSetBuilder.stableOrder();
142
143 @Nullable InitialValues initialValues;
144
145 ComputeDependenciesState computeDependenciesState = new ComputeDependenciesState();
146
147 State(boolean storeTransitivePackagesForPackageRootResolution) {
148 this.transitivePackagesForPackageRootResolution =
149 storeTransitivePackagesForPackageRootResolution ? NestedSetBuilder.stableOrder() : null;
150 }
151 }
152
153 private static class InitialValues {
154 @Nullable private final Aspect aspect;
155 @Nullable private final ConfiguredAspectFactory aspectFactory;
156 @Nullable private final BuildConfigurationValue configuration;
157 private final ConfiguredTarget associatedTarget;
158 private final Target target;
159
160 private InitialValues(
161 @Nullable Aspect aspect,
162 @Nullable ConfiguredAspectFactory aspectFactory,
163 @Nullable BuildConfigurationValue configuration,
164 ConfiguredTarget associatedTarget,
165 Target target) {
166 this.aspect = aspect;
167 this.aspectFactory = aspectFactory;
168 this.configuration = configuration;
169 this.associatedTarget = associatedTarget;
170 this.target = target;
171 }
172 }
173
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100174 @Nullable
175 @Override
176 public SkyValue compute(SkyKey skyKey, Environment env)
Florian Weikert4b67d4f2015-09-14 13:35:34 +0000177 throws AspectFunctionException, InterruptedException {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100178 AspectKey key = (AspectKey) skyKey.argument();
nharmatabcd11ae2022-01-10 20:11:22 -0800179 State state = env.getState(() -> new State(storeTransitivePackagesForPackageRootResolution));
jhorvitzdb95cc42021-11-19 08:51:18 -0800180
nharmatabcd11ae2022-01-10 20:11:22 -0800181 if (state.initialValues == null) {
182 InitialValues initialValues = getInitialValues(key, env);
183 if (initialValues == null) {
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000184 return null;
185 }
nharmatabcd11ae2022-01-10 20:11:22 -0800186 state.initialValues = initialValues;
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000187 }
nharmatabcd11ae2022-01-10 20:11:22 -0800188 Aspect aspect = state.initialValues.aspect;
189 ConfiguredAspectFactory aspectFactory = state.initialValues.aspectFactory;
190 BuildConfigurationValue configuration = state.initialValues.configuration;
191 ConfiguredTarget associatedTarget = state.initialValues.associatedTarget;
192 Target target = state.initialValues.target;
dslomov99ea6b42017-04-25 17:46:17 +0200193
kmbb495a442021-08-25 19:45:28 -0700194 if (AliasProvider.isAlias(associatedTarget)) {
tomlu3d1a1942017-11-29 14:01:21 -0800195 return createAliasAspect(
196 env,
jhorvitz3cf2bca2021-11-23 14:29:10 -0800197 buildViewProvider.getSkyframeBuildView().getHostConfiguration(),
kmbb495a442021-08-25 19:45:28 -0700198 new TargetAndConfiguration(target, configuration),
tomlu3d1a1942017-11-29 14:01:21 -0800199 aspect,
200 key,
jhorvitz564a6892021-11-18 20:29:24 -0800201 configuration,
kmbb495a442021-08-25 19:45:28 -0700202 associatedTarget);
Lukacs Berkiea988b62016-08-30 12:26:18 +0000203 }
kmbb495a442021-08-25 19:45:28 -0700204 // If we get here, label should match original label, and therefore the target we looked up
205 // above indeed corresponds to associatedTarget.getLabel().
206 Preconditions.checkState(
207 associatedTarget.getOriginalLabel().equals(associatedTarget.getLabel()),
208 "Non-alias %s should have matching label but found %s",
209 associatedTarget.getOriginalLabel(),
210 associatedTarget.getLabel());
211
messa1bca1bd2021-05-14 00:48:19 -0700212 // If the incompatible flag is set, the top-level aspect should not be applied on top-level
213 // targets whose rules do not advertise the aspect's required providers. The aspect should not
214 // also propagate to these targets dependencies.
215 StarlarkSemantics starlarkSemantics = PrecomputedValue.STARLARK_SEMANTICS.get(env);
216 if (starlarkSemantics == null) {
217 return null;
218 }
219 boolean checkRuleAdvertisedProviders =
220 starlarkSemantics.getBool(
221 BuildLanguageOptions.INCOMPATIBLE_TOP_LEVEL_ASPECTS_REQUIRE_PROVIDERS);
222 if (checkRuleAdvertisedProviders) {
messa1bca1bd2021-05-14 00:48:19 -0700223 if (target instanceof Rule) {
224 if (!aspect
225 .getDefinition()
226 .getRequiredProviders()
227 .isSatisfiedBy(((Rule) target).getRuleClassObject().getAdvertisedProviders())) {
228 return new AspectValue(
229 key,
230 aspect,
231 target.getLocation(),
232 ConfiguredAspect.forNonapplicableTarget(),
jhorvitz564a6892021-11-18 20:29:24 -0800233 /*transitivePackagesForPackageRootResolution=*/ NestedSetBuilder.emptySet(
234 Order.STABLE_ORDER));
messa1bca1bd2021-05-14 00:48:19 -0700235 }
236 }
237 }
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000238
jhorvitz3cf2bca2021-11-23 14:29:10 -0800239 ImmutableList<Aspect> topologicalAspectPath;
240 if (key.getBaseKeys().isEmpty()) {
241 topologicalAspectPath = ImmutableList.of(aspect);
242 } else {
243 LinkedHashSet<AspectKey> orderedKeys = new LinkedHashSet<>();
244 collectAspectKeysInTopologicalOrder(key.getBaseKeys(), orderedKeys);
emilyguo21b0ba02022-03-16 17:07:40 -0700245 SkyframeLookupResult aspectValues = env.getValuesAndExceptions(orderedKeys);
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000246 if (env.valuesMissing()) {
247 return null;
248 }
jhorvitz3cf2bca2021-11-23 14:29:10 -0800249 ImmutableList.Builder<Aspect> topologicalAspectPathBuilder =
250 ImmutableList.builderWithExpectedSize(orderedKeys.size() + 1);
251 for (AspectKey aspectKey : orderedKeys) {
252 AspectValue aspectValue = (AspectValue) aspectValues.get(aspectKey);
emilyguo21b0ba02022-03-16 17:07:40 -0700253 if (aspectValue == null) {
emilyguo7222cab2022-04-19 13:32:09 -0700254 BugReport.logUnexpected(
255 "aspectValue for: '%s' was missing, this should never happen", aspectKey);
emilyguo21b0ba02022-03-16 17:07:40 -0700256 return null;
257 }
jhorvitz3cf2bca2021-11-23 14:29:10 -0800258 topologicalAspectPathBuilder.add(aspectValue.getAspect());
dslomov039b9ee2017-04-11 08:51:30 +0000259 }
jhorvitz3cf2bca2021-11-23 14:29:10 -0800260 topologicalAspectPath = topologicalAspectPathBuilder.add(aspect).build();
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000261
jhorvitz3cf2bca2021-11-23 14:29:10 -0800262 List<ConfiguredAspect> directlyRequiredAspects =
263 Lists.transform(
264 key.getBaseKeys(), k -> ((AspectValue) aspectValues.get(k)).getConfiguredAspect());
265 try {
266 associatedTarget = MergedConfiguredTarget.of(associatedTarget, directlyRequiredAspects);
267 } catch (DuplicateException e) {
268 env.getListener().handle(Event.error(target.getLocation(), e.getMessage()));
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000269 throw new AspectFunctionException(
jhorvitz3cf2bca2021-11-23 14:29:10 -0800270 new AspectCreationException(e.getMessage(), target.getLabel(), configuration));
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000271 }
272 }
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000273
jhorvitze68a7d02021-04-26 11:49:28 -0700274 SkyframeDependencyResolver resolver = new SkyframeDependencyResolver(env);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100275
jhorvitz564a6892021-11-18 20:29:24 -0800276 TargetAndConfiguration originalTargetAndConfiguration =
jhorvitz3cf2bca2021-11-23 14:29:10 -0800277 new TargetAndConfiguration(target, configuration);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100278 try {
Googler602b7cd2022-06-06 05:13:12 -0700279 ConfiguredTargetFunction.ComputedToolchainContexts computedToolchainContexts =
280 getUnloadedToolchainContexts(env, key, aspect, configuration);
Greg Estren12b06b22020-09-11 10:58:43 -0700281 if (env.valuesMissing()) {
282 return null;
283 }
284
Googler602b7cd2022-06-06 05:13:12 -0700285 ToolchainCollection<UnloadedToolchainContext> unloadedToolchainContexts = null;
286 ExecGroupCollection.Builder execGroupCollectionBuilder = null;
287 if (computedToolchainContexts != null) {
288 unloadedToolchainContexts = computedToolchainContexts.toolchainCollection;
289 execGroupCollectionBuilder = computedToolchainContexts.execGroupCollectionBuilder;
290 }
291
Greg Estren12b06b22020-09-11 10:58:43 -0700292 // Get the configuration targets that trigger this rule's configurable attributes.
gregce79989f92021-02-01 07:01:55 -0800293 ConfigConditions configConditions =
Greg Estren12b06b22020-09-11 10:58:43 -0700294 ConfiguredTargetFunction.getConfigConditions(
295 env,
jhorvitz564a6892021-11-18 20:29:24 -0800296 originalTargetAndConfiguration,
nharmata85e43802022-01-05 14:55:26 -0800297 state.transitivePackagesForPackageRootResolution,
Googler602b7cd2022-06-06 05:13:12 -0700298 unloadedToolchainContexts == null
299 ? null
300 : unloadedToolchainContexts.getTargetPlatform(),
nharmata85e43802022-01-05 14:55:26 -0800301 state.transitiveRootCauses);
Greg Estren12b06b22020-09-11 10:58:43 -0700302 if (configConditions == null) {
303 // Those targets haven't yet been resolved.
304 return null;
John Cater2e56f062017-07-20 19:43:20 +0200305 }
306
lberki102256f2019-02-08 01:34:23 -0800307 OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> depValueMap;
Dmitry Lomov9b2fc5c2016-11-11 11:18:48 +0000308 try {
John Cater2e56f062017-07-20 19:43:20 +0200309 depValueMap =
310 ConfiguredTargetFunction.computeDependencies(
nharmatabcd11ae2022-01-10 20:11:22 -0800311 state.computeDependenciesState,
312 state.transitivePackagesForPackageRootResolution,
313 state.transitiveRootCauses,
John Cater2e56f062017-07-20 19:43:20 +0200314 env,
315 resolver,
jhorvitz564a6892021-11-18 20:29:24 -0800316 originalTargetAndConfiguration,
jhorvitz3cf2bca2021-11-23 14:29:10 -0800317 topologicalAspectPath,
gregce79989f92021-02-01 07:01:55 -0800318 configConditions.asProviders(),
Googler602b7cd2022-06-06 05:13:12 -0700319 unloadedToolchainContexts == null
juliexxia71a80dc2020-04-09 09:07:09 -0700320 ? null
Googler602b7cd2022-06-06 05:13:12 -0700321 : unloadedToolchainContexts.asToolchainContexts(),
John Cater2e56f062017-07-20 19:43:20 +0200322 ruleClassProvider,
nharmata85e43802022-01-05 14:55:26 -0800323 buildViewProvider.getSkyframeBuildView().getHostConfiguration());
mschaller859c9ac2020-09-25 16:09:19 -0700324 } catch (ConfiguredValueCreationException e) {
325 throw new AspectCreationException(
jhorvitz564a6892021-11-18 20:29:24 -0800326 e.getMessage(), key.getLabel(), configuration, e.getDetailedExitCode());
Dmitry Lomov9b2fc5c2016-11-11 11:18:48 +0000327 }
Ulf Adams84901732016-01-28 15:05:16 +0000328 if (depValueMap == null) {
329 return null;
330 }
nharmata85e43802022-01-05 14:55:26 -0800331 if (!state.transitiveRootCauses.isEmpty()) {
332 NestedSet<Cause> causes = state.transitiveRootCauses.build();
Ulf Adams84901732016-01-28 15:05:16 +0000333 throw new AspectFunctionException(
mschaller859c9ac2020-09-25 16:09:19 -0700334 new AspectCreationException(
335 "Loading failed",
336 causes,
337 ConfiguredTargetFunction.getPrioritizedDetailedExitCode(causes)));
Ulf Adams84901732016-01-28 15:05:16 +0000338 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100339
John Caterae4e7852018-07-09 15:02:42 -0700340 // Load the requested toolchains into the ToolchainContext, now that we have dependencies.
Googler602b7cd2022-06-06 05:13:12 -0700341 ToolchainCollection<ResolvedToolchainContext> toolchainContexts = null;
342 if (unloadedToolchainContexts != null) {
John Cater50745142019-04-16 07:41:24 -0700343 String targetDescription =
344 String.format(
jhorvitz3cf2bca2021-11-23 14:29:10 -0800345 "aspect %s applied to %s", aspect.getDescriptor().getDescription(), target);
Googler602b7cd2022-06-06 05:13:12 -0700346 ToolchainCollection.Builder<ResolvedToolchainContext> contextsBuilder =
347 ToolchainCollection.builder();
348 for (Map.Entry<String, UnloadedToolchainContext> unloadedContext :
349 unloadedToolchainContexts.getContextMap().entrySet()) {
350 Set<ConfiguredTargetAndData> toolchainDependencies =
351 depValueMap.get(DependencyKind.forExecGroup(unloadedContext.getKey()));
352 contextsBuilder.addContext(
353 unloadedContext.getKey(),
354 ResolvedToolchainContext.load(
355 unloadedContext.getValue(), targetDescription, toolchainDependencies));
356 }
357 toolchainContexts = contextsBuilder.build();
John Caterae4e7852018-07-09 15:02:42 -0700358 }
359
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000360 return createAspect(
361 env,
362 key,
jhorvitz3cf2bca2021-11-23 14:29:10 -0800363 topologicalAspectPath,
Dmitry Lomov2eb8bdd2016-04-06 08:47:30 +0000364 aspect,
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000365 aspectFactory,
jhorvitz3cf2bca2021-11-23 14:29:10 -0800366 new ConfiguredTargetAndData(
367 associatedTarget, target, configuration, /*transitionKeys=*/ null),
jhorvitz564a6892021-11-18 20:29:24 -0800368 configuration,
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000369 configConditions,
Googler602b7cd2022-06-06 05:13:12 -0700370 toolchainContexts,
371 execGroupCollectionBuilder,
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000372 depValueMap,
nharmata85e43802022-01-05 14:55:26 -0800373 state.transitivePackagesForPackageRootResolution);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100374 } catch (DependencyEvaluationException e) {
gregcec5649772021-07-08 13:10:19 -0700375 // TODO(bazel-team): consolidate all env.getListener().handle() calls in this method, like in
376 // ConfiguredTargetFunction. This encourages clear, consistent user messages (ideally without
377 // the programmer having to think about it).
378 if (!e.depReportedOwnError()) {
379 env.getListener().handle(Event.error(e.getLocation(), e.getMessage()));
380 }
Ulf Adams25f03d82016-01-25 10:31:46 +0000381 if (e.getCause() instanceof ConfiguredValueCreationException) {
382 ConfiguredValueCreationException cause = (ConfiguredValueCreationException) e.getCause();
ulfjack904a8d62018-05-29 05:17:35 -0700383 throw new AspectFunctionException(
mschaller859c9ac2020-09-25 16:09:19 -0700384 new AspectCreationException(
385 cause.getMessage(), cause.getRootCauses(), cause.getDetailedExitCode()));
Dmitry Lomovd83af9e2017-02-23 15:44:23 +0000386 } else if (e.getCause() instanceof InconsistentAspectOrderException) {
387 InconsistentAspectOrderException cause = (InconsistentAspectOrderException) e.getCause();
gregcec5649772021-07-08 13:10:19 -0700388 env.getListener().handle(Event.error(cause.getLocation(), cause.getMessage()));
ulfjack904a8d62018-05-29 05:17:35 -0700389 throw new AspectFunctionException(
jhorvitz564a6892021-11-18 20:29:24 -0800390 new AspectCreationException(cause.getMessage(), key.getLabel(), configuration));
Samuel Giddinseadadbd2020-08-17 08:00:05 -0700391 } else if (e.getCause() instanceof TransitionException) {
392 TransitionException cause = (TransitionException) e.getCause();
393 throw new AspectFunctionException(
jhorvitz564a6892021-11-18 20:29:24 -0800394 new AspectCreationException(cause.getMessage(), key.getLabel(), configuration));
Ulf Adams25f03d82016-01-25 10:31:46 +0000395 } else {
396 // Cast to InvalidConfigurationException as a consistency check. If you add any
397 // DependencyEvaluationException constructors, you may need to change this code, too.
398 InvalidConfigurationException cause = (InvalidConfigurationException) e.getCause();
ulfjack904a8d62018-05-29 05:17:35 -0700399 throw new AspectFunctionException(
mschaller859c9ac2020-09-25 16:09:19 -0700400 new AspectCreationException(
jhorvitz564a6892021-11-18 20:29:24 -0800401 cause.getMessage(), key.getLabel(), configuration, cause.getDetailedExitCode()));
Ulf Adams25f03d82016-01-25 10:31:46 +0000402 }
Marian Loburfc567b32015-09-14 08:44:25 +0000403 } catch (AspectCreationException e) {
404 throw new AspectFunctionException(e);
gregcec5649772021-07-08 13:10:19 -0700405 } catch (ConfiguredValueCreationException e) {
406 throw new AspectFunctionException(e);
jcater3fed8692019-04-01 13:36:36 -0700407 } catch (ToolchainException e) {
408 throw new AspectFunctionException(
409 new AspectCreationException(
mschaller1511dd22020-09-21 14:19:33 -0700410 e.getMessage(), new LabelCause(key.getLabel(), e.getDetailedExitCode())));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100411 }
412 }
413
janakr9bb80c22022-03-30 10:18:33 -0700414 static BzlLoadValue.Key bzlLoadKeyForStarlarkAspect(StarlarkAspectClass starlarkAspectClass) {
jhorvitzdb95cc42021-11-19 08:51:18 -0800415 Label extensionLabel = starlarkAspectClass.getExtensionLabel();
416 return StarlarkBuiltinsValue.isBuiltinsRepo(extensionLabel.getRepository())
417 ? BzlLoadValue.keyForBuiltins(extensionLabel)
418 : BzlLoadValue.keyForBuild(extensionLabel);
419 }
420
nharmatabcd11ae2022-01-10 20:11:22 -0800421 @Nullable
422 private InitialValues getInitialValues(AspectKey key, Environment env)
423 throws AspectFunctionException, InterruptedException {
424 StarlarkAspectClass starlarkAspectClass;
425 ConfiguredAspectFactory aspectFactory = null;
426 Aspect aspect = null;
427
428 SkyKey aspectPackageKey = PackageValue.key(key.getLabel().getPackageIdentifier());
429 SkyKey baseConfiguredTargetKey = key.getBaseConfiguredTargetKey();
430 SkyKey basePackageKey =
431 PackageValue.key(key.getBaseConfiguredTargetKey().getLabel().getPackageIdentifier());
432 SkyKey configurationKey = key.getConfigurationKey();
janakr9bb80c22022-03-30 10:18:33 -0700433 BzlLoadValue.Key bzlLoadKey;
nharmatabcd11ae2022-01-10 20:11:22 -0800434
435 if (key.getAspectClass() instanceof NativeAspectClass) {
436 NativeAspectClass nativeAspectClass = (NativeAspectClass) key.getAspectClass();
437 starlarkAspectClass = null;
438 aspectFactory = (ConfiguredAspectFactory) nativeAspectClass;
439 aspect = Aspect.forNative(nativeAspectClass, key.getParameters());
440 bzlLoadKey = null;
441 } else {
442 Preconditions.checkState(
443 key.getAspectClass() instanceof StarlarkAspectClass, "Unknown aspect class: %s", key);
444 starlarkAspectClass = (StarlarkAspectClass) key.getAspectClass();
445 bzlLoadKey = bzlLoadKeyForStarlarkAspect(starlarkAspectClass);
446 }
447
448 ImmutableSet.Builder<SkyKey> initialKeys = ImmutableSet.builder();
449 initialKeys.add(aspectPackageKey).add(baseConfiguredTargetKey).add(basePackageKey);
450 if (configurationKey != null) {
451 initialKeys.add(configurationKey);
452 }
453 if (bzlLoadKey != null) {
454 initialKeys.add(bzlLoadKey);
455 }
emilyguo8ca657c2022-02-25 10:36:22 -0800456 SkyframeLookupResult initialValues = env.getValuesAndExceptions(initialKeys.build());
nharmatabcd11ae2022-01-10 20:11:22 -0800457 if (env.valuesMissing()) {
458 return null;
459 }
460
461 if (starlarkAspectClass != null) {
462 StarlarkDefinedAspect starlarkAspect;
463 try {
emilyguo8ca657c2022-02-25 10:36:22 -0800464 BzlLoadValue bzlLoadvalue;
465 try {
466 bzlLoadvalue =
467 (BzlLoadValue) initialValues.getOrThrow(bzlLoadKey, BzlLoadFailedException.class);
468 if (bzlLoadvalue == null) {
janakr9bb80c22022-03-30 10:18:33 -0700469 BugReport.logUnexpected(
470 "Unexpected exception with %s and AspectKey %s", bzlLoadKey, key);
emilyguo8ca657c2022-02-25 10:36:22 -0800471 return null;
472 }
473 } catch (BzlLoadFailedException e) {
474 throw new AspectCreationException(
475 e.getMessage(), starlarkAspectClass.getExtensionLabel(), e.getDetailedExitCode());
476 }
477 starlarkAspect = loadAspectFromBzl(starlarkAspectClass, bzlLoadvalue);
nharmatabcd11ae2022-01-10 20:11:22 -0800478 } catch (AspectCreationException e) {
479 env.getListener().handle(Event.error(e.getMessage()));
480 throw new AspectFunctionException(e);
481 }
482 aspectFactory = new StarlarkAspectFactory(starlarkAspect);
483 aspect =
484 Aspect.forStarlark(
485 starlarkAspect.getAspectClass(),
486 starlarkAspect.getDefinition(key.getParameters()),
487 key.getParameters());
488 }
489
490 // Keep this in sync with the same code in ConfiguredTargetFunction.
emilyguo8ca657c2022-02-25 10:36:22 -0800491 PackageValue aspectPackage = (PackageValue) initialValues.get(aspectPackageKey);
nharmatabcd11ae2022-01-10 20:11:22 -0800492 if (aspectPackage.getPackage().containsErrors()) {
493 throw new AspectFunctionException(
494 new BuildFileContainsErrorsException(key.getLabel().getPackageIdentifier()));
495 }
496
497 ConfiguredTargetValue baseConfiguredTargetValue;
498 try {
499 baseConfiguredTargetValue =
emilyguo8ca657c2022-02-25 10:36:22 -0800500 (ConfiguredTargetValue)
501 initialValues.getOrThrow(
502 baseConfiguredTargetKey, ConfiguredValueCreationException.class);
503 if (baseConfiguredTargetValue == null) {
janakr9bb80c22022-03-30 10:18:33 -0700504 BugReport.logUnexpected(
505 "Unexpected exception with %s and AspectKey %s", baseConfiguredTargetKey, key);
emilyguo8ca657c2022-02-25 10:36:22 -0800506 return null;
507 }
nharmatabcd11ae2022-01-10 20:11:22 -0800508 } catch (ConfiguredValueCreationException e) {
509 throw new AspectFunctionException(
510 new AspectCreationException(e.getMessage(), e.getRootCauses(), e.getDetailedExitCode()));
511 }
512
513 ConfiguredTarget associatedTarget = baseConfiguredTargetValue.getConfiguredTarget();
514 Preconditions.checkState(
515 Objects.equals(key.getConfigurationKey(), associatedTarget.getConfigurationKey()),
516 "Aspect not in same configuration as associated target: %s, %s",
517 key,
518 associatedTarget);
519
520 BuildConfigurationValue configuration =
521 configurationKey == null
522 ? null
emilyguo8ca657c2022-02-25 10:36:22 -0800523 : (BuildConfigurationValue) initialValues.get(configurationKey);
nharmatabcd11ae2022-01-10 20:11:22 -0800524
emilyguo8ca657c2022-02-25 10:36:22 -0800525 PackageValue basePackage = (PackageValue) initialValues.get(basePackageKey);
nharmatabcd11ae2022-01-10 20:11:22 -0800526 Target target;
527 try {
528 target = basePackage.getPackage().getTarget(associatedTarget.getOriginalLabel().getName());
529 } catch (NoSuchTargetException e) {
530 throw new IllegalStateException("Name already verified", e);
531 }
532
533 return new InitialValues(aspect, aspectFactory, configuration, associatedTarget, target);
534 }
535
jhorvitzdb95cc42021-11-19 08:51:18 -0800536 /**
537 * Loads a Starlark-defined aspect from an extension file.
538 *
539 * @throws AspectCreationException if the value loaded is not a {@link StarlarkDefinedAspect}
540 */
541 static StarlarkDefinedAspect loadAspectFromBzl(
542 StarlarkAspectClass starlarkAspectClass, BzlLoadValue bzlLoadValue)
543 throws AspectCreationException {
544 Label extensionLabel = starlarkAspectClass.getExtensionLabel();
545 String starlarkValueName = starlarkAspectClass.getExportedName();
546 Object starlarkValue = bzlLoadValue.getModule().getGlobal(starlarkValueName);
547 if (!(starlarkValue instanceof StarlarkDefinedAspect)) {
548 throw new AspectCreationException(
549 String.format(
550 starlarkValue == null ? "%s is not exported from %s" : "%s from %s is not an aspect",
551 starlarkValueName,
552 extensionLabel),
553 extensionLabel);
554 }
555 return (StarlarkDefinedAspect) starlarkValue;
556 }
557
558 @Nullable
Googler602b7cd2022-06-06 05:13:12 -0700559 private static ComputedToolchainContexts getUnloadedToolchainContexts(
jhorvitz33f76482021-10-28 10:13:26 -0700560 Environment env,
561 AspectKey key,
562 Aspect aspect,
563 @Nullable BuildConfigurationValue configuration)
kmbb495a442021-08-25 19:45:28 -0700564 throws InterruptedException, AspectCreationException {
Googler602b7cd2022-06-06 05:13:12 -0700565 if (configuration == null) {
kmbb495a442021-08-25 19:45:28 -0700566 // Configuration can be null in the case of aspects applied to input files. In this case,
567 // there are no chances of toolchains being used, so skip it.
kmbb495a442021-08-25 19:45:28 -0700568 return null;
569 }
Googler602b7cd2022-06-06 05:13:12 -0700570 // Determine what toolchains are needed by this target.
571 try {
572 return ConfiguredTargetFunction.computeUnloadedToolchainContexts(
573 env,
574 key.getLabel(),
575 true,
576 Predicates.alwaysFalse(),
577 configuration.getKey(),
578 aspect.getDefinition().getToolchainTypes(),
579 aspect.getDefinition().execCompatibleWith(),
580 aspect.getDefinition().execGroups(),
581 null);
582 } catch (ToolchainException e) {
583 // TODO(katre): better error handling
584 throw new AspectCreationException(
585 e.getMessage(), new LabelCause(key.getLabel(), e.getDetailedExitCode()));
586 }
kmbb495a442021-08-25 19:45:28 -0700587 }
588
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000589 /**
jhorvitz3cf2bca2021-11-23 14:29:10 -0800590 * Collects {@link AspectKey} dependencies by performing a postorder traversal over {@link
591 * AspectKey#getBaseKeys}.
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000592 *
jhorvitz3cf2bca2021-11-23 14:29:10 -0800593 * <p>The resulting set of {@code orderedKeys} is topologically ordered: each aspect key appears
594 * after all of its dependencies.
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000595 */
jhorvitz3cf2bca2021-11-23 14:29:10 -0800596 private static void collectAspectKeysInTopologicalOrder(
597 List<AspectKey> baseKeys, LinkedHashSet<AspectKey> orderedKeys) {
598 for (AspectKey key : baseKeys) {
599 if (!orderedKeys.contains(key)) {
600 collectAspectKeysInTopologicalOrder(key.getBaseKeys(), orderedKeys);
601 orderedKeys.add(key);
602 }
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000603 }
Dmitry Lomove851fe22017-02-14 23:11:23 +0000604 }
dslomovfa50c3d2017-05-08 08:47:44 -0400605
kmbb495a442021-08-25 19:45:28 -0700606 /**
607 * Computes the given aspectKey of an alias-like target, by depending on the corresponding key of
608 * the next target in the alias chain (if there are more), or the "real" configured target.
609 */
610 @Nullable
611 private AspectValue createAliasAspect(
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000612 Environment env,
jhorvitz33f76482021-10-28 10:13:26 -0700613 BuildConfigurationValue hostConfiguration,
kmbb495a442021-08-25 19:45:28 -0700614 TargetAndConfiguration originalTarget,
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000615 Aspect aspect,
Lukacs Berkiea988b62016-08-30 12:26:18 +0000616 AspectKey originalKey,
jhorvitz33f76482021-10-28 10:13:26 -0700617 BuildConfigurationValue aspectConfiguration,
janakr93e3eea2017-03-30 22:09:37 +0000618 ConfiguredTarget configuredTarget)
kmbb495a442021-08-25 19:45:28 -0700619 throws AspectFunctionException, InterruptedException {
620 ImmutableList<Label> aliasChain =
621 configuredTarget.getProvider(AliasProvider.class).getAliasChain();
Lukacs Berkiea988b62016-08-30 12:26:18 +0000622 // Find the next alias in the chain: either the next alias (if there are two) or the name of
623 // the real configured target.
kmbb495a442021-08-25 19:45:28 -0700624 Label aliasedLabel = aliasChain.size() > 1 ? aliasChain.get(1) : configuredTarget.getLabel();
Lukacs Berkiea988b62016-08-30 12:26:18 +0000625
kmbb495a442021-08-25 19:45:28 -0700626 NestedSetBuilder<Package> transitivePackagesForPackageRootResolution =
627 storeTransitivePackagesForPackageRootResolution ? NestedSetBuilder.stableOrder() : null;
628 NestedSetBuilder<Cause> transitiveRootCauses = NestedSetBuilder.stableOrder();
629
630 // Compute the Dependency from originalTarget to aliasedLabel
631 Dependency dep;
632 try {
Googler602b7cd2022-06-06 05:13:12 -0700633 ConfiguredTargetFunction.ComputedToolchainContexts computedToolchainContexts =
634 getUnloadedToolchainContexts(env, originalKey, aspect, originalTarget.getConfiguration());
kmbb495a442021-08-25 19:45:28 -0700635 if (env.valuesMissing()) {
636 return null;
637 }
638
Googler602b7cd2022-06-06 05:13:12 -0700639 ToolchainCollection<UnloadedToolchainContext> unloadedToolchainContexts =
640 computedToolchainContexts.toolchainCollection;
641
kmbb495a442021-08-25 19:45:28 -0700642 // See comment in compute() above for why we pair target with aspectConfiguration here
643 TargetAndConfiguration originalTargetAndAspectConfiguration =
644 new TargetAndConfiguration(originalTarget.getTarget(), aspectConfiguration);
645
646 // Get the configuration targets that trigger this rule's configurable attributes.
647 ConfigConditions configConditions =
648 ConfiguredTargetFunction.getConfigConditions(
649 env,
650 originalTargetAndAspectConfiguration,
651 transitivePackagesForPackageRootResolution,
Googler602b7cd2022-06-06 05:13:12 -0700652 unloadedToolchainContexts == null
653 ? null
654 : unloadedToolchainContexts.getTargetPlatform(),
kmbb495a442021-08-25 19:45:28 -0700655 transitiveRootCauses);
656 if (configConditions == null) {
657 // Those targets haven't yet been resolved.
658 return null;
659 }
660
661 Target aliasedTarget = getTargetFromLabel(env, aliasedLabel);
662 if (aliasedTarget == null) {
663 return null;
664 }
665 ConfigurationTransition transition =
666 TransitionResolver.evaluateTransition(
667 aspectConfiguration,
668 NoTransition.INSTANCE,
669 aliasedTarget,
670 ((ConfiguredRuleClassProvider) ruleClassProvider).getTrimmingTransitionFactory());
671
672 // Use ConfigurationResolver to apply any configuration transitions on the alias edge.
673 // This is a shortened/simplified variant of ConfiguredTargetFunction.computeDependencies
674 // for just the one special attribute we care about here.
675 DependencyKey depKey =
676 DependencyKey.builder().setLabel(aliasedLabel).setTransition(transition).build();
677 DependencyKind depKind =
678 DependencyKind.AttributeDependencyKind.forRule(
679 getAttributeContainingAlias(originalTarget.getTarget()));
680 ConfigurationResolver resolver =
681 new ConfigurationResolver(
682 env,
683 originalTargetAndAspectConfiguration,
684 hostConfiguration,
685 configConditions.asProviders());
nharmata85e43802022-01-05 14:55:26 -0800686 ImmutableList<Dependency> deps =
687 resolver.resolveConfiguration(depKind, depKey, env.getListener());
kmbb495a442021-08-25 19:45:28 -0700688 if (deps == null) {
689 return null;
690 }
691 // Actual should resolve to exactly one dependency
692 Preconditions.checkState(
693 deps.size() == 1, "Unexpected split in alias %s: %s", originalTarget.getLabel(), deps);
694 dep = deps.get(0);
695 } catch (NoSuchPackageException | NoSuchTargetException e) {
696 throw new AspectFunctionException(e);
697 } catch (ConfiguredValueCreationException e) {
698 throw new AspectFunctionException(e);
699 } catch (AspectCreationException e) {
700 throw new AspectFunctionException(e);
701 }
702
703 if (!transitiveRootCauses.isEmpty()) {
704 NestedSet<Cause> causes = transitiveRootCauses.build();
705 throw new AspectFunctionException(
706 new AspectCreationException(
707 "Loading failed",
708 causes,
709 ConfiguredTargetFunction.getPrioritizedDetailedExitCode(causes)));
710 }
711
712 // Now that we have a Dependency, we can compute the aliased key and depend on it
713 AspectKey actualKey = buildAliasAspectKey(originalKey, aliasedLabel, dep);
714 return createAliasAspect(
715 env,
716 originalTarget.getTarget(),
717 originalKey,
718 aspect,
719 actualKey,
720 transitivePackagesForPackageRootResolution);
cparsons089148b2019-09-17 08:14:41 -0700721 }
722
Googler5cc598c2022-07-06 03:29:45 -0700723 @Nullable
jhorvitz86409b72021-10-04 16:55:20 -0700724 private static AspectValue createAliasAspect(
cparsons089148b2019-09-17 08:14:41 -0700725 Environment env,
726 Target originalTarget,
cparsons089148b2019-09-17 08:14:41 -0700727 AspectKey originalKey,
kmbb495a442021-08-25 19:45:28 -0700728 Aspect aspect,
729 AspectKey depKey,
730 @Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution)
cparsons089148b2019-09-17 08:14:41 -0700731 throws InterruptedException {
Lukacs Berkiea988b62016-08-30 12:26:18 +0000732 // Compute the AspectValue of the target the alias refers to (which can itself be either an
733 // alias or a real target)
Lukacs Berki549bfce2016-04-22 15:29:12 +0000734 AspectValue real = (AspectValue) env.getValue(depKey);
735 if (env.valuesMissing()) {
736 return null;
737 }
738
kmbb495a442021-08-25 19:45:28 -0700739 NestedSet<Package> finalTransitivePackagesForPackageRootResolution = null;
740 if (transitivePackagesForPackageRootResolution != null) {
741 finalTransitivePackagesForPackageRootResolution =
742 transitivePackagesForPackageRootResolution
743 .addTransitive(real.getTransitivePackagesForPackageRootResolution())
744 .add(originalTarget.getPackage())
745 .build();
746 }
Lukacs Berki549bfce2016-04-22 15:29:12 +0000747 return new AspectValue(
748 originalKey,
749 aspect,
Lukacs Berki549bfce2016-04-22 15:29:12 +0000750 originalTarget.getLocation(),
751 ConfiguredAspect.forAlias(real.getConfiguredAspect()),
kmbb495a442021-08-25 19:45:28 -0700752 finalTransitivePackagesForPackageRootResolution);
753 }
754
755 @Nullable
756 private static Target getTargetFromLabel(Environment env, Label aliasLabel)
757 throws InterruptedException, NoSuchPackageException, NoSuchTargetException {
758 SkyValue val =
759 env.getValueOrThrow(
760 PackageValue.key(aliasLabel.getPackageIdentifier()), NoSuchPackageException.class);
761 if (val == null) {
762 return null;
763 }
764
765 Package pkg = ((PackageValue) val).getPackage();
766 return pkg.getTarget(aliasLabel.getName());
767 }
768
769 private static AspectKey buildAliasAspectKey(
770 AspectKey originalKey, Label aliasLabel, Dependency dep) {
771 ImmutableList<AspectKey> aliasedBaseKeys =
772 originalKey.getBaseKeys().stream()
773 .map(baseKey -> buildAliasAspectKey(baseKey, aliasLabel, dep))
774 .collect(toImmutableList());
lebab52a1902021-09-23 01:35:13 -0700775 return AspectKeyCreator.createAspectKey(
kmbb495a442021-08-25 19:45:28 -0700776 originalKey.getAspectDescriptor(),
jhorvitz564a6892021-11-18 20:29:24 -0800777 aliasedBaseKeys,
778 ConfiguredTargetKey.builder()
779 .setLabel(aliasLabel)
780 .setConfiguration(dep.getConfiguration())
781 .build());
kmbb495a442021-08-25 19:45:28 -0700782 }
783
784 /**
785 * Given an alias-like target, returns the attribute containing the "actual", by looking for
786 * attribute names used in known alias rules (Alias, Bind, LateBoundAlias, XcodeConfigAlias).
787 *
788 * <p>Alias and Bind rules use "actual", which will be by far the most common match here. It'll
789 * likely be rare that aspects need to traverse across other alias-like rules.
790 */
791 // TODO(lberki,kmb): try to avoid this, maybe by recording the attribute name in AliasProvider
792 private static Attribute getAttributeContainingAlias(Target originalTarget) {
793 Attribute aliasAttr = null;
794 for (Attribute attr : originalTarget.getAssociatedRule().getAttributes()) {
795 switch (attr.getName()) {
796 case "actual": // alias and bind rules
797 case ":alias": // LateBoundAlias-derived rules
798 case ":xcode_config": // xcode_config_alias rule
799 Preconditions.checkState(
800 aliasAttr == null,
801 "Found multiple candidate attributes %s and %s in %s",
802 aliasAttr,
803 attr,
804 originalTarget);
805 aliasAttr = attr;
806 break;
807 default:
808 break;
809 }
810 }
811 Preconditions.checkState(
812 aliasAttr != null, "Attribute containing alias not found in %s", originalTarget);
813 return aliasAttr;
Lukacs Berki549bfce2016-04-22 15:29:12 +0000814 }
815
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100816 @Nullable
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000817 private AspectValue createAspect(
818 Environment env,
819 AspectKey key,
jhorvitz3cf2bca2021-11-23 14:29:10 -0800820 ImmutableList<Aspect> topologicalAspectPath,
Dmitry Lomov2eb8bdd2016-04-06 08:47:30 +0000821 Aspect aspect,
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000822 ConfiguredAspectFactory aspectFactory,
janakr9c101402018-03-10 06:48:59 -0800823 ConfiguredTargetAndData associatedTarget,
jhorvitz564a6892021-11-18 20:29:24 -0800824 BuildConfigurationValue configuration,
gregce79989f92021-02-01 07:01:55 -0800825 ConfigConditions configConditions,
Googler602b7cd2022-06-06 05:13:12 -0700826 @Nullable ToolchainCollection<ResolvedToolchainContext> toolchainContexts,
827 @Nullable ExecGroupCollection.Builder execGroupCollectionBuilder,
lberki102256f2019-02-08 01:34:23 -0800828 OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> directDeps,
janakr931d2852017-12-15 13:48:29 -0800829 @Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution)
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000830 throws AspectFunctionException, InterruptedException {
brandjon66b64632020-12-17 14:11:32 -0800831 // Should be successfully evaluated and cached from the loading phase.
832 StarlarkBuiltinsValue starlarkBuiltinsValue =
833 (StarlarkBuiltinsValue) env.getValue(StarlarkBuiltinsValue.key());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100834 if (env.valuesMissing()) {
835 return null;
836 }
837
brandjon66b64632020-12-17 14:11:32 -0800838 SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
839
840 StoredEventHandler events = new StoredEventHandler();
841 CachingAnalysisEnvironment analysisEnvironment =
jhorvitz564a6892021-11-18 20:29:24 -0800842 view.createAnalysisEnvironment(key, events, env, configuration, starlarkBuiltinsValue);
brandjon66b64632020-12-17 14:11:32 -0800843
Dmitry Lomov6cd98972017-03-01 15:44:00 +0000844 ConfiguredAspect configuredAspect;
cparsons089148b2019-09-17 08:14:41 -0700845 if (aspect.getDefinition().applyToGeneratingRules()
846 && associatedTarget.getTarget() instanceof OutputFile) {
847 OutputFile outputFile = (OutputFile) associatedTarget.getTarget();
848 Label label = outputFile.getGeneratingRule().getLabel();
kmbb495a442021-08-25 19:45:28 -0700849 return createAliasAspect(
850 env,
851 associatedTarget.getTarget(),
852 key,
853 aspect,
854 key.withLabel(label),
855 transitivePackagesForPackageRootResolution);
cparsons089148b2019-09-17 08:14:41 -0700856 } else if (AspectResolver.aspectMatchesConfiguredTarget(associatedTarget, aspect)) {
tomlu72642a22017-10-18 06:23:14 +0200857 try {
858 CurrentRuleTracker.beginConfiguredAspect(aspect.getAspectClass());
859 configuredAspect =
860 view.getConfiguredTargetFactory()
861 .createAspect(
862 analysisEnvironment,
863 associatedTarget,
jhorvitz3cf2bca2021-11-23 14:29:10 -0800864 topologicalAspectPath,
tomlu72642a22017-10-18 06:23:14 +0200865 aspectFactory,
866 aspect,
867 directDeps,
868 configConditions,
Googler602b7cd2022-06-06 05:13:12 -0700869 toolchainContexts,
870 execGroupCollectionBuilder,
jhorvitz564a6892021-11-18 20:29:24 -0800871 configuration,
jhorvitz86409b72021-10-04 16:55:20 -0700872 view.getHostConfiguration(),
janakreaff19c2019-01-31 13:59:40 -0800873 key);
ulfjack37407682019-09-17 06:30:49 -0700874 } catch (MissingDepException e) {
875 Preconditions.checkState(env.valuesMissing());
876 return null;
jcater0b385bd2020-04-08 15:27:07 -0700877 } catch (ActionConflictException e) {
878 throw new AspectFunctionException(e);
juliexxia6fe70c22020-05-18 14:38:42 -0700879 } catch (InvalidExecGroupException e) {
880 throw new AspectFunctionException(e);
tomlu72642a22017-10-18 06:23:14 +0200881 } finally {
882 CurrentRuleTracker.endConfiguredAspect();
883 }
Dmitry Lomov6cd98972017-03-01 15:44:00 +0000884 } else {
janakrf15d08d2020-04-22 12:53:03 -0700885 configuredAspect = ConfiguredAspect.forNonapplicableTarget();
Dmitry Lomov6cd98972017-03-01 15:44:00 +0000886 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100887
888 events.replayOn(env.getListener());
889 if (events.hasErrors()) {
890 analysisEnvironment.disable(associatedTarget.getTarget());
janakr043acd92020-02-28 18:59:06 -0800891 String msg = "Analysis of target '" + associatedTarget.getTarget().getLabel() + "' failed";
janakrf3e6f252018-01-18 07:45:12 -0800892 throw new AspectFunctionException(
jhorvitz564a6892021-11-18 20:29:24 -0800893 new AspectCreationException(msg, key.getLabel(), configuration));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100894 }
895 Preconditions.checkState(!analysisEnvironment.hasErrors(),
896 "Analysis environment hasError() but no errors reported");
897
898 if (env.valuesMissing()) {
899 return null;
900 }
901
902 analysisEnvironment.disable(associatedTarget.getTarget());
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000903 Preconditions.checkNotNull(configuredAspect);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100904
905 return new AspectValue(
Dmitry Lomove2033b12015-08-19 16:57:49 +0000906 key,
Dmitry Lomov2eb8bdd2016-04-06 08:47:30 +0000907 aspect,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000908 associatedTarget.getTarget().getLocation(),
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000909 configuredAspect,
janakr931d2852017-12-15 13:48:29 -0800910 transitivePackagesForPackageRootResolution == null
911 ? null
Googlerce6ad292019-12-20 10:29:21 -0800912 : transitivePackagesForPackageRootResolution.build());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100913 }
914
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100915 @Override
916 public String extractTag(SkyKey skyKey) {
Michael Staib2707a882016-09-16 21:06:40 +0000917 AspectKey aspectKey = (AspectKey) skyKey.argument();
918 return Label.print(aspectKey.getLabel());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100919 }
Marian Loburc62faba2015-09-09 10:08:06 +0000920
tomlu39a0a382018-06-22 09:43:23 -0700921 /** Used to indicate errors during the computation of an {@link AspectValue}. */
922 public static final class AspectFunctionException extends SkyFunctionException {
Ulf Adams9e16f0a2016-01-25 12:43:32 +0000923 public AspectFunctionException(NoSuchThingException e) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100924 super(e, Transience.PERSISTENT);
925 }
926
Ulf Adams9e16f0a2016-01-25 12:43:32 +0000927 public AspectFunctionException(AspectCreationException e) {
928 super(e, Transience.PERSISTENT);
Ulf Adamsd55d7af2016-01-19 11:03:22 +0000929 }
Dmitry Lomovd83af9e2017-02-23 15:44:23 +0000930
gregcec5649772021-07-08 13:10:19 -0700931 public AspectFunctionException(ConfiguredValueCreationException e) {
932 super(e, Transience.PERSISTENT);
933 }
934
juliexxia6fe70c22020-05-18 14:38:42 -0700935 public AspectFunctionException(InvalidExecGroupException e) {
936 super(e, Transience.PERSISTENT);
937 }
938
janakr0175ce32018-02-26 15:54:57 -0800939 public AspectFunctionException(ActionConflictException cause) {
Dmitry Lomovd83af9e2017-02-23 15:44:23 +0000940 super(cause, Transience.PERSISTENT);
941 }
Ulf Adamsd55d7af2016-01-19 11:03:22 +0000942 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100943}