blob: 2633d473afdea4779f0440f88f10b559bd493b99 [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;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010020import com.google.common.collect.ImmutableList;
Lukacs Berki7894c182016-05-10 12:07:01 +000021import com.google.common.collect.ImmutableMap;
cpeyserfb829992017-09-07 17:17:03 +020022import com.google.common.collect.ImmutableSet;
janakr0175ce32018-02-26 15:54:57 -080023import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
ulfjack90e2e982017-08-07 11:27:32 +020024import com.google.devtools.build.lib.analysis.AliasProvider;
gregce4c3ef112017-09-20 23:43:14 +020025import com.google.devtools.build.lib.analysis.AspectResolver;
jcater44c99422020-04-20 15:52:18 -070026import com.google.devtools.build.lib.analysis.AspectValue;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010027import com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment;
ulfjack37407682019-09-17 06:30:49 -070028import com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment.MissingDepException;
Dmitry Lomovb487ac62015-11-09 13:09:12 +000029import com.google.devtools.build.lib.analysis.ConfiguredAspect;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010030import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory;
kmbb495a442021-08-25 19:45:28 -070031import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010032import com.google.devtools.build.lib.analysis.ConfiguredTarget;
janakr876deaa2021-02-17 07:49:48 -080033import com.google.devtools.build.lib.analysis.ConfiguredTargetValue;
kmbb495a442021-08-25 19:45:28 -070034import com.google.devtools.build.lib.analysis.Dependency;
35import com.google.devtools.build.lib.analysis.DependencyKey;
jcaterdad2dd32020-04-13 08:31:58 -070036import com.google.devtools.build.lib.analysis.DependencyKind;
jcater84ca5562020-04-06 14:35:46 -070037import com.google.devtools.build.lib.analysis.DuplicateException;
jcater645c42b2021-05-12 09:35:48 -070038import com.google.devtools.build.lib.analysis.ExecGroupCollection.InvalidExecGroupException;
jcaterdad2dd32020-04-13 08:31:58 -070039import com.google.devtools.build.lib.analysis.InconsistentAspectOrderException;
jcaterbc4ef8c2020-06-16 13:58:01 -070040import com.google.devtools.build.lib.analysis.PlatformOptions;
John Catercdfa9ca2019-04-05 12:32:09 -070041import com.google.devtools.build.lib.analysis.ResolvedToolchainContext;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010042import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
juliexxia71a80dc2020-04-09 09:07:09 -070043import com.google.devtools.build.lib.analysis.ToolchainCollection;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010044import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
gregce79989f92021-02-01 07:01:55 -080045import com.google.devtools.build.lib.analysis.config.ConfigConditions;
kmbb495a442021-08-25 19:45:28 -070046import com.google.devtools.build.lib.analysis.config.ConfigurationResolver;
jcater67181912020-04-08 10:46:29 -070047import com.google.devtools.build.lib.analysis.config.DependencyEvaluationException;
Ulf Adams25f03d82016-01-25 10:31:46 +000048import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
kmbb495a442021-08-25 19:45:28 -070049import com.google.devtools.build.lib.analysis.config.TransitionResolver;
50import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition;
51import com.google.devtools.build.lib.analysis.config.transitions.NoTransition;
gregce2aee44b2017-09-16 07:16:44 +020052import com.google.devtools.build.lib.analysis.configuredtargets.MergedConfiguredTarget;
Samuel Giddinseadadbd2020-08-17 08:00:05 -070053import com.google.devtools.build.lib.analysis.starlark.StarlarkTransition.TransitionException;
ulfjack904a8d62018-05-29 05:17:35 -070054import com.google.devtools.build.lib.causes.Cause;
55import com.google.devtools.build.lib.causes.LabelCause;
John Fielda97e17f2015-11-13 02:19:52 +000056import com.google.devtools.build.lib.cmdline.Label;
Ulf Adams84901732016-01-28 15:05:16 +000057import com.google.devtools.build.lib.collect.nestedset.NestedSet;
Marian Loburc62faba2015-09-09 10:08:06 +000058import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Ulf Adams9e16f0a2016-01-25 12:43:32 +000059import com.google.devtools.build.lib.events.Event;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010060import com.google.devtools.build.lib.events.StoredEventHandler;
Dmitry Lomov2eb8bdd2016-04-06 08:47:30 +000061import com.google.devtools.build.lib.packages.Aspect;
jcaterbc4ef8c2020-06-16 13:58:01 -070062import com.google.devtools.build.lib.packages.AspectDefinition;
Dmitry Lomove851fe22017-02-14 23:11:23 +000063import com.google.devtools.build.lib.packages.AspectDescriptor;
kmbb495a442021-08-25 19:45:28 -070064import com.google.devtools.build.lib.packages.Attribute;
Janak Ramakrishnan0a4c6e42015-09-17 00:37:58 +000065import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException;
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +000066import com.google.devtools.build.lib.packages.NativeAspectClass;
kmbb495a442021-08-25 19:45:28 -070067import com.google.devtools.build.lib.packages.NoSuchPackageException;
janakrf3e6f252018-01-18 07:45:12 -080068import com.google.devtools.build.lib.packages.NoSuchTargetException;
Ulf Adamsd55d7af2016-01-19 11:03:22 +000069import com.google.devtools.build.lib.packages.NoSuchThingException;
cparsons089148b2019-09-17 08:14:41 -070070import com.google.devtools.build.lib.packages.OutputFile;
Marian Loburc62faba2015-09-09 10:08:06 +000071import com.google.devtools.build.lib.packages.Package;
messa1bca1bd2021-05-14 00:48:19 -070072import com.google.devtools.build.lib.packages.Rule;
Greg Estren00049432015-08-25 16:43:47 +000073import com.google.devtools.build.lib.packages.RuleClassProvider;
gregce18694cd2020-05-12 15:40:05 -070074import com.google.devtools.build.lib.packages.StarlarkAspectClass;
gregced281df72020-05-11 12:27:06 -070075import com.google.devtools.build.lib.packages.StarlarkDefinedAspect;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010076import com.google.devtools.build.lib.packages.Target;
Googlerc5fcc862019-09-06 16:17:47 -070077import com.google.devtools.build.lib.packages.Type.ConversionException;
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;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010082import com.google.devtools.build.lib.skyframe.SkyframeExecutor.BuildViewProvider;
Greg Estrend5353252016-08-11 22:13:31 +000083import com.google.devtools.build.lib.util.OrderedSetMultimap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010084import com.google.devtools.build.skyframe.SkyFunction;
85import com.google.devtools.build.skyframe.SkyFunctionException;
86import com.google.devtools.build.skyframe.SkyKey;
87import com.google.devtools.build.skyframe.SkyValue;
cpeysera8a61ee2018-01-26 09:20:37 -080088import com.google.devtools.build.skyframe.ValueOrException;
Dmitry Lomovca9bfa42016-11-15 13:22:36 +000089import java.util.ArrayList;
Dmitry Lomove851fe22017-02-14 23:11:23 +000090import java.util.HashMap;
Dmitry Lomovca9bfa42016-11-15 13:22:36 +000091import java.util.Map;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010092import javax.annotation.Nullable;
messa1bca1bd2021-05-14 00:48:19 -070093import net.starlark.java.eval.StarlarkSemantics;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010094
95/**
96 * The Skyframe function that generates aspects.
Dmitry Lomove8040172016-04-06 14:53:43 +000097 *
jhorvitz81395032021-05-05 08:48:08 -070098 * <p>This class, together with {@link ConfiguredTargetFunction} drives the analysis phase. For more
ulfjack26d0e492017-08-07 13:42:33 +020099 * information, see {@link com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory}.
Lukacs Berki2300cd62016-05-19 11:06:37 +0000100 *
jhorvitz81395032021-05-05 08:48:08 -0700101 * <p>{@link AspectFunction} takes a SkyKey containing an {@link AspectKey} [a tuple of (target
102 * label, configurations, aspect class and aspect parameters)], loads an {@link Aspect} from aspect
103 * class and aspect parameters, gets a {@link ConfiguredTarget} for label and configurations, and
104 * then creates a {@link ConfiguredAspect} for a given {@link AspectKey}.
Dmitry Lomove8040172016-04-06 14:53:43 +0000105 *
jhorvitz81395032021-05-05 08:48:08 -0700106 * <p>See {@link com.google.devtools.build.lib.packages.AspectClass} documentation for an overview
107 * of aspect-related classes
Lukacs Berki2300cd62016-05-19 11:06:37 +0000108 *
ulfjack26d0e492017-08-07 13:42:33 +0200109 * @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory
Lukacs Berki2300cd62016-05-19 11:06:37 +0000110 * @see com.google.devtools.build.lib.packages.AspectClass
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100111 */
jhorvitz81395032021-05-05 08:48:08 -0700112final class AspectFunction implements SkyFunction {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100113 private final BuildViewProvider buildViewProvider;
Greg Estren00049432015-08-25 16:43:47 +0000114 private final RuleClassProvider ruleClassProvider;
janakr931d2852017-12-15 13:48:29 -0800115 /**
116 * Indicates whether the set of packages transitively loaded for a given {@link AspectValue} will
117 * be needed for package root resolution later in the build. If not, they are not collected and
118 * stored.
119 */
120 private final boolean storeTransitivePackagesForPackageRootResolution;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100121
janakr93e3eea2017-03-30 22:09:37 +0000122 AspectFunction(
123 BuildViewProvider buildViewProvider,
124 RuleClassProvider ruleClassProvider,
jhorvitz81395032021-05-05 08:48:08 -0700125 boolean storeTransitivePackagesForPackageRootResolution) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100126 this.buildViewProvider = buildViewProvider;
Greg Estren00049432015-08-25 16:43:47 +0000127 this.ruleClassProvider = ruleClassProvider;
janakr931d2852017-12-15 13:48:29 -0800128 this.storeTransitivePackagesForPackageRootResolution =
129 storeTransitivePackagesForPackageRootResolution;
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000130 }
131
132 /**
gregce3377c112020-04-13 09:29:59 -0700133 * Load Starlark-defined aspect from an extension file. Is to be called from a SkyFunction.
cparsons0d55f4c2017-12-20 14:49:13 -0800134 *
135 * @return {@code null} if dependencies cannot be satisfied.
gregced281df72020-05-11 12:27:06 -0700136 * @throws AspectCreationException if the value loaded is not a {@link StarlarkDefinedAspect}.
cparsons0d55f4c2017-12-20 14:49:13 -0800137 */
138 @Nullable
messaba64b032021-09-17 15:15:44 -0700139 public static StarlarkDefinedAspect loadStarlarkDefinedAspect(
gregce18694cd2020-05-12 15:40:05 -0700140 Environment env, StarlarkAspectClass starlarkAspectClass)
cparsons0d55f4c2017-12-20 14:49:13 -0800141 throws AspectCreationException, InterruptedException {
gregced281df72020-05-11 12:27:06 -0700142 Label extensionLabel = starlarkAspectClass.getExtensionLabel();
143 String starlarkValueName = starlarkAspectClass.getExportedName();
cparsons0d55f4c2017-12-20 14:49:13 -0800144
cmita961b1762021-05-25 03:04:22 -0700145 SkyKey importFileKey =
146 StarlarkBuiltinsValue.isBuiltinsRepo(extensionLabel.getRepository())
147 ? BzlLoadValue.keyForBuiltins(extensionLabel)
148 : BzlLoadValue.keyForBuild(extensionLabel);
Ulf Adams0678e792016-01-25 15:30:45 +0000149 try {
brandjon771a0292020-05-26 12:04:16 -0700150 BzlLoadValue bzlLoadValue =
151 (BzlLoadValue) env.getValueOrThrow(importFileKey, BzlLoadFailedException.class);
152 if (bzlLoadValue == null) {
cpeyser10798092018-03-23 12:10:25 -0700153 Preconditions.checkState(
laurentlb7dcad732018-10-25 05:17:20 -0700154 env.valuesMissing(), "no Starlark import value for %s", importFileKey);
Ulf Adams0678e792016-01-25 15:30:45 +0000155 return null;
156 }
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000157
brandjon771a0292020-05-26 12:04:16 -0700158 Object starlarkValue = bzlLoadValue.getModule().getGlobal(starlarkValueName);
gregced281df72020-05-11 12:27:06 -0700159 if (starlarkValue == null) {
Dmitry Lomov1920dd92017-07-21 12:57:18 +0200160 throw new ConversionException(
jhorvitz86409b72021-10-04 16:55:20 -0700161 String.format("%s is not exported from %s", starlarkValueName, extensionLabel));
Dmitry Lomov1920dd92017-07-21 12:57:18 +0200162 }
messaba64b032021-09-17 15:15:44 -0700163 if (!(starlarkValue instanceof StarlarkDefinedAspect)) {
Ulf Adams0678e792016-01-25 15:30:45 +0000164 throw new ConversionException(
messaba64b032021-09-17 15:15:44 -0700165 String.format("%s from %s is not an aspect", starlarkValueName, extensionLabel));
Ulf Adams0678e792016-01-25 15:30:45 +0000166 }
messaba64b032021-09-17 15:15:44 -0700167 return (StarlarkDefinedAspect) starlarkValue;
mschaller859c9ac2020-09-25 16:09:19 -0700168 } catch (BzlLoadFailedException e) {
169 env.getListener().handle(Event.error(e.getMessage()));
170 throw new AspectCreationException(e.getMessage(), extensionLabel, e.getDetailedExitCode());
171 } catch (ConversionException e) {
Ulf Adams0678e792016-01-25 15:30:45 +0000172 env.getListener().handle(Event.error(e.getMessage()));
ulfjack904a8d62018-05-29 05:17:35 -0700173 throw new AspectCreationException(e.getMessage(), extensionLabel);
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000174 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100175 }
176
177 @Nullable
178 @Override
179 public SkyValue compute(SkyKey skyKey, Environment env)
Florian Weikert4b67d4f2015-09-14 13:35:34 +0000180 throws AspectFunctionException, InterruptedException {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100181 SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
ulfjack904a8d62018-05-29 05:17:35 -0700182 NestedSetBuilder<Cause> transitiveRootCauses = NestedSetBuilder.stableOrder();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100183 AspectKey key = (AspectKey) skyKey.argument();
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000184 ConfiguredAspectFactory aspectFactory;
Dmitry Lomov2eb8bdd2016-04-06 08:47:30 +0000185 Aspect aspect;
Luis Fernando Pino Duquee82713d2016-04-26 16:22:38 +0000186 if (key.getAspectClass() instanceof NativeAspectClass) {
187 NativeAspectClass nativeAspectClass = (NativeAspectClass) key.getAspectClass();
188 aspectFactory = (ConfiguredAspectFactory) nativeAspectClass;
messaa4063f62021-09-09 10:14:45 -0700189 aspect = Aspect.forNative(nativeAspectClass, key.getParameters());
gregce18694cd2020-05-12 15:40:05 -0700190 } else if (key.getAspectClass() instanceof StarlarkAspectClass) {
191 StarlarkAspectClass starlarkAspectClass = (StarlarkAspectClass) key.getAspectClass();
gregced281df72020-05-11 12:27:06 -0700192 StarlarkDefinedAspect starlarkAspect;
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000193 try {
gregced281df72020-05-11 12:27:06 -0700194 starlarkAspect = loadStarlarkDefinedAspect(env, starlarkAspectClass);
Ulf Adams0678e792016-01-25 15:30:45 +0000195 } catch (AspectCreationException e) {
196 throw new AspectFunctionException(e);
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000197 }
gregced281df72020-05-11 12:27:06 -0700198 if (starlarkAspect == null) {
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000199 return null;
200 }
201
gregce5c8a5f52020-05-13 10:35:36 -0700202 aspectFactory = new StarlarkAspectFactory(starlarkAspect);
gregced281df72020-05-11 12:27:06 -0700203 aspect =
gregce18694cd2020-05-12 15:40:05 -0700204 Aspect.forStarlark(
gregced281df72020-05-11 12:27:06 -0700205 starlarkAspect.getAspectClass(),
206 starlarkAspect.getDefinition(key.getParameters()),
messaa4063f62021-09-09 10:14:45 -0700207 key.getParameters());
Dmitry Lomovc15ba2e2015-10-30 15:50:01 +0000208 } else {
209 throw new IllegalStateException();
210 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100211
Ulf Adams9e16f0a2016-01-25 12:43:32 +0000212 // Keep this in sync with the same code in ConfiguredTargetFunction.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100213 PackageValue packageValue =
214 (PackageValue) env.getValue(PackageValue.key(key.getLabel().getPackageIdentifier()));
215 if (packageValue == null) {
216 return null;
217 }
Janak Ramakrishnan0a4c6e42015-09-17 00:37:58 +0000218 Package pkg = packageValue.getPackage();
219 if (pkg.containsErrors()) {
220 throw new AspectFunctionException(
Ulf Adams9e16f0a2016-01-25 12:43:32 +0000221 new BuildFileContainsErrorsException(key.getLabel().getPackageIdentifier()));
Janak Ramakrishnan0a4c6e42015-09-17 00:37:58 +0000222 }
Lukacs Berkiea988b62016-08-30 12:26:18 +0000223
cpeysera8a61ee2018-01-26 09:20:37 -0800224 boolean aspectHasConfiguration = key.getAspectConfigurationKey() != null;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100225
cpeysera8a61ee2018-01-26 09:20:37 -0800226 ImmutableSet<SkyKey> keys =
227 aspectHasConfiguration
228 ? ImmutableSet.of(key.getBaseConfiguredTargetKey(), key.getAspectConfigurationKey())
229 : ImmutableSet.of(key.getBaseConfiguredTargetKey());
230
231 Map<SkyKey, ValueOrException<ConfiguredValueCreationException>> baseAndAspectValues =
232 env.getValuesOrThrow(keys, ConfiguredValueCreationException.class);
233 if (env.valuesMissing()) {
234 return null;
235 }
236
237 ConfiguredTargetValue baseConfiguredTargetValue;
238 BuildConfiguration aspectConfiguration = null;
239
Ulf Adams84901732016-01-28 15:05:16 +0000240 try {
cpeysera8a61ee2018-01-26 09:20:37 -0800241 baseConfiguredTargetValue =
242 (ConfiguredTargetValue) baseAndAspectValues.get(key.getBaseConfiguredTargetKey()).get();
Ulf Adams84901732016-01-28 15:05:16 +0000243 } catch (ConfiguredValueCreationException e) {
ulfjack904a8d62018-05-29 05:17:35 -0700244 throw new AspectFunctionException(
mschaller859c9ac2020-09-25 16:09:19 -0700245 new AspectCreationException(e.getMessage(), e.getRootCauses(), e.getDetailedExitCode()));
Ulf Adams84901732016-01-28 15:05:16 +0000246 }
cpeysera8a61ee2018-01-26 09:20:37 -0800247
248 if (aspectHasConfiguration) {
249 try {
250 aspectConfiguration =
251 ((BuildConfigurationValue)
252 baseAndAspectValues.get(key.getAspectConfigurationKey()).get())
253 .getConfiguration();
254 } catch (ConfiguredValueCreationException e) {
255 throw new IllegalStateException("Unexpected exception from BuildConfigurationFunction when "
256 + "computing " + key.getAspectConfigurationKey(), e);
257 }
Dmitry Lomove2033b12015-08-19 16:57:49 +0000258 }
Lukacs Berkiea988b62016-08-30 12:26:18 +0000259
cpeysera8a61ee2018-01-26 09:20:37 -0800260 ConfiguredTarget associatedTarget = baseConfiguredTargetValue.getConfiguredTarget();
dslomov99ea6b42017-04-25 17:46:17 +0200261
janakr171a7eb2018-03-26 09:26:53 -0700262 Package targetPkg;
263 BuildConfiguration configuration = null;
264 PackageValue.Key packageKey =
kmbb495a442021-08-25 19:45:28 -0700265 PackageValue.key(associatedTarget.getOriginalLabel().getPackageIdentifier());
janakr171a7eb2018-03-26 09:26:53 -0700266 if (associatedTarget.getConfigurationKey() == null) {
267 PackageValue val = ((PackageValue) env.getValue(packageKey));
268 if (val == null) {
269 // Unexpected in Bazel logic, but Skyframe makes no guarantees that this package is
270 // actually present.
271 return null;
272 }
273 targetPkg = val.getPackage();
274 } else {
275 Map<SkyKey, SkyValue> result =
276 env.getValues(ImmutableSet.of(packageKey, associatedTarget.getConfigurationKey()));
277 if (env.valuesMissing()) {
278 // Unexpected in Bazel logic, but Skyframe makes no guarantees that this package and
279 // configuration are actually present.
280 return null;
281 }
282 targetPkg = ((PackageValue) result.get(packageKey)).getPackage();
283 configuration =
284 ((BuildConfigurationValue) result.get(associatedTarget.getConfigurationKey()))
285 .getConfiguration();
janakr171a7eb2018-03-26 09:26:53 -0700286 }
kmbb495a442021-08-25 19:45:28 -0700287
288 Target target;
janakrf3e6f252018-01-18 07:45:12 -0800289 try {
kmbb495a442021-08-25 19:45:28 -0700290 target = targetPkg.getTarget(associatedTarget.getOriginalLabel().getName());
janakrf3e6f252018-01-18 07:45:12 -0800291 } catch (NoSuchTargetException e) {
292 throw new IllegalStateException("Name already verified", e);
293 }
dslomov99ea6b42017-04-25 17:46:17 +0200294
kmbb495a442021-08-25 19:45:28 -0700295 if (AliasProvider.isAlias(associatedTarget)) {
tomlu3d1a1942017-11-29 14:01:21 -0800296 return createAliasAspect(
297 env,
jhorvitz86409b72021-10-04 16:55:20 -0700298 view.getHostConfiguration(),
kmbb495a442021-08-25 19:45:28 -0700299 new TargetAndConfiguration(target, configuration),
tomlu3d1a1942017-11-29 14:01:21 -0800300 aspect,
301 key,
kmbb495a442021-08-25 19:45:28 -0700302 aspectConfiguration,
303 associatedTarget);
Lukacs Berkiea988b62016-08-30 12:26:18 +0000304 }
kmbb495a442021-08-25 19:45:28 -0700305 // If we get here, label should match original label, and therefore the target we looked up
306 // above indeed corresponds to associatedTarget.getLabel().
307 Preconditions.checkState(
308 associatedTarget.getOriginalLabel().equals(associatedTarget.getLabel()),
309 "Non-alias %s should have matching label but found %s",
310 associatedTarget.getOriginalLabel(),
311 associatedTarget.getLabel());
312
313 ConfiguredTargetAndData associatedConfiguredTargetAndData =
314 new ConfiguredTargetAndData(associatedTarget, target, configuration, null);
Lukacs Berkiea988b62016-08-30 12:26:18 +0000315
messa1bca1bd2021-05-14 00:48:19 -0700316 // If the incompatible flag is set, the top-level aspect should not be applied on top-level
317 // targets whose rules do not advertise the aspect's required providers. The aspect should not
318 // also propagate to these targets dependencies.
319 StarlarkSemantics starlarkSemantics = PrecomputedValue.STARLARK_SEMANTICS.get(env);
320 if (starlarkSemantics == null) {
321 return null;
322 }
323 boolean checkRuleAdvertisedProviders =
324 starlarkSemantics.getBool(
325 BuildLanguageOptions.INCOMPATIBLE_TOP_LEVEL_ASPECTS_REQUIRE_PROVIDERS);
326 if (checkRuleAdvertisedProviders) {
messa1bca1bd2021-05-14 00:48:19 -0700327 if (target instanceof Rule) {
328 if (!aspect
329 .getDefinition()
330 .getRequiredProviders()
331 .isSatisfiedBy(((Rule) target).getRuleClassObject().getAdvertisedProviders())) {
332 return new AspectValue(
333 key,
334 aspect,
335 target.getLocation(),
336 ConfiguredAspect.forNonapplicableTarget(),
337 /*transitivePackagesForPackageRootResolution=*/ NestedSetBuilder
338 .<Package>stableOrder()
339 .build());
340 }
341 }
342 }
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000343
Dmitry Lomov15756522016-12-16 16:52:37 +0000344 ImmutableList.Builder<Aspect> aspectPathBuilder = ImmutableList.builder();
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000345
Dmitry Lomove851fe22017-02-14 23:11:23 +0000346 if (!key.getBaseKeys().isEmpty()) {
347 // We transitively collect all required aspects to reduce the number of restarts.
348 // Semantically it is enough to just request key.getBaseKeys().
dslomov039b9ee2017-04-11 08:51:30 +0000349 ImmutableList.Builder<SkyKey> aspectPathSkyKeysBuilder = ImmutableList.builder();
350 ImmutableMap<AspectDescriptor, SkyKey> aspectKeys =
351 getSkyKeysForAspectsAndCollectAspectPath(key.getBaseKeys(), aspectPathSkyKeysBuilder);
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000352
Dmitry Lomove851fe22017-02-14 23:11:23 +0000353 Map<SkyKey, SkyValue> values = env.getValues(aspectKeys.values());
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000354 if (env.valuesMissing()) {
355 return null;
356 }
dslomov039b9ee2017-04-11 08:51:30 +0000357 ImmutableList<SkyKey> aspectPathSkyKeys = aspectPathSkyKeysBuilder.build();
358 for (SkyKey aspectPathSkyKey : aspectPathSkyKeys) {
359 aspectPathBuilder.add(((AspectValue) values.get(aspectPathSkyKey)).getAspect());
360 }
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000361 try {
dslomov039b9ee2017-04-11 08:51:30 +0000362 associatedTarget = getBaseTarget(
363 associatedTarget, key.getBaseKeys(), values);
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000364 } catch (DuplicateException e) {
mjhalupka30bf44c2018-01-25 08:22:34 -0800365 env.getListener()
366 .handle(
367 Event.error(
janakr9c101402018-03-10 06:48:59 -0800368 associatedConfiguredTargetAndData.getTarget().getLocation(), e.getMessage()));
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000369
370 throw new AspectFunctionException(
ulfjack904a8d62018-05-29 05:17:35 -0700371 new AspectCreationException(
372 e.getMessage(), associatedTarget.getLabel(), aspectConfiguration));
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000373 }
374 }
janakr9c101402018-03-10 06:48:59 -0800375 associatedConfiguredTargetAndData =
376 associatedConfiguredTargetAndData.fromConfiguredTarget(associatedTarget);
Dmitry Lomov15756522016-12-16 16:52:37 +0000377 aspectPathBuilder.add(aspect);
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000378
jhorvitze68a7d02021-04-26 11:49:28 -0700379 SkyframeDependencyResolver resolver = new SkyframeDependencyResolver(env);
janakr931d2852017-12-15 13:48:29 -0800380 NestedSetBuilder<Package> transitivePackagesForPackageRootResolution =
381 storeTransitivePackagesForPackageRootResolution ? NestedSetBuilder.stableOrder() : null;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100382
Michael Staib04f6f242016-03-01 15:40:29 +0000383 // When getting the dependencies of this hybrid aspect+base target, use the aspect's
384 // configuration. The configuration of the aspect will always be a superset of the target's
gregcee0bbe752017-09-12 23:58:34 +0200385 // (trimmed configuration mode: target is part of the aspect's config fragment requirements;
386 // untrimmed mode: target is the same configuration as the aspect), so the fragments
Michael Staib04f6f242016-03-01 15:40:29 +0000387 // required by all dependencies (both those of the aspect and those of the base target)
388 // will be present this way.
389 TargetAndConfiguration originalTargetAndAspectConfiguration =
janakrf3e6f252018-01-18 07:45:12 -0800390 new TargetAndConfiguration(
janakr9c101402018-03-10 06:48:59 -0800391 associatedConfiguredTargetAndData.getTarget(), aspectConfiguration);
Dmitry Lomov15756522016-12-16 16:52:37 +0000392 ImmutableList<Aspect> aspectPath = aspectPathBuilder.build();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100393 try {
kmbb495a442021-08-25 19:45:28 -0700394 UnloadedToolchainContext unloadedToolchainContext =
395 getUnloadedToolchainContext(env, key, aspect, configuration);
Greg Estren12b06b22020-09-11 10:58:43 -0700396 if (env.valuesMissing()) {
397 return null;
398 }
399
400 // Get the configuration targets that trigger this rule's configurable attributes.
gregce79989f92021-02-01 07:01:55 -0800401 ConfigConditions configConditions =
Greg Estren12b06b22020-09-11 10:58:43 -0700402 ConfiguredTargetFunction.getConfigConditions(
403 env,
404 originalTargetAndAspectConfiguration,
405 transitivePackagesForPackageRootResolution,
406 unloadedToolchainContext == null ? null : unloadedToolchainContext.targetPlatform(),
407 transitiveRootCauses);
408 if (configConditions == null) {
409 // Those targets haven't yet been resolved.
410 return null;
John Cater2e56f062017-07-20 19:43:20 +0200411 }
412
lberki102256f2019-02-08 01:34:23 -0800413 OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> depValueMap;
Dmitry Lomov9b2fc5c2016-11-11 11:18:48 +0000414 try {
John Cater2e56f062017-07-20 19:43:20 +0200415 depValueMap =
416 ConfiguredTargetFunction.computeDependencies(
417 env,
418 resolver,
419 originalTargetAndAspectConfiguration,
420 aspectPath,
gregce79989f92021-02-01 07:01:55 -0800421 configConditions.asProviders(),
juliexxia71a80dc2020-04-09 09:07:09 -0700422 unloadedToolchainContext == null
423 ? null
jcater50375372020-06-02 08:51:33 -0700424 : ToolchainCollection.builder()
juliexxia71a80dc2020-04-09 09:07:09 -0700425 .addDefaultContext(unloadedToolchainContext)
426 .build(),
jcaterbc4ef8c2020-06-16 13:58:01 -0700427 shouldUseToolchainTransition(configuration, aspect.getDefinition()),
John Cater2e56f062017-07-20 19:43:20 +0200428 ruleClassProvider,
jhorvitz86409b72021-10-04 16:55:20 -0700429 view.getHostConfiguration(),
janakr931d2852017-12-15 13:48:29 -0800430 transitivePackagesForPackageRootResolution,
jhorvitz81395032021-05-05 08:48:08 -0700431 transitiveRootCauses);
mschaller859c9ac2020-09-25 16:09:19 -0700432 } catch (ConfiguredValueCreationException e) {
433 throw new AspectCreationException(
434 e.getMessage(), key.getLabel(), aspectConfiguration, e.getDetailedExitCode());
Dmitry Lomov9b2fc5c2016-11-11 11:18:48 +0000435 }
Ulf Adams84901732016-01-28 15:05:16 +0000436 if (depValueMap == null) {
437 return null;
438 }
439 if (!transitiveRootCauses.isEmpty()) {
mschaller859c9ac2020-09-25 16:09:19 -0700440 NestedSet<Cause> causes = transitiveRootCauses.build();
Ulf Adams84901732016-01-28 15:05:16 +0000441 throw new AspectFunctionException(
mschaller859c9ac2020-09-25 16:09:19 -0700442 new AspectCreationException(
443 "Loading failed",
444 causes,
445 ConfiguredTargetFunction.getPrioritizedDetailedExitCode(causes)));
Ulf Adams84901732016-01-28 15:05:16 +0000446 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100447
John Caterae4e7852018-07-09 15:02:42 -0700448 // Load the requested toolchains into the ToolchainContext, now that we have dependencies.
John Catercdfa9ca2019-04-05 12:32:09 -0700449 ResolvedToolchainContext toolchainContext = null;
jcater1f724162018-08-27 09:16:01 -0700450 if (unloadedToolchainContext != null) {
John Cater50745142019-04-16 07:41:24 -0700451 String targetDescription =
452 String.format(
453 "aspect %s applied to %s",
454 aspect.getDescriptor().getDescription(),
455 associatedConfiguredTargetAndData.getTarget());
lberki102256f2019-02-08 01:34:23 -0800456 toolchainContext =
John Cater50745142019-04-16 07:41:24 -0700457 ResolvedToolchainContext.load(
John Cater50745142019-04-16 07:41:24 -0700458 unloadedToolchainContext,
459 targetDescription,
jcater6415e5c2020-07-15 14:17:53 -0700460 // TODO(161222568): Support exec groups on aspects.
461 depValueMap.get(DependencyKind.defaultExecGroupToolchain()));
John Caterae4e7852018-07-09 15:02:42 -0700462 }
463
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000464 return createAspect(
465 env,
466 key,
Dmitry Lomov15756522016-12-16 16:52:37 +0000467 aspectPath,
Dmitry Lomov2eb8bdd2016-04-06 08:47:30 +0000468 aspect,
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000469 aspectFactory,
janakr9c101402018-03-10 06:48:59 -0800470 associatedConfiguredTargetAndData,
cpeysera8a61ee2018-01-26 09:20:37 -0800471 aspectConfiguration,
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000472 configConditions,
John Cater2e56f062017-07-20 19:43:20 +0200473 toolchainContext,
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000474 depValueMap,
janakr931d2852017-12-15 13:48:29 -0800475 transitivePackagesForPackageRootResolution);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100476 } catch (DependencyEvaluationException e) {
gregcec5649772021-07-08 13:10:19 -0700477 // TODO(bazel-team): consolidate all env.getListener().handle() calls in this method, like in
478 // ConfiguredTargetFunction. This encourages clear, consistent user messages (ideally without
479 // the programmer having to think about it).
480 if (!e.depReportedOwnError()) {
481 env.getListener().handle(Event.error(e.getLocation(), e.getMessage()));
482 }
Ulf Adams25f03d82016-01-25 10:31:46 +0000483 if (e.getCause() instanceof ConfiguredValueCreationException) {
484 ConfiguredValueCreationException cause = (ConfiguredValueCreationException) e.getCause();
ulfjack904a8d62018-05-29 05:17:35 -0700485 throw new AspectFunctionException(
mschaller859c9ac2020-09-25 16:09:19 -0700486 new AspectCreationException(
487 cause.getMessage(), cause.getRootCauses(), cause.getDetailedExitCode()));
Dmitry Lomovd83af9e2017-02-23 15:44:23 +0000488 } else if (e.getCause() instanceof InconsistentAspectOrderException) {
489 InconsistentAspectOrderException cause = (InconsistentAspectOrderException) e.getCause();
gregcec5649772021-07-08 13:10:19 -0700490 env.getListener().handle(Event.error(cause.getLocation(), cause.getMessage()));
ulfjack904a8d62018-05-29 05:17:35 -0700491 throw new AspectFunctionException(
492 new AspectCreationException(cause.getMessage(), key.getLabel(), aspectConfiguration));
Samuel Giddinseadadbd2020-08-17 08:00:05 -0700493 } else if (e.getCause() instanceof TransitionException) {
494 TransitionException cause = (TransitionException) e.getCause();
495 throw new AspectFunctionException(
496 new AspectCreationException(cause.getMessage(), key.getLabel(), aspectConfiguration));
Ulf Adams25f03d82016-01-25 10:31:46 +0000497 } else {
498 // Cast to InvalidConfigurationException as a consistency check. If you add any
499 // DependencyEvaluationException constructors, you may need to change this code, too.
500 InvalidConfigurationException cause = (InvalidConfigurationException) e.getCause();
ulfjack904a8d62018-05-29 05:17:35 -0700501 throw new AspectFunctionException(
mschaller859c9ac2020-09-25 16:09:19 -0700502 new AspectCreationException(
503 cause.getMessage(),
504 key.getLabel(),
505 aspectConfiguration,
506 cause.getDetailedExitCode()));
Ulf Adams25f03d82016-01-25 10:31:46 +0000507 }
Marian Loburfc567b32015-09-14 08:44:25 +0000508 } catch (AspectCreationException e) {
509 throw new AspectFunctionException(e);
gregcec5649772021-07-08 13:10:19 -0700510 } catch (ConfiguredValueCreationException e) {
511 throw new AspectFunctionException(e);
jcater3fed8692019-04-01 13:36:36 -0700512 } catch (ToolchainException e) {
513 throw new AspectFunctionException(
514 new AspectCreationException(
mschaller1511dd22020-09-21 14:19:33 -0700515 e.getMessage(), new LabelCause(key.getLabel(), e.getDetailedExitCode())));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100516 }
517 }
518
kmbb495a442021-08-25 19:45:28 -0700519 @Nullable
520 private static UnloadedToolchainContext getUnloadedToolchainContext(
521 Environment env, AspectKey key, Aspect aspect, @Nullable BuildConfiguration configuration)
522 throws InterruptedException, AspectCreationException {
523 // Determine what toolchains are needed by this target.
524 UnloadedToolchainContext unloadedToolchainContext = null;
525 if (configuration != null) {
526 // Configuration can be null in the case of aspects applied to input files. In this case,
527 // there are no chances of toolchains being used, so skip it.
528 try {
529 ImmutableSet<Label> requiredToolchains = aspect.getDefinition().getRequiredToolchains();
530 unloadedToolchainContext =
531 (UnloadedToolchainContext)
532 env.getValueOrThrow(
533 ToolchainContextKey.key()
534 .configurationKey(BuildConfigurationValue.key(configuration))
535 .requiredToolchainTypeLabels(requiredToolchains)
536 .build(),
537 ToolchainException.class);
538 } catch (ToolchainException e) {
539 // TODO(katre): better error handling
540 throw new AspectCreationException(
541 e.getMessage(), new LabelCause(key.getLabel(), e.getDetailedExitCode()));
542 }
543 }
544 if (env.valuesMissing()) {
545 return null;
546 }
547 return unloadedToolchainContext;
548 }
549
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000550 /**
jcaterbc4ef8c2020-06-16 13:58:01 -0700551 * Returns whether or not to use the new toolchain transition. Checks the global incompatible
552 * change flag and the aspect's toolchain transition readiness attribute.
553 */
554 // TODO(#10523): Remove this when the migration period for toolchain transitions has ended.
555 private static boolean shouldUseToolchainTransition(
556 @Nullable BuildConfiguration configuration, AspectDefinition definition) {
557 // Check whether the global incompatible change flag is set.
558 if (configuration != null) {
559 PlatformOptions platformOptions = configuration.getOptions().get(PlatformOptions.class);
560 if (platformOptions != null && platformOptions.overrideToolchainTransition) {
561 return true;
562 }
563 }
564
565 // Check the aspect definition to see if it is ready.
566 return definition.useToolchainTransition();
567 }
568
569 /**
570 * Merges aspects defined by {@code aspectKeys} into the {@code target} using previously computed
571 * {@code values}.
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000572 *
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000573 * @return A {@link ConfiguredTarget} that is a result of a merge.
574 * @throws DuplicateException if there is a duplicate provider provided by aspects.
575 */
jcaterbc4ef8c2020-06-16 13:58:01 -0700576 private static ConfiguredTarget getBaseTarget(
577 ConfiguredTarget target, ImmutableList<AspectKey> aspectKeys, Map<SkyKey, SkyValue> values)
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000578 throws DuplicateException {
579 ArrayList<ConfiguredAspect> aspectValues = new ArrayList<>();
Dmitry Lomove851fe22017-02-14 23:11:23 +0000580 for (AspectKey aspectKey : aspectKeys) {
janakr573807d2018-01-11 14:02:35 -0800581 AspectValue aspectValue = (AspectValue) values.get(aspectKey);
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000582 ConfiguredAspect configuredAspect = aspectValue.getConfiguredAspect();
583 aspectValues.add(configuredAspect);
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000584 }
585 return MergedConfiguredTarget.of(target, aspectValues);
586 }
587
588 /**
jhorvitze362fc92021-04-22 16:04:44 -0700589 * Collect all SkyKeys that are needed for a given list of AspectKeys, including transitive
590 * dependencies.
dslomov039b9ee2017-04-11 08:51:30 +0000591 *
jhorvitze362fc92021-04-22 16:04:44 -0700592 * <p>Also collects all propagating aspects in correct order.
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000593 */
jhorvitze362fc92021-04-22 16:04:44 -0700594 private static ImmutableMap<AspectDescriptor, SkyKey> getSkyKeysForAspectsAndCollectAspectPath(
595 ImmutableList<AspectKey> keys, ImmutableList.Builder<SkyKey> aspectPathBuilder) {
Dmitry Lomove851fe22017-02-14 23:11:23 +0000596 HashMap<AspectDescriptor, SkyKey> result = new HashMap<>();
597 for (AspectKey key : keys) {
dslomov039b9ee2017-04-11 08:51:30 +0000598 buildSkyKeys(key, result, aspectPathBuilder);
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000599 }
Dmitry Lomove851fe22017-02-14 23:11:23 +0000600 return ImmutableMap.copyOf(result);
Dmitry Lomovca9bfa42016-11-15 13:22:36 +0000601 }
602
jhorvitze362fc92021-04-22 16:04:44 -0700603 private static void buildSkyKeys(
604 AspectKey key,
605 HashMap<AspectDescriptor, SkyKey> result,
dslomov039b9ee2017-04-11 08:51:30 +0000606 ImmutableList.Builder<SkyKey> aspectPathBuilder) {
Dmitry Lomove851fe22017-02-14 23:11:23 +0000607 if (result.containsKey(key.getAspectDescriptor())) {
608 return;
609 }
610 ImmutableList<AspectKey> baseKeys = key.getBaseKeys();
janakr573807d2018-01-11 14:02:35 -0800611 result.put(key.getAspectDescriptor(), key);
Dmitry Lomove851fe22017-02-14 23:11:23 +0000612 for (AspectKey baseKey : baseKeys) {
dslomov039b9ee2017-04-11 08:51:30 +0000613 buildSkyKeys(baseKey, result, aspectPathBuilder);
Dmitry Lomove851fe22017-02-14 23:11:23 +0000614 }
dslomov039b9ee2017-04-11 08:51:30 +0000615 // Post-order list of aspect SkyKeys gives the order of propagating aspects:
616 // the aspect comes after all aspects it transitively sees.
janakr573807d2018-01-11 14:02:35 -0800617 aspectPathBuilder.add(key);
Dmitry Lomove851fe22017-02-14 23:11:23 +0000618 }
dslomovfa50c3d2017-05-08 08:47:44 -0400619
kmbb495a442021-08-25 19:45:28 -0700620 /**
621 * Computes the given aspectKey of an alias-like target, by depending on the corresponding key of
622 * the next target in the alias chain (if there are more), or the "real" configured target.
623 */
624 @Nullable
625 private AspectValue createAliasAspect(
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000626 Environment env,
kmbb495a442021-08-25 19:45:28 -0700627 BuildConfiguration hostConfiguration,
628 TargetAndConfiguration originalTarget,
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000629 Aspect aspect,
Lukacs Berkiea988b62016-08-30 12:26:18 +0000630 AspectKey originalKey,
kmbb495a442021-08-25 19:45:28 -0700631 BuildConfiguration aspectConfiguration,
janakr93e3eea2017-03-30 22:09:37 +0000632 ConfiguredTarget configuredTarget)
kmbb495a442021-08-25 19:45:28 -0700633 throws AspectFunctionException, InterruptedException {
634 ImmutableList<Label> aliasChain =
635 configuredTarget.getProvider(AliasProvider.class).getAliasChain();
Lukacs Berkiea988b62016-08-30 12:26:18 +0000636 // Find the next alias in the chain: either the next alias (if there are two) or the name of
637 // the real configured target.
kmbb495a442021-08-25 19:45:28 -0700638 Label aliasedLabel = aliasChain.size() > 1 ? aliasChain.get(1) : configuredTarget.getLabel();
Lukacs Berkiea988b62016-08-30 12:26:18 +0000639
kmbb495a442021-08-25 19:45:28 -0700640 NestedSetBuilder<Package> transitivePackagesForPackageRootResolution =
641 storeTransitivePackagesForPackageRootResolution ? NestedSetBuilder.stableOrder() : null;
642 NestedSetBuilder<Cause> transitiveRootCauses = NestedSetBuilder.stableOrder();
643
644 // Compute the Dependency from originalTarget to aliasedLabel
645 Dependency dep;
646 try {
647 UnloadedToolchainContext unloadedToolchainContext =
648 getUnloadedToolchainContext(env, originalKey, aspect, originalTarget.getConfiguration());
649 if (env.valuesMissing()) {
650 return null;
651 }
652
653 // See comment in compute() above for why we pair target with aspectConfiguration here
654 TargetAndConfiguration originalTargetAndAspectConfiguration =
655 new TargetAndConfiguration(originalTarget.getTarget(), aspectConfiguration);
656
657 // Get the configuration targets that trigger this rule's configurable attributes.
658 ConfigConditions configConditions =
659 ConfiguredTargetFunction.getConfigConditions(
660 env,
661 originalTargetAndAspectConfiguration,
662 transitivePackagesForPackageRootResolution,
663 unloadedToolchainContext == null ? null : unloadedToolchainContext.targetPlatform(),
664 transitiveRootCauses);
665 if (configConditions == null) {
666 // Those targets haven't yet been resolved.
667 return null;
668 }
669
670 Target aliasedTarget = getTargetFromLabel(env, aliasedLabel);
671 if (aliasedTarget == null) {
672 return null;
673 }
674 ConfigurationTransition transition =
675 TransitionResolver.evaluateTransition(
676 aspectConfiguration,
677 NoTransition.INSTANCE,
678 aliasedTarget,
679 ((ConfiguredRuleClassProvider) ruleClassProvider).getTrimmingTransitionFactory());
680
681 // Use ConfigurationResolver to apply any configuration transitions on the alias edge.
682 // This is a shortened/simplified variant of ConfiguredTargetFunction.computeDependencies
683 // for just the one special attribute we care about here.
684 DependencyKey depKey =
685 DependencyKey.builder().setLabel(aliasedLabel).setTransition(transition).build();
686 DependencyKind depKind =
687 DependencyKind.AttributeDependencyKind.forRule(
688 getAttributeContainingAlias(originalTarget.getTarget()));
689 ConfigurationResolver resolver =
690 new ConfigurationResolver(
691 env,
692 originalTargetAndAspectConfiguration,
693 hostConfiguration,
694 configConditions.asProviders());
695 ImmutableList<Dependency> deps = resolver.resolveConfiguration(depKind, depKey);
696 if (deps == null) {
697 return null;
698 }
699 // Actual should resolve to exactly one dependency
700 Preconditions.checkState(
701 deps.size() == 1, "Unexpected split in alias %s: %s", originalTarget.getLabel(), deps);
702 dep = deps.get(0);
703 } catch (NoSuchPackageException | NoSuchTargetException e) {
704 throw new AspectFunctionException(e);
705 } catch (ConfiguredValueCreationException e) {
706 throw new AspectFunctionException(e);
707 } catch (AspectCreationException e) {
708 throw new AspectFunctionException(e);
709 }
710
711 if (!transitiveRootCauses.isEmpty()) {
712 NestedSet<Cause> causes = transitiveRootCauses.build();
713 throw new AspectFunctionException(
714 new AspectCreationException(
715 "Loading failed",
716 causes,
717 ConfiguredTargetFunction.getPrioritizedDetailedExitCode(causes)));
718 }
719
720 // Now that we have a Dependency, we can compute the aliased key and depend on it
721 AspectKey actualKey = buildAliasAspectKey(originalKey, aliasedLabel, dep);
722 return createAliasAspect(
723 env,
724 originalTarget.getTarget(),
725 originalKey,
726 aspect,
727 actualKey,
728 transitivePackagesForPackageRootResolution);
cparsons089148b2019-09-17 08:14:41 -0700729 }
730
jhorvitz86409b72021-10-04 16:55:20 -0700731 private static AspectValue createAliasAspect(
cparsons089148b2019-09-17 08:14:41 -0700732 Environment env,
733 Target originalTarget,
cparsons089148b2019-09-17 08:14:41 -0700734 AspectKey originalKey,
kmbb495a442021-08-25 19:45:28 -0700735 Aspect aspect,
736 AspectKey depKey,
737 @Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution)
cparsons089148b2019-09-17 08:14:41 -0700738 throws InterruptedException {
Lukacs Berkiea988b62016-08-30 12:26:18 +0000739 // Compute the AspectValue of the target the alias refers to (which can itself be either an
740 // alias or a real target)
Lukacs Berki549bfce2016-04-22 15:29:12 +0000741 AspectValue real = (AspectValue) env.getValue(depKey);
742 if (env.valuesMissing()) {
743 return null;
744 }
745
kmbb495a442021-08-25 19:45:28 -0700746 NestedSet<Package> finalTransitivePackagesForPackageRootResolution = null;
747 if (transitivePackagesForPackageRootResolution != null) {
748 finalTransitivePackagesForPackageRootResolution =
749 transitivePackagesForPackageRootResolution
750 .addTransitive(real.getTransitivePackagesForPackageRootResolution())
751 .add(originalTarget.getPackage())
752 .build();
753 }
Lukacs Berki549bfce2016-04-22 15:29:12 +0000754 return new AspectValue(
755 originalKey,
756 aspect,
Lukacs Berki549bfce2016-04-22 15:29:12 +0000757 originalTarget.getLocation(),
758 ConfiguredAspect.forAlias(real.getConfiguredAspect()),
kmbb495a442021-08-25 19:45:28 -0700759 finalTransitivePackagesForPackageRootResolution);
760 }
761
762 @Nullable
763 private static Target getTargetFromLabel(Environment env, Label aliasLabel)
764 throws InterruptedException, NoSuchPackageException, NoSuchTargetException {
765 SkyValue val =
766 env.getValueOrThrow(
767 PackageValue.key(aliasLabel.getPackageIdentifier()), NoSuchPackageException.class);
768 if (val == null) {
769 return null;
770 }
771
772 Package pkg = ((PackageValue) val).getPackage();
773 return pkg.getTarget(aliasLabel.getName());
774 }
775
776 private static AspectKey buildAliasAspectKey(
777 AspectKey originalKey, Label aliasLabel, Dependency dep) {
778 ImmutableList<AspectKey> aliasedBaseKeys =
779 originalKey.getBaseKeys().stream()
780 .map(baseKey -> buildAliasAspectKey(baseKey, aliasLabel, dep))
781 .collect(toImmutableList());
lebab52a1902021-09-23 01:35:13 -0700782 return AspectKeyCreator.createAspectKey(
kmbb495a442021-08-25 19:45:28 -0700783 aliasLabel,
784 dep.getConfiguration(),
785 aliasedBaseKeys,
786 originalKey.getAspectDescriptor(),
787 dep.getAspectConfiguration(originalKey.getAspectDescriptor()));
788 }
789
790 /**
791 * Given an alias-like target, returns the attribute containing the "actual", by looking for
792 * attribute names used in known alias rules (Alias, Bind, LateBoundAlias, XcodeConfigAlias).
793 *
794 * <p>Alias and Bind rules use "actual", which will be by far the most common match here. It'll
795 * likely be rare that aspects need to traverse across other alias-like rules.
796 */
797 // TODO(lberki,kmb): try to avoid this, maybe by recording the attribute name in AliasProvider
798 private static Attribute getAttributeContainingAlias(Target originalTarget) {
799 Attribute aliasAttr = null;
800 for (Attribute attr : originalTarget.getAssociatedRule().getAttributes()) {
801 switch (attr.getName()) {
802 case "actual": // alias and bind rules
803 case ":alias": // LateBoundAlias-derived rules
804 case ":xcode_config": // xcode_config_alias rule
805 Preconditions.checkState(
806 aliasAttr == null,
807 "Found multiple candidate attributes %s and %s in %s",
808 aliasAttr,
809 attr,
810 originalTarget);
811 aliasAttr = attr;
812 break;
813 default:
814 break;
815 }
816 }
817 Preconditions.checkState(
818 aliasAttr != null, "Attribute containing alias not found in %s", originalTarget);
819 return aliasAttr;
Lukacs Berki549bfce2016-04-22 15:29:12 +0000820 }
821
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100822 @Nullable
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000823 private AspectValue createAspect(
824 Environment env,
825 AspectKey key,
Dmitry Lomov15756522016-12-16 16:52:37 +0000826 ImmutableList<Aspect> aspectPath,
Dmitry Lomov2eb8bdd2016-04-06 08:47:30 +0000827 Aspect aspect,
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000828 ConfiguredAspectFactory aspectFactory,
janakr9c101402018-03-10 06:48:59 -0800829 ConfiguredTargetAndData associatedTarget,
Michael Staib04f6f242016-03-01 15:40:29 +0000830 BuildConfiguration aspectConfiguration,
gregce79989f92021-02-01 07:01:55 -0800831 ConfigConditions configConditions,
John Catercdfa9ca2019-04-05 12:32:09 -0700832 ResolvedToolchainContext toolchainContext,
lberki102256f2019-02-08 01:34:23 -0800833 OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> directDeps,
janakr931d2852017-12-15 13:48:29 -0800834 @Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution)
Dmitry Lomov0b832ce2015-10-20 10:03:14 +0000835 throws AspectFunctionException, InterruptedException {
brandjon66b64632020-12-17 14:11:32 -0800836 // Should be successfully evaluated and cached from the loading phase.
837 StarlarkBuiltinsValue starlarkBuiltinsValue =
838 (StarlarkBuiltinsValue) env.getValue(StarlarkBuiltinsValue.key());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100839 if (env.valuesMissing()) {
840 return null;
841 }
842
brandjon66b64632020-12-17 14:11:32 -0800843 SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
844
845 StoredEventHandler events = new StoredEventHandler();
846 CachingAnalysisEnvironment analysisEnvironment =
847 view.createAnalysisEnvironment(
jhorvitze362fc92021-04-22 16:04:44 -0700848 key, events, env, aspectConfiguration, starlarkBuiltinsValue);
brandjon66b64632020-12-17 14:11:32 -0800849
Dmitry Lomov6cd98972017-03-01 15:44:00 +0000850 ConfiguredAspect configuredAspect;
cparsons089148b2019-09-17 08:14:41 -0700851 if (aspect.getDefinition().applyToGeneratingRules()
852 && associatedTarget.getTarget() instanceof OutputFile) {
853 OutputFile outputFile = (OutputFile) associatedTarget.getTarget();
854 Label label = outputFile.getGeneratingRule().getLabel();
kmbb495a442021-08-25 19:45:28 -0700855 return createAliasAspect(
856 env,
857 associatedTarget.getTarget(),
858 key,
859 aspect,
860 key.withLabel(label),
861 transitivePackagesForPackageRootResolution);
cparsons089148b2019-09-17 08:14:41 -0700862 } else if (AspectResolver.aspectMatchesConfiguredTarget(associatedTarget, aspect)) {
tomlu72642a22017-10-18 06:23:14 +0200863 try {
864 CurrentRuleTracker.beginConfiguredAspect(aspect.getAspectClass());
865 configuredAspect =
866 view.getConfiguredTargetFactory()
867 .createAspect(
868 analysisEnvironment,
869 associatedTarget,
870 aspectPath,
871 aspectFactory,
872 aspect,
873 directDeps,
874 configConditions,
875 toolchainContext,
876 aspectConfiguration,
jhorvitz86409b72021-10-04 16:55:20 -0700877 view.getHostConfiguration(),
janakreaff19c2019-01-31 13:59:40 -0800878 key);
ulfjack37407682019-09-17 06:30:49 -0700879 } catch (MissingDepException e) {
880 Preconditions.checkState(env.valuesMissing());
881 return null;
jcater0b385bd2020-04-08 15:27:07 -0700882 } catch (ActionConflictException e) {
883 throw new AspectFunctionException(e);
juliexxia6fe70c22020-05-18 14:38:42 -0700884 } catch (InvalidExecGroupException e) {
885 throw new AspectFunctionException(e);
tomlu72642a22017-10-18 06:23:14 +0200886 } finally {
887 CurrentRuleTracker.endConfiguredAspect();
888 }
Dmitry Lomov6cd98972017-03-01 15:44:00 +0000889 } else {
janakrf15d08d2020-04-22 12:53:03 -0700890 configuredAspect = ConfiguredAspect.forNonapplicableTarget();
Dmitry Lomov6cd98972017-03-01 15:44:00 +0000891 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100892
893 events.replayOn(env.getListener());
894 if (events.hasErrors()) {
895 analysisEnvironment.disable(associatedTarget.getTarget());
janakr043acd92020-02-28 18:59:06 -0800896 String msg = "Analysis of target '" + associatedTarget.getTarget().getLabel() + "' failed";
janakrf3e6f252018-01-18 07:45:12 -0800897 throw new AspectFunctionException(
ulfjack904a8d62018-05-29 05:17:35 -0700898 new AspectCreationException(msg, key.getLabel(), aspectConfiguration));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100899 }
900 Preconditions.checkState(!analysisEnvironment.hasErrors(),
901 "Analysis environment hasError() but no errors reported");
902
903 if (env.valuesMissing()) {
904 return null;
905 }
906
907 analysisEnvironment.disable(associatedTarget.getTarget());
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000908 Preconditions.checkNotNull(configuredAspect);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100909
910 return new AspectValue(
Dmitry Lomove2033b12015-08-19 16:57:49 +0000911 key,
Dmitry Lomov2eb8bdd2016-04-06 08:47:30 +0000912 aspect,
Dmitry Lomove2033b12015-08-19 16:57:49 +0000913 associatedTarget.getTarget().getLocation(),
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000914 configuredAspect,
janakr931d2852017-12-15 13:48:29 -0800915 transitivePackagesForPackageRootResolution == null
916 ? null
Googlerce6ad292019-12-20 10:29:21 -0800917 : transitivePackagesForPackageRootResolution.build());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100918 }
919
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100920 @Override
921 public String extractTag(SkyKey skyKey) {
Michael Staib2707a882016-09-16 21:06:40 +0000922 AspectKey aspectKey = (AspectKey) skyKey.argument();
923 return Label.print(aspectKey.getLabel());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100924 }
Marian Loburc62faba2015-09-09 10:08:06 +0000925
tomlu39a0a382018-06-22 09:43:23 -0700926 /** Used to indicate errors during the computation of an {@link AspectValue}. */
927 public static final class AspectFunctionException extends SkyFunctionException {
Ulf Adams9e16f0a2016-01-25 12:43:32 +0000928 public AspectFunctionException(NoSuchThingException e) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100929 super(e, Transience.PERSISTENT);
930 }
931
Ulf Adams9e16f0a2016-01-25 12:43:32 +0000932 public AspectFunctionException(AspectCreationException e) {
933 super(e, Transience.PERSISTENT);
Ulf Adamsd55d7af2016-01-19 11:03:22 +0000934 }
Dmitry Lomovd83af9e2017-02-23 15:44:23 +0000935
gregcec5649772021-07-08 13:10:19 -0700936 public AspectFunctionException(ConfiguredValueCreationException e) {
937 super(e, Transience.PERSISTENT);
938 }
939
juliexxia6fe70c22020-05-18 14:38:42 -0700940 public AspectFunctionException(InvalidExecGroupException e) {
941 super(e, Transience.PERSISTENT);
942 }
943
janakr0175ce32018-02-26 15:54:57 -0800944 public AspectFunctionException(ActionConflictException cause) {
Dmitry Lomovd83af9e2017-02-23 15:44:23 +0000945 super(cause, Transience.PERSISTENT);
946 }
Ulf Adamsd55d7af2016-01-19 11:03:22 +0000947 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100948}