Damien Martin-Guillerez | f88f4d8 | 2015-09-25 13:56:55 +0000 | [diff] [blame] | 1 | // Copyright 2014 The Bazel Authors. All rights reserved. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | package com.google.devtools.build.lib.skyframe; |
| 16 | |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 17 | import static com.google.common.collect.ImmutableList.toImmutableList; |
| 18 | |
tomlu | a155b53 | 2017-11-08 20:12:47 +0100 | [diff] [blame] | 19 | import com.google.common.base.Preconditions; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 20 | import com.google.common.collect.ImmutableList; |
Lukacs Berki | 7894c18 | 2016-05-10 12:07:01 +0000 | [diff] [blame] | 21 | import com.google.common.collect.ImmutableMap; |
cpeyser | fb82999 | 2017-09-07 17:17:03 +0200 | [diff] [blame] | 22 | import com.google.common.collect.ImmutableSet; |
janakr | 0175ce3 | 2018-02-26 15:54:57 -0800 | [diff] [blame] | 23 | import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException; |
ulfjack | 90e2e98 | 2017-08-07 11:27:32 +0200 | [diff] [blame] | 24 | import com.google.devtools.build.lib.analysis.AliasProvider; |
gregce | 4c3ef11 | 2017-09-20 23:43:14 +0200 | [diff] [blame] | 25 | import com.google.devtools.build.lib.analysis.AspectResolver; |
jcater | 44c9942 | 2020-04-20 15:52:18 -0700 | [diff] [blame] | 26 | import com.google.devtools.build.lib.analysis.AspectValue; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 27 | import com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment; |
ulfjack | 3740768 | 2019-09-17 06:30:49 -0700 | [diff] [blame] | 28 | import com.google.devtools.build.lib.analysis.CachingAnalysisEnvironment.MissingDepException; |
Dmitry Lomov | b487ac6 | 2015-11-09 13:09:12 +0000 | [diff] [blame] | 29 | import com.google.devtools.build.lib.analysis.ConfiguredAspect; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 30 | import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory; |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 31 | import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 32 | import com.google.devtools.build.lib.analysis.ConfiguredTarget; |
janakr | 876deaa | 2021-02-17 07:49:48 -0800 | [diff] [blame] | 33 | import com.google.devtools.build.lib.analysis.ConfiguredTargetValue; |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 34 | import com.google.devtools.build.lib.analysis.Dependency; |
| 35 | import com.google.devtools.build.lib.analysis.DependencyKey; |
jcater | dad2dd3 | 2020-04-13 08:31:58 -0700 | [diff] [blame] | 36 | import com.google.devtools.build.lib.analysis.DependencyKind; |
jcater | 84ca556 | 2020-04-06 14:35:46 -0700 | [diff] [blame] | 37 | import com.google.devtools.build.lib.analysis.DuplicateException; |
jcater | 645c42b | 2021-05-12 09:35:48 -0700 | [diff] [blame] | 38 | import com.google.devtools.build.lib.analysis.ExecGroupCollection.InvalidExecGroupException; |
jcater | dad2dd3 | 2020-04-13 08:31:58 -0700 | [diff] [blame] | 39 | import com.google.devtools.build.lib.analysis.InconsistentAspectOrderException; |
jcater | bc4ef8c | 2020-06-16 13:58:01 -0700 | [diff] [blame] | 40 | import com.google.devtools.build.lib.analysis.PlatformOptions; |
John Cater | cdfa9ca | 2019-04-05 12:32:09 -0700 | [diff] [blame] | 41 | import com.google.devtools.build.lib.analysis.ResolvedToolchainContext; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 42 | import com.google.devtools.build.lib.analysis.TargetAndConfiguration; |
juliexxia | 71a80dc | 2020-04-09 09:07:09 -0700 | [diff] [blame] | 43 | import com.google.devtools.build.lib.analysis.ToolchainCollection; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 44 | import com.google.devtools.build.lib.analysis.config.BuildConfiguration; |
gregce | 79989f9 | 2021-02-01 07:01:55 -0800 | [diff] [blame] | 45 | import com.google.devtools.build.lib.analysis.config.ConfigConditions; |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 46 | import com.google.devtools.build.lib.analysis.config.ConfigurationResolver; |
jcater | 6718191 | 2020-04-08 10:46:29 -0700 | [diff] [blame] | 47 | import com.google.devtools.build.lib.analysis.config.DependencyEvaluationException; |
Ulf Adams | 25f03d8 | 2016-01-25 10:31:46 +0000 | [diff] [blame] | 48 | import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException; |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 49 | import com.google.devtools.build.lib.analysis.config.TransitionResolver; |
| 50 | import com.google.devtools.build.lib.analysis.config.transitions.ConfigurationTransition; |
| 51 | import com.google.devtools.build.lib.analysis.config.transitions.NoTransition; |
gregce | 2aee44b | 2017-09-16 07:16:44 +0200 | [diff] [blame] | 52 | import com.google.devtools.build.lib.analysis.configuredtargets.MergedConfiguredTarget; |
Samuel Giddins | eadadbd | 2020-08-17 08:00:05 -0700 | [diff] [blame] | 53 | import com.google.devtools.build.lib.analysis.starlark.StarlarkTransition.TransitionException; |
ulfjack | 904a8d6 | 2018-05-29 05:17:35 -0700 | [diff] [blame] | 54 | import com.google.devtools.build.lib.causes.Cause; |
| 55 | import com.google.devtools.build.lib.causes.LabelCause; |
John Field | a97e17f | 2015-11-13 02:19:52 +0000 | [diff] [blame] | 56 | import com.google.devtools.build.lib.cmdline.Label; |
Ulf Adams | 8490173 | 2016-01-28 15:05:16 +0000 | [diff] [blame] | 57 | import com.google.devtools.build.lib.collect.nestedset.NestedSet; |
Marian Lobur | c62faba | 2015-09-09 10:08:06 +0000 | [diff] [blame] | 58 | import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; |
Ulf Adams | 9e16f0a | 2016-01-25 12:43:32 +0000 | [diff] [blame] | 59 | import com.google.devtools.build.lib.events.Event; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 60 | import com.google.devtools.build.lib.events.StoredEventHandler; |
Dmitry Lomov | 2eb8bdd | 2016-04-06 08:47:30 +0000 | [diff] [blame] | 61 | import com.google.devtools.build.lib.packages.Aspect; |
jcater | bc4ef8c | 2020-06-16 13:58:01 -0700 | [diff] [blame] | 62 | import com.google.devtools.build.lib.packages.AspectDefinition; |
Dmitry Lomov | e851fe2 | 2017-02-14 23:11:23 +0000 | [diff] [blame] | 63 | import com.google.devtools.build.lib.packages.AspectDescriptor; |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 64 | import com.google.devtools.build.lib.packages.Attribute; |
Janak Ramakrishnan | 0a4c6e4 | 2015-09-17 00:37:58 +0000 | [diff] [blame] | 65 | import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException; |
Dmitry Lomov | c15ba2e | 2015-10-30 15:50:01 +0000 | [diff] [blame] | 66 | import com.google.devtools.build.lib.packages.NativeAspectClass; |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 67 | import com.google.devtools.build.lib.packages.NoSuchPackageException; |
janakr | f3e6f25 | 2018-01-18 07:45:12 -0800 | [diff] [blame] | 68 | import com.google.devtools.build.lib.packages.NoSuchTargetException; |
Ulf Adams | d55d7af | 2016-01-19 11:03:22 +0000 | [diff] [blame] | 69 | import com.google.devtools.build.lib.packages.NoSuchThingException; |
cparsons | 089148b | 2019-09-17 08:14:41 -0700 | [diff] [blame] | 70 | import com.google.devtools.build.lib.packages.OutputFile; |
Marian Lobur | c62faba | 2015-09-09 10:08:06 +0000 | [diff] [blame] | 71 | import com.google.devtools.build.lib.packages.Package; |
messa | 1bca1bd | 2021-05-14 00:48:19 -0700 | [diff] [blame] | 72 | import com.google.devtools.build.lib.packages.Rule; |
Greg Estren | 0004943 | 2015-08-25 16:43:47 +0000 | [diff] [blame] | 73 | import com.google.devtools.build.lib.packages.RuleClassProvider; |
gregce | 18694cd | 2020-05-12 15:40:05 -0700 | [diff] [blame] | 74 | import com.google.devtools.build.lib.packages.StarlarkAspectClass; |
gregce | d281df7 | 2020-05-11 12:27:06 -0700 | [diff] [blame] | 75 | import com.google.devtools.build.lib.packages.StarlarkDefinedAspect; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 76 | import com.google.devtools.build.lib.packages.Target; |
Googler | c5fcc86 | 2019-09-06 16:17:47 -0700 | [diff] [blame] | 77 | import com.google.devtools.build.lib.packages.Type.ConversionException; |
messa | 1bca1bd | 2021-05-14 00:48:19 -0700 | [diff] [blame] | 78 | import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions; |
tomlu | 72642a2 | 2017-10-18 06:23:14 +0200 | [diff] [blame] | 79 | import com.google.devtools.build.lib.profiler.memory.CurrentRuleTracker; |
leba | b52a190 | 2021-09-23 01:35:13 -0700 | [diff] [blame] | 80 | import com.google.devtools.build.lib.skyframe.AspectKeyCreator.AspectKey; |
brandjon | 771a029 | 2020-05-26 12:04:16 -0700 | [diff] [blame] | 81 | import com.google.devtools.build.lib.skyframe.BzlLoadFunction.BzlLoadFailedException; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 82 | import com.google.devtools.build.lib.skyframe.SkyframeExecutor.BuildViewProvider; |
Greg Estren | d535325 | 2016-08-11 22:13:31 +0000 | [diff] [blame] | 83 | import com.google.devtools.build.lib.util.OrderedSetMultimap; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 84 | import com.google.devtools.build.skyframe.SkyFunction; |
| 85 | import com.google.devtools.build.skyframe.SkyFunctionException; |
| 86 | import com.google.devtools.build.skyframe.SkyKey; |
| 87 | import com.google.devtools.build.skyframe.SkyValue; |
cpeyser | a8a61ee | 2018-01-26 09:20:37 -0800 | [diff] [blame] | 88 | import com.google.devtools.build.skyframe.ValueOrException; |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 89 | import java.util.ArrayList; |
Dmitry Lomov | e851fe2 | 2017-02-14 23:11:23 +0000 | [diff] [blame] | 90 | import java.util.HashMap; |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 91 | import java.util.Map; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 92 | import javax.annotation.Nullable; |
messa | 1bca1bd | 2021-05-14 00:48:19 -0700 | [diff] [blame] | 93 | import net.starlark.java.eval.StarlarkSemantics; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 94 | |
| 95 | /** |
| 96 | * The Skyframe function that generates aspects. |
Dmitry Lomov | e804017 | 2016-04-06 14:53:43 +0000 | [diff] [blame] | 97 | * |
jhorvitz | 8139503 | 2021-05-05 08:48:08 -0700 | [diff] [blame] | 98 | * <p>This class, together with {@link ConfiguredTargetFunction} drives the analysis phase. For more |
ulfjack | 26d0e49 | 2017-08-07 13:42:33 +0200 | [diff] [blame] | 99 | * information, see {@link com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory}. |
Lukacs Berki | 2300cd6 | 2016-05-19 11:06:37 +0000 | [diff] [blame] | 100 | * |
jhorvitz | 8139503 | 2021-05-05 08:48:08 -0700 | [diff] [blame] | 101 | * <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 Lomov | e804017 | 2016-04-06 14:53:43 +0000 | [diff] [blame] | 105 | * |
jhorvitz | 8139503 | 2021-05-05 08:48:08 -0700 | [diff] [blame] | 106 | * <p>See {@link com.google.devtools.build.lib.packages.AspectClass} documentation for an overview |
| 107 | * of aspect-related classes |
Lukacs Berki | 2300cd6 | 2016-05-19 11:06:37 +0000 | [diff] [blame] | 108 | * |
ulfjack | 26d0e49 | 2017-08-07 13:42:33 +0200 | [diff] [blame] | 109 | * @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory |
Lukacs Berki | 2300cd6 | 2016-05-19 11:06:37 +0000 | [diff] [blame] | 110 | * @see com.google.devtools.build.lib.packages.AspectClass |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 111 | */ |
jhorvitz | 8139503 | 2021-05-05 08:48:08 -0700 | [diff] [blame] | 112 | final class AspectFunction implements SkyFunction { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 113 | private final BuildViewProvider buildViewProvider; |
Greg Estren | 0004943 | 2015-08-25 16:43:47 +0000 | [diff] [blame] | 114 | private final RuleClassProvider ruleClassProvider; |
janakr | 931d285 | 2017-12-15 13:48:29 -0800 | [diff] [blame] | 115 | /** |
| 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 Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 121 | |
janakr | 93e3eea | 2017-03-30 22:09:37 +0000 | [diff] [blame] | 122 | AspectFunction( |
| 123 | BuildViewProvider buildViewProvider, |
| 124 | RuleClassProvider ruleClassProvider, |
jhorvitz | 8139503 | 2021-05-05 08:48:08 -0700 | [diff] [blame] | 125 | boolean storeTransitivePackagesForPackageRootResolution) { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 126 | this.buildViewProvider = buildViewProvider; |
Greg Estren | 0004943 | 2015-08-25 16:43:47 +0000 | [diff] [blame] | 127 | this.ruleClassProvider = ruleClassProvider; |
janakr | 931d285 | 2017-12-15 13:48:29 -0800 | [diff] [blame] | 128 | this.storeTransitivePackagesForPackageRootResolution = |
| 129 | storeTransitivePackagesForPackageRootResolution; |
Dmitry Lomov | c15ba2e | 2015-10-30 15:50:01 +0000 | [diff] [blame] | 130 | } |
| 131 | |
| 132 | /** |
gregce | 3377c11 | 2020-04-13 09:29:59 -0700 | [diff] [blame] | 133 | * Load Starlark-defined aspect from an extension file. Is to be called from a SkyFunction. |
cparsons | 0d55f4c | 2017-12-20 14:49:13 -0800 | [diff] [blame] | 134 | * |
| 135 | * @return {@code null} if dependencies cannot be satisfied. |
gregce | d281df7 | 2020-05-11 12:27:06 -0700 | [diff] [blame] | 136 | * @throws AspectCreationException if the value loaded is not a {@link StarlarkDefinedAspect}. |
cparsons | 0d55f4c | 2017-12-20 14:49:13 -0800 | [diff] [blame] | 137 | */ |
| 138 | @Nullable |
messa | ba64b03 | 2021-09-17 15:15:44 -0700 | [diff] [blame] | 139 | public static StarlarkDefinedAspect loadStarlarkDefinedAspect( |
gregce | 18694cd | 2020-05-12 15:40:05 -0700 | [diff] [blame] | 140 | Environment env, StarlarkAspectClass starlarkAspectClass) |
cparsons | 0d55f4c | 2017-12-20 14:49:13 -0800 | [diff] [blame] | 141 | throws AspectCreationException, InterruptedException { |
gregce | d281df7 | 2020-05-11 12:27:06 -0700 | [diff] [blame] | 142 | Label extensionLabel = starlarkAspectClass.getExtensionLabel(); |
| 143 | String starlarkValueName = starlarkAspectClass.getExportedName(); |
cparsons | 0d55f4c | 2017-12-20 14:49:13 -0800 | [diff] [blame] | 144 | |
cmita | 961b176 | 2021-05-25 03:04:22 -0700 | [diff] [blame] | 145 | SkyKey importFileKey = |
| 146 | StarlarkBuiltinsValue.isBuiltinsRepo(extensionLabel.getRepository()) |
| 147 | ? BzlLoadValue.keyForBuiltins(extensionLabel) |
| 148 | : BzlLoadValue.keyForBuild(extensionLabel); |
Ulf Adams | 0678e79 | 2016-01-25 15:30:45 +0000 | [diff] [blame] | 149 | try { |
brandjon | 771a029 | 2020-05-26 12:04:16 -0700 | [diff] [blame] | 150 | BzlLoadValue bzlLoadValue = |
| 151 | (BzlLoadValue) env.getValueOrThrow(importFileKey, BzlLoadFailedException.class); |
| 152 | if (bzlLoadValue == null) { |
cpeyser | 1079809 | 2018-03-23 12:10:25 -0700 | [diff] [blame] | 153 | Preconditions.checkState( |
laurentlb | 7dcad73 | 2018-10-25 05:17:20 -0700 | [diff] [blame] | 154 | env.valuesMissing(), "no Starlark import value for %s", importFileKey); |
Ulf Adams | 0678e79 | 2016-01-25 15:30:45 +0000 | [diff] [blame] | 155 | return null; |
| 156 | } |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 157 | |
brandjon | 771a029 | 2020-05-26 12:04:16 -0700 | [diff] [blame] | 158 | Object starlarkValue = bzlLoadValue.getModule().getGlobal(starlarkValueName); |
gregce | d281df7 | 2020-05-11 12:27:06 -0700 | [diff] [blame] | 159 | if (starlarkValue == null) { |
Dmitry Lomov | 1920dd9 | 2017-07-21 12:57:18 +0200 | [diff] [blame] | 160 | throw new ConversionException( |
jhorvitz | 86409b7 | 2021-10-04 16:55:20 -0700 | [diff] [blame^] | 161 | String.format("%s is not exported from %s", starlarkValueName, extensionLabel)); |
Dmitry Lomov | 1920dd9 | 2017-07-21 12:57:18 +0200 | [diff] [blame] | 162 | } |
messa | ba64b03 | 2021-09-17 15:15:44 -0700 | [diff] [blame] | 163 | if (!(starlarkValue instanceof StarlarkDefinedAspect)) { |
Ulf Adams | 0678e79 | 2016-01-25 15:30:45 +0000 | [diff] [blame] | 164 | throw new ConversionException( |
messa | ba64b03 | 2021-09-17 15:15:44 -0700 | [diff] [blame] | 165 | String.format("%s from %s is not an aspect", starlarkValueName, extensionLabel)); |
Ulf Adams | 0678e79 | 2016-01-25 15:30:45 +0000 | [diff] [blame] | 166 | } |
messa | ba64b03 | 2021-09-17 15:15:44 -0700 | [diff] [blame] | 167 | return (StarlarkDefinedAspect) starlarkValue; |
mschaller | 859c9ac | 2020-09-25 16:09:19 -0700 | [diff] [blame] | 168 | } 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 Adams | 0678e79 | 2016-01-25 15:30:45 +0000 | [diff] [blame] | 172 | env.getListener().handle(Event.error(e.getMessage())); |
ulfjack | 904a8d6 | 2018-05-29 05:17:35 -0700 | [diff] [blame] | 173 | throw new AspectCreationException(e.getMessage(), extensionLabel); |
Dmitry Lomov | c15ba2e | 2015-10-30 15:50:01 +0000 | [diff] [blame] | 174 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 175 | } |
| 176 | |
| 177 | @Nullable |
| 178 | @Override |
| 179 | public SkyValue compute(SkyKey skyKey, Environment env) |
Florian Weikert | 4b67d4f | 2015-09-14 13:35:34 +0000 | [diff] [blame] | 180 | throws AspectFunctionException, InterruptedException { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 181 | SkyframeBuildView view = buildViewProvider.getSkyframeBuildView(); |
ulfjack | 904a8d6 | 2018-05-29 05:17:35 -0700 | [diff] [blame] | 182 | NestedSetBuilder<Cause> transitiveRootCauses = NestedSetBuilder.stableOrder(); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 183 | AspectKey key = (AspectKey) skyKey.argument(); |
Dmitry Lomov | c15ba2e | 2015-10-30 15:50:01 +0000 | [diff] [blame] | 184 | ConfiguredAspectFactory aspectFactory; |
Dmitry Lomov | 2eb8bdd | 2016-04-06 08:47:30 +0000 | [diff] [blame] | 185 | Aspect aspect; |
Luis Fernando Pino Duque | e82713d | 2016-04-26 16:22:38 +0000 | [diff] [blame] | 186 | if (key.getAspectClass() instanceof NativeAspectClass) { |
| 187 | NativeAspectClass nativeAspectClass = (NativeAspectClass) key.getAspectClass(); |
| 188 | aspectFactory = (ConfiguredAspectFactory) nativeAspectClass; |
messa | a4063f6 | 2021-09-09 10:14:45 -0700 | [diff] [blame] | 189 | aspect = Aspect.forNative(nativeAspectClass, key.getParameters()); |
gregce | 18694cd | 2020-05-12 15:40:05 -0700 | [diff] [blame] | 190 | } else if (key.getAspectClass() instanceof StarlarkAspectClass) { |
| 191 | StarlarkAspectClass starlarkAspectClass = (StarlarkAspectClass) key.getAspectClass(); |
gregce | d281df7 | 2020-05-11 12:27:06 -0700 | [diff] [blame] | 192 | StarlarkDefinedAspect starlarkAspect; |
Dmitry Lomov | c15ba2e | 2015-10-30 15:50:01 +0000 | [diff] [blame] | 193 | try { |
gregce | d281df7 | 2020-05-11 12:27:06 -0700 | [diff] [blame] | 194 | starlarkAspect = loadStarlarkDefinedAspect(env, starlarkAspectClass); |
Ulf Adams | 0678e79 | 2016-01-25 15:30:45 +0000 | [diff] [blame] | 195 | } catch (AspectCreationException e) { |
| 196 | throw new AspectFunctionException(e); |
Dmitry Lomov | c15ba2e | 2015-10-30 15:50:01 +0000 | [diff] [blame] | 197 | } |
gregce | d281df7 | 2020-05-11 12:27:06 -0700 | [diff] [blame] | 198 | if (starlarkAspect == null) { |
Dmitry Lomov | c15ba2e | 2015-10-30 15:50:01 +0000 | [diff] [blame] | 199 | return null; |
| 200 | } |
| 201 | |
gregce | 5c8a5f5 | 2020-05-13 10:35:36 -0700 | [diff] [blame] | 202 | aspectFactory = new StarlarkAspectFactory(starlarkAspect); |
gregce | d281df7 | 2020-05-11 12:27:06 -0700 | [diff] [blame] | 203 | aspect = |
gregce | 18694cd | 2020-05-12 15:40:05 -0700 | [diff] [blame] | 204 | Aspect.forStarlark( |
gregce | d281df7 | 2020-05-11 12:27:06 -0700 | [diff] [blame] | 205 | starlarkAspect.getAspectClass(), |
| 206 | starlarkAspect.getDefinition(key.getParameters()), |
messa | a4063f6 | 2021-09-09 10:14:45 -0700 | [diff] [blame] | 207 | key.getParameters()); |
Dmitry Lomov | c15ba2e | 2015-10-30 15:50:01 +0000 | [diff] [blame] | 208 | } else { |
| 209 | throw new IllegalStateException(); |
| 210 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 211 | |
Ulf Adams | 9e16f0a | 2016-01-25 12:43:32 +0000 | [diff] [blame] | 212 | // Keep this in sync with the same code in ConfiguredTargetFunction. |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 213 | PackageValue packageValue = |
| 214 | (PackageValue) env.getValue(PackageValue.key(key.getLabel().getPackageIdentifier())); |
| 215 | if (packageValue == null) { |
| 216 | return null; |
| 217 | } |
Janak Ramakrishnan | 0a4c6e4 | 2015-09-17 00:37:58 +0000 | [diff] [blame] | 218 | Package pkg = packageValue.getPackage(); |
| 219 | if (pkg.containsErrors()) { |
| 220 | throw new AspectFunctionException( |
Ulf Adams | 9e16f0a | 2016-01-25 12:43:32 +0000 | [diff] [blame] | 221 | new BuildFileContainsErrorsException(key.getLabel().getPackageIdentifier())); |
Janak Ramakrishnan | 0a4c6e4 | 2015-09-17 00:37:58 +0000 | [diff] [blame] | 222 | } |
Lukacs Berki | ea988b6 | 2016-08-30 12:26:18 +0000 | [diff] [blame] | 223 | |
cpeyser | a8a61ee | 2018-01-26 09:20:37 -0800 | [diff] [blame] | 224 | boolean aspectHasConfiguration = key.getAspectConfigurationKey() != null; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 225 | |
cpeyser | a8a61ee | 2018-01-26 09:20:37 -0800 | [diff] [blame] | 226 | 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 Adams | 8490173 | 2016-01-28 15:05:16 +0000 | [diff] [blame] | 240 | try { |
cpeyser | a8a61ee | 2018-01-26 09:20:37 -0800 | [diff] [blame] | 241 | baseConfiguredTargetValue = |
| 242 | (ConfiguredTargetValue) baseAndAspectValues.get(key.getBaseConfiguredTargetKey()).get(); |
Ulf Adams | 8490173 | 2016-01-28 15:05:16 +0000 | [diff] [blame] | 243 | } catch (ConfiguredValueCreationException e) { |
ulfjack | 904a8d6 | 2018-05-29 05:17:35 -0700 | [diff] [blame] | 244 | throw new AspectFunctionException( |
mschaller | 859c9ac | 2020-09-25 16:09:19 -0700 | [diff] [blame] | 245 | new AspectCreationException(e.getMessage(), e.getRootCauses(), e.getDetailedExitCode())); |
Ulf Adams | 8490173 | 2016-01-28 15:05:16 +0000 | [diff] [blame] | 246 | } |
cpeyser | a8a61ee | 2018-01-26 09:20:37 -0800 | [diff] [blame] | 247 | |
| 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 Lomov | e2033b1 | 2015-08-19 16:57:49 +0000 | [diff] [blame] | 258 | } |
Lukacs Berki | ea988b6 | 2016-08-30 12:26:18 +0000 | [diff] [blame] | 259 | |
cpeyser | a8a61ee | 2018-01-26 09:20:37 -0800 | [diff] [blame] | 260 | ConfiguredTarget associatedTarget = baseConfiguredTargetValue.getConfiguredTarget(); |
dslomov | 99ea6b4 | 2017-04-25 17:46:17 +0200 | [diff] [blame] | 261 | |
janakr | 171a7eb | 2018-03-26 09:26:53 -0700 | [diff] [blame] | 262 | Package targetPkg; |
| 263 | BuildConfiguration configuration = null; |
| 264 | PackageValue.Key packageKey = |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 265 | PackageValue.key(associatedTarget.getOriginalLabel().getPackageIdentifier()); |
janakr | 171a7eb | 2018-03-26 09:26:53 -0700 | [diff] [blame] | 266 | 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(); |
janakr | 171a7eb | 2018-03-26 09:26:53 -0700 | [diff] [blame] | 286 | } |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 287 | |
| 288 | Target target; |
janakr | f3e6f25 | 2018-01-18 07:45:12 -0800 | [diff] [blame] | 289 | try { |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 290 | target = targetPkg.getTarget(associatedTarget.getOriginalLabel().getName()); |
janakr | f3e6f25 | 2018-01-18 07:45:12 -0800 | [diff] [blame] | 291 | } catch (NoSuchTargetException e) { |
| 292 | throw new IllegalStateException("Name already verified", e); |
| 293 | } |
dslomov | 99ea6b4 | 2017-04-25 17:46:17 +0200 | [diff] [blame] | 294 | |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 295 | if (AliasProvider.isAlias(associatedTarget)) { |
tomlu | 3d1a194 | 2017-11-29 14:01:21 -0800 | [diff] [blame] | 296 | return createAliasAspect( |
| 297 | env, |
jhorvitz | 86409b7 | 2021-10-04 16:55:20 -0700 | [diff] [blame^] | 298 | view.getHostConfiguration(), |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 299 | new TargetAndConfiguration(target, configuration), |
tomlu | 3d1a194 | 2017-11-29 14:01:21 -0800 | [diff] [blame] | 300 | aspect, |
| 301 | key, |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 302 | aspectConfiguration, |
| 303 | associatedTarget); |
Lukacs Berki | ea988b6 | 2016-08-30 12:26:18 +0000 | [diff] [blame] | 304 | } |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 305 | // 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 Berki | ea988b6 | 2016-08-30 12:26:18 +0000 | [diff] [blame] | 315 | |
messa | 1bca1bd | 2021-05-14 00:48:19 -0700 | [diff] [blame] | 316 | // 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) { |
messa | 1bca1bd | 2021-05-14 00:48:19 -0700 | [diff] [blame] | 327 | 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 Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 343 | |
Dmitry Lomov | 1575652 | 2016-12-16 16:52:37 +0000 | [diff] [blame] | 344 | ImmutableList.Builder<Aspect> aspectPathBuilder = ImmutableList.builder(); |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 345 | |
Dmitry Lomov | e851fe2 | 2017-02-14 23:11:23 +0000 | [diff] [blame] | 346 | 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(). |
dslomov | 039b9ee | 2017-04-11 08:51:30 +0000 | [diff] [blame] | 349 | ImmutableList.Builder<SkyKey> aspectPathSkyKeysBuilder = ImmutableList.builder(); |
| 350 | ImmutableMap<AspectDescriptor, SkyKey> aspectKeys = |
| 351 | getSkyKeysForAspectsAndCollectAspectPath(key.getBaseKeys(), aspectPathSkyKeysBuilder); |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 352 | |
Dmitry Lomov | e851fe2 | 2017-02-14 23:11:23 +0000 | [diff] [blame] | 353 | Map<SkyKey, SkyValue> values = env.getValues(aspectKeys.values()); |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 354 | if (env.valuesMissing()) { |
| 355 | return null; |
| 356 | } |
dslomov | 039b9ee | 2017-04-11 08:51:30 +0000 | [diff] [blame] | 357 | ImmutableList<SkyKey> aspectPathSkyKeys = aspectPathSkyKeysBuilder.build(); |
| 358 | for (SkyKey aspectPathSkyKey : aspectPathSkyKeys) { |
| 359 | aspectPathBuilder.add(((AspectValue) values.get(aspectPathSkyKey)).getAspect()); |
| 360 | } |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 361 | try { |
dslomov | 039b9ee | 2017-04-11 08:51:30 +0000 | [diff] [blame] | 362 | associatedTarget = getBaseTarget( |
| 363 | associatedTarget, key.getBaseKeys(), values); |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 364 | } catch (DuplicateException e) { |
mjhalupka | 30bf44c | 2018-01-25 08:22:34 -0800 | [diff] [blame] | 365 | env.getListener() |
| 366 | .handle( |
| 367 | Event.error( |
janakr | 9c10140 | 2018-03-10 06:48:59 -0800 | [diff] [blame] | 368 | associatedConfiguredTargetAndData.getTarget().getLocation(), e.getMessage())); |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 369 | |
| 370 | throw new AspectFunctionException( |
ulfjack | 904a8d6 | 2018-05-29 05:17:35 -0700 | [diff] [blame] | 371 | new AspectCreationException( |
| 372 | e.getMessage(), associatedTarget.getLabel(), aspectConfiguration)); |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 373 | } |
| 374 | } |
janakr | 9c10140 | 2018-03-10 06:48:59 -0800 | [diff] [blame] | 375 | associatedConfiguredTargetAndData = |
| 376 | associatedConfiguredTargetAndData.fromConfiguredTarget(associatedTarget); |
Dmitry Lomov | 1575652 | 2016-12-16 16:52:37 +0000 | [diff] [blame] | 377 | aspectPathBuilder.add(aspect); |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 378 | |
jhorvitz | e68a7d0 | 2021-04-26 11:49:28 -0700 | [diff] [blame] | 379 | SkyframeDependencyResolver resolver = new SkyframeDependencyResolver(env); |
janakr | 931d285 | 2017-12-15 13:48:29 -0800 | [diff] [blame] | 380 | NestedSetBuilder<Package> transitivePackagesForPackageRootResolution = |
| 381 | storeTransitivePackagesForPackageRootResolution ? NestedSetBuilder.stableOrder() : null; |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 382 | |
Michael Staib | 04f6f24 | 2016-03-01 15:40:29 +0000 | [diff] [blame] | 383 | // 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 |
gregce | e0bbe75 | 2017-09-12 23:58:34 +0200 | [diff] [blame] | 385 | // (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 Staib | 04f6f24 | 2016-03-01 15:40:29 +0000 | [diff] [blame] | 387 | // required by all dependencies (both those of the aspect and those of the base target) |
| 388 | // will be present this way. |
| 389 | TargetAndConfiguration originalTargetAndAspectConfiguration = |
janakr | f3e6f25 | 2018-01-18 07:45:12 -0800 | [diff] [blame] | 390 | new TargetAndConfiguration( |
janakr | 9c10140 | 2018-03-10 06:48:59 -0800 | [diff] [blame] | 391 | associatedConfiguredTargetAndData.getTarget(), aspectConfiguration); |
Dmitry Lomov | 1575652 | 2016-12-16 16:52:37 +0000 | [diff] [blame] | 392 | ImmutableList<Aspect> aspectPath = aspectPathBuilder.build(); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 393 | try { |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 394 | UnloadedToolchainContext unloadedToolchainContext = |
| 395 | getUnloadedToolchainContext(env, key, aspect, configuration); |
Greg Estren | 12b06b2 | 2020-09-11 10:58:43 -0700 | [diff] [blame] | 396 | if (env.valuesMissing()) { |
| 397 | return null; |
| 398 | } |
| 399 | |
| 400 | // Get the configuration targets that trigger this rule's configurable attributes. |
gregce | 79989f9 | 2021-02-01 07:01:55 -0800 | [diff] [blame] | 401 | ConfigConditions configConditions = |
Greg Estren | 12b06b2 | 2020-09-11 10:58:43 -0700 | [diff] [blame] | 402 | 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 Cater | 2e56f06 | 2017-07-20 19:43:20 +0200 | [diff] [blame] | 411 | } |
| 412 | |
lberki | 102256f | 2019-02-08 01:34:23 -0800 | [diff] [blame] | 413 | OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> depValueMap; |
Dmitry Lomov | 9b2fc5c | 2016-11-11 11:18:48 +0000 | [diff] [blame] | 414 | try { |
John Cater | 2e56f06 | 2017-07-20 19:43:20 +0200 | [diff] [blame] | 415 | depValueMap = |
| 416 | ConfiguredTargetFunction.computeDependencies( |
| 417 | env, |
| 418 | resolver, |
| 419 | originalTargetAndAspectConfiguration, |
| 420 | aspectPath, |
gregce | 79989f9 | 2021-02-01 07:01:55 -0800 | [diff] [blame] | 421 | configConditions.asProviders(), |
juliexxia | 71a80dc | 2020-04-09 09:07:09 -0700 | [diff] [blame] | 422 | unloadedToolchainContext == null |
| 423 | ? null |
jcater | 5037537 | 2020-06-02 08:51:33 -0700 | [diff] [blame] | 424 | : ToolchainCollection.builder() |
juliexxia | 71a80dc | 2020-04-09 09:07:09 -0700 | [diff] [blame] | 425 | .addDefaultContext(unloadedToolchainContext) |
| 426 | .build(), |
jcater | bc4ef8c | 2020-06-16 13:58:01 -0700 | [diff] [blame] | 427 | shouldUseToolchainTransition(configuration, aspect.getDefinition()), |
John Cater | 2e56f06 | 2017-07-20 19:43:20 +0200 | [diff] [blame] | 428 | ruleClassProvider, |
jhorvitz | 86409b7 | 2021-10-04 16:55:20 -0700 | [diff] [blame^] | 429 | view.getHostConfiguration(), |
janakr | 931d285 | 2017-12-15 13:48:29 -0800 | [diff] [blame] | 430 | transitivePackagesForPackageRootResolution, |
jhorvitz | 8139503 | 2021-05-05 08:48:08 -0700 | [diff] [blame] | 431 | transitiveRootCauses); |
mschaller | 859c9ac | 2020-09-25 16:09:19 -0700 | [diff] [blame] | 432 | } catch (ConfiguredValueCreationException e) { |
| 433 | throw new AspectCreationException( |
| 434 | e.getMessage(), key.getLabel(), aspectConfiguration, e.getDetailedExitCode()); |
Dmitry Lomov | 9b2fc5c | 2016-11-11 11:18:48 +0000 | [diff] [blame] | 435 | } |
Ulf Adams | 8490173 | 2016-01-28 15:05:16 +0000 | [diff] [blame] | 436 | if (depValueMap == null) { |
| 437 | return null; |
| 438 | } |
| 439 | if (!transitiveRootCauses.isEmpty()) { |
mschaller | 859c9ac | 2020-09-25 16:09:19 -0700 | [diff] [blame] | 440 | NestedSet<Cause> causes = transitiveRootCauses.build(); |
Ulf Adams | 8490173 | 2016-01-28 15:05:16 +0000 | [diff] [blame] | 441 | throw new AspectFunctionException( |
mschaller | 859c9ac | 2020-09-25 16:09:19 -0700 | [diff] [blame] | 442 | new AspectCreationException( |
| 443 | "Loading failed", |
| 444 | causes, |
| 445 | ConfiguredTargetFunction.getPrioritizedDetailedExitCode(causes))); |
Ulf Adams | 8490173 | 2016-01-28 15:05:16 +0000 | [diff] [blame] | 446 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 447 | |
John Cater | ae4e785 | 2018-07-09 15:02:42 -0700 | [diff] [blame] | 448 | // Load the requested toolchains into the ToolchainContext, now that we have dependencies. |
John Cater | cdfa9ca | 2019-04-05 12:32:09 -0700 | [diff] [blame] | 449 | ResolvedToolchainContext toolchainContext = null; |
jcater | 1f72416 | 2018-08-27 09:16:01 -0700 | [diff] [blame] | 450 | if (unloadedToolchainContext != null) { |
John Cater | 5074514 | 2019-04-16 07:41:24 -0700 | [diff] [blame] | 451 | String targetDescription = |
| 452 | String.format( |
| 453 | "aspect %s applied to %s", |
| 454 | aspect.getDescriptor().getDescription(), |
| 455 | associatedConfiguredTargetAndData.getTarget()); |
lberki | 102256f | 2019-02-08 01:34:23 -0800 | [diff] [blame] | 456 | toolchainContext = |
John Cater | 5074514 | 2019-04-16 07:41:24 -0700 | [diff] [blame] | 457 | ResolvedToolchainContext.load( |
John Cater | 5074514 | 2019-04-16 07:41:24 -0700 | [diff] [blame] | 458 | unloadedToolchainContext, |
| 459 | targetDescription, |
jcater | 6415e5c | 2020-07-15 14:17:53 -0700 | [diff] [blame] | 460 | // TODO(161222568): Support exec groups on aspects. |
| 461 | depValueMap.get(DependencyKind.defaultExecGroupToolchain())); |
John Cater | ae4e785 | 2018-07-09 15:02:42 -0700 | [diff] [blame] | 462 | } |
| 463 | |
Dmitry Lomov | 0b832ce | 2015-10-20 10:03:14 +0000 | [diff] [blame] | 464 | return createAspect( |
| 465 | env, |
| 466 | key, |
Dmitry Lomov | 1575652 | 2016-12-16 16:52:37 +0000 | [diff] [blame] | 467 | aspectPath, |
Dmitry Lomov | 2eb8bdd | 2016-04-06 08:47:30 +0000 | [diff] [blame] | 468 | aspect, |
Dmitry Lomov | 0b832ce | 2015-10-20 10:03:14 +0000 | [diff] [blame] | 469 | aspectFactory, |
janakr | 9c10140 | 2018-03-10 06:48:59 -0800 | [diff] [blame] | 470 | associatedConfiguredTargetAndData, |
cpeyser | a8a61ee | 2018-01-26 09:20:37 -0800 | [diff] [blame] | 471 | aspectConfiguration, |
Dmitry Lomov | 0b832ce | 2015-10-20 10:03:14 +0000 | [diff] [blame] | 472 | configConditions, |
John Cater | 2e56f06 | 2017-07-20 19:43:20 +0200 | [diff] [blame] | 473 | toolchainContext, |
Dmitry Lomov | 0b832ce | 2015-10-20 10:03:14 +0000 | [diff] [blame] | 474 | depValueMap, |
janakr | 931d285 | 2017-12-15 13:48:29 -0800 | [diff] [blame] | 475 | transitivePackagesForPackageRootResolution); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 476 | } catch (DependencyEvaluationException e) { |
gregce | c564977 | 2021-07-08 13:10:19 -0700 | [diff] [blame] | 477 | // 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 Adams | 25f03d8 | 2016-01-25 10:31:46 +0000 | [diff] [blame] | 483 | if (e.getCause() instanceof ConfiguredValueCreationException) { |
| 484 | ConfiguredValueCreationException cause = (ConfiguredValueCreationException) e.getCause(); |
ulfjack | 904a8d6 | 2018-05-29 05:17:35 -0700 | [diff] [blame] | 485 | throw new AspectFunctionException( |
mschaller | 859c9ac | 2020-09-25 16:09:19 -0700 | [diff] [blame] | 486 | new AspectCreationException( |
| 487 | cause.getMessage(), cause.getRootCauses(), cause.getDetailedExitCode())); |
Dmitry Lomov | d83af9e | 2017-02-23 15:44:23 +0000 | [diff] [blame] | 488 | } else if (e.getCause() instanceof InconsistentAspectOrderException) { |
| 489 | InconsistentAspectOrderException cause = (InconsistentAspectOrderException) e.getCause(); |
gregce | c564977 | 2021-07-08 13:10:19 -0700 | [diff] [blame] | 490 | env.getListener().handle(Event.error(cause.getLocation(), cause.getMessage())); |
ulfjack | 904a8d6 | 2018-05-29 05:17:35 -0700 | [diff] [blame] | 491 | throw new AspectFunctionException( |
| 492 | new AspectCreationException(cause.getMessage(), key.getLabel(), aspectConfiguration)); |
Samuel Giddins | eadadbd | 2020-08-17 08:00:05 -0700 | [diff] [blame] | 493 | } 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 Adams | 25f03d8 | 2016-01-25 10:31:46 +0000 | [diff] [blame] | 497 | } 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(); |
ulfjack | 904a8d6 | 2018-05-29 05:17:35 -0700 | [diff] [blame] | 501 | throw new AspectFunctionException( |
mschaller | 859c9ac | 2020-09-25 16:09:19 -0700 | [diff] [blame] | 502 | new AspectCreationException( |
| 503 | cause.getMessage(), |
| 504 | key.getLabel(), |
| 505 | aspectConfiguration, |
| 506 | cause.getDetailedExitCode())); |
Ulf Adams | 25f03d8 | 2016-01-25 10:31:46 +0000 | [diff] [blame] | 507 | } |
Marian Lobur | fc567b3 | 2015-09-14 08:44:25 +0000 | [diff] [blame] | 508 | } catch (AspectCreationException e) { |
| 509 | throw new AspectFunctionException(e); |
gregce | c564977 | 2021-07-08 13:10:19 -0700 | [diff] [blame] | 510 | } catch (ConfiguredValueCreationException e) { |
| 511 | throw new AspectFunctionException(e); |
jcater | 3fed869 | 2019-04-01 13:36:36 -0700 | [diff] [blame] | 512 | } catch (ToolchainException e) { |
| 513 | throw new AspectFunctionException( |
| 514 | new AspectCreationException( |
mschaller | 1511dd2 | 2020-09-21 14:19:33 -0700 | [diff] [blame] | 515 | e.getMessage(), new LabelCause(key.getLabel(), e.getDetailedExitCode()))); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 516 | } |
| 517 | } |
| 518 | |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 519 | @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 Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 550 | /** |
jcater | bc4ef8c | 2020-06-16 13:58:01 -0700 | [diff] [blame] | 551 | * 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 Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 572 | * |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 573 | * @return A {@link ConfiguredTarget} that is a result of a merge. |
| 574 | * @throws DuplicateException if there is a duplicate provider provided by aspects. |
| 575 | */ |
jcater | bc4ef8c | 2020-06-16 13:58:01 -0700 | [diff] [blame] | 576 | private static ConfiguredTarget getBaseTarget( |
| 577 | ConfiguredTarget target, ImmutableList<AspectKey> aspectKeys, Map<SkyKey, SkyValue> values) |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 578 | throws DuplicateException { |
| 579 | ArrayList<ConfiguredAspect> aspectValues = new ArrayList<>(); |
Dmitry Lomov | e851fe2 | 2017-02-14 23:11:23 +0000 | [diff] [blame] | 580 | for (AspectKey aspectKey : aspectKeys) { |
janakr | 573807d | 2018-01-11 14:02:35 -0800 | [diff] [blame] | 581 | AspectValue aspectValue = (AspectValue) values.get(aspectKey); |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 582 | ConfiguredAspect configuredAspect = aspectValue.getConfiguredAspect(); |
| 583 | aspectValues.add(configuredAspect); |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 584 | } |
| 585 | return MergedConfiguredTarget.of(target, aspectValues); |
| 586 | } |
| 587 | |
| 588 | /** |
jhorvitz | e362fc9 | 2021-04-22 16:04:44 -0700 | [diff] [blame] | 589 | * Collect all SkyKeys that are needed for a given list of AspectKeys, including transitive |
| 590 | * dependencies. |
dslomov | 039b9ee | 2017-04-11 08:51:30 +0000 | [diff] [blame] | 591 | * |
jhorvitz | e362fc9 | 2021-04-22 16:04:44 -0700 | [diff] [blame] | 592 | * <p>Also collects all propagating aspects in correct order. |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 593 | */ |
jhorvitz | e362fc9 | 2021-04-22 16:04:44 -0700 | [diff] [blame] | 594 | private static ImmutableMap<AspectDescriptor, SkyKey> getSkyKeysForAspectsAndCollectAspectPath( |
| 595 | ImmutableList<AspectKey> keys, ImmutableList.Builder<SkyKey> aspectPathBuilder) { |
Dmitry Lomov | e851fe2 | 2017-02-14 23:11:23 +0000 | [diff] [blame] | 596 | HashMap<AspectDescriptor, SkyKey> result = new HashMap<>(); |
| 597 | for (AspectKey key : keys) { |
dslomov | 039b9ee | 2017-04-11 08:51:30 +0000 | [diff] [blame] | 598 | buildSkyKeys(key, result, aspectPathBuilder); |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 599 | } |
Dmitry Lomov | e851fe2 | 2017-02-14 23:11:23 +0000 | [diff] [blame] | 600 | return ImmutableMap.copyOf(result); |
Dmitry Lomov | ca9bfa4 | 2016-11-15 13:22:36 +0000 | [diff] [blame] | 601 | } |
| 602 | |
jhorvitz | e362fc9 | 2021-04-22 16:04:44 -0700 | [diff] [blame] | 603 | private static void buildSkyKeys( |
| 604 | AspectKey key, |
| 605 | HashMap<AspectDescriptor, SkyKey> result, |
dslomov | 039b9ee | 2017-04-11 08:51:30 +0000 | [diff] [blame] | 606 | ImmutableList.Builder<SkyKey> aspectPathBuilder) { |
Dmitry Lomov | e851fe2 | 2017-02-14 23:11:23 +0000 | [diff] [blame] | 607 | if (result.containsKey(key.getAspectDescriptor())) { |
| 608 | return; |
| 609 | } |
| 610 | ImmutableList<AspectKey> baseKeys = key.getBaseKeys(); |
janakr | 573807d | 2018-01-11 14:02:35 -0800 | [diff] [blame] | 611 | result.put(key.getAspectDescriptor(), key); |
Dmitry Lomov | e851fe2 | 2017-02-14 23:11:23 +0000 | [diff] [blame] | 612 | for (AspectKey baseKey : baseKeys) { |
dslomov | 039b9ee | 2017-04-11 08:51:30 +0000 | [diff] [blame] | 613 | buildSkyKeys(baseKey, result, aspectPathBuilder); |
Dmitry Lomov | e851fe2 | 2017-02-14 23:11:23 +0000 | [diff] [blame] | 614 | } |
dslomov | 039b9ee | 2017-04-11 08:51:30 +0000 | [diff] [blame] | 615 | // Post-order list of aspect SkyKeys gives the order of propagating aspects: |
| 616 | // the aspect comes after all aspects it transitively sees. |
janakr | 573807d | 2018-01-11 14:02:35 -0800 | [diff] [blame] | 617 | aspectPathBuilder.add(key); |
Dmitry Lomov | e851fe2 | 2017-02-14 23:11:23 +0000 | [diff] [blame] | 618 | } |
dslomov | fa50c3d | 2017-05-08 08:47:44 -0400 | [diff] [blame] | 619 | |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 620 | /** |
| 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 Ramakrishnan | 3c0adb2 | 2016-08-15 21:54:55 +0000 | [diff] [blame] | 626 | Environment env, |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 627 | BuildConfiguration hostConfiguration, |
| 628 | TargetAndConfiguration originalTarget, |
Janak Ramakrishnan | 3c0adb2 | 2016-08-15 21:54:55 +0000 | [diff] [blame] | 629 | Aspect aspect, |
Lukacs Berki | ea988b6 | 2016-08-30 12:26:18 +0000 | [diff] [blame] | 630 | AspectKey originalKey, |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 631 | BuildConfiguration aspectConfiguration, |
janakr | 93e3eea | 2017-03-30 22:09:37 +0000 | [diff] [blame] | 632 | ConfiguredTarget configuredTarget) |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 633 | throws AspectFunctionException, InterruptedException { |
| 634 | ImmutableList<Label> aliasChain = |
| 635 | configuredTarget.getProvider(AliasProvider.class).getAliasChain(); |
Lukacs Berki | ea988b6 | 2016-08-30 12:26:18 +0000 | [diff] [blame] | 636 | // Find the next alias in the chain: either the next alias (if there are two) or the name of |
| 637 | // the real configured target. |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 638 | Label aliasedLabel = aliasChain.size() > 1 ? aliasChain.get(1) : configuredTarget.getLabel(); |
Lukacs Berki | ea988b6 | 2016-08-30 12:26:18 +0000 | [diff] [blame] | 639 | |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 640 | 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); |
cparsons | 089148b | 2019-09-17 08:14:41 -0700 | [diff] [blame] | 729 | } |
| 730 | |
jhorvitz | 86409b7 | 2021-10-04 16:55:20 -0700 | [diff] [blame^] | 731 | private static AspectValue createAliasAspect( |
cparsons | 089148b | 2019-09-17 08:14:41 -0700 | [diff] [blame] | 732 | Environment env, |
| 733 | Target originalTarget, |
cparsons | 089148b | 2019-09-17 08:14:41 -0700 | [diff] [blame] | 734 | AspectKey originalKey, |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 735 | Aspect aspect, |
| 736 | AspectKey depKey, |
| 737 | @Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution) |
cparsons | 089148b | 2019-09-17 08:14:41 -0700 | [diff] [blame] | 738 | throws InterruptedException { |
Lukacs Berki | ea988b6 | 2016-08-30 12:26:18 +0000 | [diff] [blame] | 739 | // Compute the AspectValue of the target the alias refers to (which can itself be either an |
| 740 | // alias or a real target) |
Lukacs Berki | 549bfce | 2016-04-22 15:29:12 +0000 | [diff] [blame] | 741 | AspectValue real = (AspectValue) env.getValue(depKey); |
| 742 | if (env.valuesMissing()) { |
| 743 | return null; |
| 744 | } |
| 745 | |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 746 | NestedSet<Package> finalTransitivePackagesForPackageRootResolution = null; |
| 747 | if (transitivePackagesForPackageRootResolution != null) { |
| 748 | finalTransitivePackagesForPackageRootResolution = |
| 749 | transitivePackagesForPackageRootResolution |
| 750 | .addTransitive(real.getTransitivePackagesForPackageRootResolution()) |
| 751 | .add(originalTarget.getPackage()) |
| 752 | .build(); |
| 753 | } |
Lukacs Berki | 549bfce | 2016-04-22 15:29:12 +0000 | [diff] [blame] | 754 | return new AspectValue( |
| 755 | originalKey, |
| 756 | aspect, |
Lukacs Berki | 549bfce | 2016-04-22 15:29:12 +0000 | [diff] [blame] | 757 | originalTarget.getLocation(), |
| 758 | ConfiguredAspect.forAlias(real.getConfiguredAspect()), |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 759 | 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()); |
leba | b52a190 | 2021-09-23 01:35:13 -0700 | [diff] [blame] | 782 | return AspectKeyCreator.createAspectKey( |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 783 | 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 Berki | 549bfce | 2016-04-22 15:29:12 +0000 | [diff] [blame] | 820 | } |
| 821 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 822 | @Nullable |
Dmitry Lomov | 0b832ce | 2015-10-20 10:03:14 +0000 | [diff] [blame] | 823 | private AspectValue createAspect( |
| 824 | Environment env, |
| 825 | AspectKey key, |
Dmitry Lomov | 1575652 | 2016-12-16 16:52:37 +0000 | [diff] [blame] | 826 | ImmutableList<Aspect> aspectPath, |
Dmitry Lomov | 2eb8bdd | 2016-04-06 08:47:30 +0000 | [diff] [blame] | 827 | Aspect aspect, |
Dmitry Lomov | 0b832ce | 2015-10-20 10:03:14 +0000 | [diff] [blame] | 828 | ConfiguredAspectFactory aspectFactory, |
janakr | 9c10140 | 2018-03-10 06:48:59 -0800 | [diff] [blame] | 829 | ConfiguredTargetAndData associatedTarget, |
Michael Staib | 04f6f24 | 2016-03-01 15:40:29 +0000 | [diff] [blame] | 830 | BuildConfiguration aspectConfiguration, |
gregce | 79989f9 | 2021-02-01 07:01:55 -0800 | [diff] [blame] | 831 | ConfigConditions configConditions, |
John Cater | cdfa9ca | 2019-04-05 12:32:09 -0700 | [diff] [blame] | 832 | ResolvedToolchainContext toolchainContext, |
lberki | 102256f | 2019-02-08 01:34:23 -0800 | [diff] [blame] | 833 | OrderedSetMultimap<DependencyKind, ConfiguredTargetAndData> directDeps, |
janakr | 931d285 | 2017-12-15 13:48:29 -0800 | [diff] [blame] | 834 | @Nullable NestedSetBuilder<Package> transitivePackagesForPackageRootResolution) |
Dmitry Lomov | 0b832ce | 2015-10-20 10:03:14 +0000 | [diff] [blame] | 835 | throws AspectFunctionException, InterruptedException { |
brandjon | 66b6463 | 2020-12-17 14:11:32 -0800 | [diff] [blame] | 836 | // Should be successfully evaluated and cached from the loading phase. |
| 837 | StarlarkBuiltinsValue starlarkBuiltinsValue = |
| 838 | (StarlarkBuiltinsValue) env.getValue(StarlarkBuiltinsValue.key()); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 839 | if (env.valuesMissing()) { |
| 840 | return null; |
| 841 | } |
| 842 | |
brandjon | 66b6463 | 2020-12-17 14:11:32 -0800 | [diff] [blame] | 843 | SkyframeBuildView view = buildViewProvider.getSkyframeBuildView(); |
| 844 | |
| 845 | StoredEventHandler events = new StoredEventHandler(); |
| 846 | CachingAnalysisEnvironment analysisEnvironment = |
| 847 | view.createAnalysisEnvironment( |
jhorvitz | e362fc9 | 2021-04-22 16:04:44 -0700 | [diff] [blame] | 848 | key, events, env, aspectConfiguration, starlarkBuiltinsValue); |
brandjon | 66b6463 | 2020-12-17 14:11:32 -0800 | [diff] [blame] | 849 | |
Dmitry Lomov | 6cd9897 | 2017-03-01 15:44:00 +0000 | [diff] [blame] | 850 | ConfiguredAspect configuredAspect; |
cparsons | 089148b | 2019-09-17 08:14:41 -0700 | [diff] [blame] | 851 | if (aspect.getDefinition().applyToGeneratingRules() |
| 852 | && associatedTarget.getTarget() instanceof OutputFile) { |
| 853 | OutputFile outputFile = (OutputFile) associatedTarget.getTarget(); |
| 854 | Label label = outputFile.getGeneratingRule().getLabel(); |
kmb | b495a44 | 2021-08-25 19:45:28 -0700 | [diff] [blame] | 855 | return createAliasAspect( |
| 856 | env, |
| 857 | associatedTarget.getTarget(), |
| 858 | key, |
| 859 | aspect, |
| 860 | key.withLabel(label), |
| 861 | transitivePackagesForPackageRootResolution); |
cparsons | 089148b | 2019-09-17 08:14:41 -0700 | [diff] [blame] | 862 | } else if (AspectResolver.aspectMatchesConfiguredTarget(associatedTarget, aspect)) { |
tomlu | 72642a2 | 2017-10-18 06:23:14 +0200 | [diff] [blame] | 863 | 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, |
jhorvitz | 86409b7 | 2021-10-04 16:55:20 -0700 | [diff] [blame^] | 877 | view.getHostConfiguration(), |
janakr | eaff19c | 2019-01-31 13:59:40 -0800 | [diff] [blame] | 878 | key); |
ulfjack | 3740768 | 2019-09-17 06:30:49 -0700 | [diff] [blame] | 879 | } catch (MissingDepException e) { |
| 880 | Preconditions.checkState(env.valuesMissing()); |
| 881 | return null; |
jcater | 0b385bd | 2020-04-08 15:27:07 -0700 | [diff] [blame] | 882 | } catch (ActionConflictException e) { |
| 883 | throw new AspectFunctionException(e); |
juliexxia | 6fe70c2 | 2020-05-18 14:38:42 -0700 | [diff] [blame] | 884 | } catch (InvalidExecGroupException e) { |
| 885 | throw new AspectFunctionException(e); |
tomlu | 72642a2 | 2017-10-18 06:23:14 +0200 | [diff] [blame] | 886 | } finally { |
| 887 | CurrentRuleTracker.endConfiguredAspect(); |
| 888 | } |
Dmitry Lomov | 6cd9897 | 2017-03-01 15:44:00 +0000 | [diff] [blame] | 889 | } else { |
janakr | f15d08d | 2020-04-22 12:53:03 -0700 | [diff] [blame] | 890 | configuredAspect = ConfiguredAspect.forNonapplicableTarget(); |
Dmitry Lomov | 6cd9897 | 2017-03-01 15:44:00 +0000 | [diff] [blame] | 891 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 892 | |
| 893 | events.replayOn(env.getListener()); |
| 894 | if (events.hasErrors()) { |
| 895 | analysisEnvironment.disable(associatedTarget.getTarget()); |
janakr | 043acd9 | 2020-02-28 18:59:06 -0800 | [diff] [blame] | 896 | String msg = "Analysis of target '" + associatedTarget.getTarget().getLabel() + "' failed"; |
janakr | f3e6f25 | 2018-01-18 07:45:12 -0800 | [diff] [blame] | 897 | throw new AspectFunctionException( |
ulfjack | 904a8d6 | 2018-05-29 05:17:35 -0700 | [diff] [blame] | 898 | new AspectCreationException(msg, key.getLabel(), aspectConfiguration)); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 899 | } |
| 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 Lomov | b487ac6 | 2015-11-09 13:09:12 +0000 | [diff] [blame] | 908 | Preconditions.checkNotNull(configuredAspect); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 909 | |
| 910 | return new AspectValue( |
Dmitry Lomov | e2033b1 | 2015-08-19 16:57:49 +0000 | [diff] [blame] | 911 | key, |
Dmitry Lomov | 2eb8bdd | 2016-04-06 08:47:30 +0000 | [diff] [blame] | 912 | aspect, |
Dmitry Lomov | e2033b1 | 2015-08-19 16:57:49 +0000 | [diff] [blame] | 913 | associatedTarget.getTarget().getLocation(), |
Dmitry Lomov | b487ac6 | 2015-11-09 13:09:12 +0000 | [diff] [blame] | 914 | configuredAspect, |
janakr | 931d285 | 2017-12-15 13:48:29 -0800 | [diff] [blame] | 915 | transitivePackagesForPackageRootResolution == null |
| 916 | ? null |
Googler | ce6ad29 | 2019-12-20 10:29:21 -0800 | [diff] [blame] | 917 | : transitivePackagesForPackageRootResolution.build()); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 918 | } |
| 919 | |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 920 | @Override |
| 921 | public String extractTag(SkyKey skyKey) { |
Michael Staib | 2707a88 | 2016-09-16 21:06:40 +0000 | [diff] [blame] | 922 | AspectKey aspectKey = (AspectKey) skyKey.argument(); |
| 923 | return Label.print(aspectKey.getLabel()); |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 924 | } |
Marian Lobur | c62faba | 2015-09-09 10:08:06 +0000 | [diff] [blame] | 925 | |
tomlu | 39a0a38 | 2018-06-22 09:43:23 -0700 | [diff] [blame] | 926 | /** Used to indicate errors during the computation of an {@link AspectValue}. */ |
| 927 | public static final class AspectFunctionException extends SkyFunctionException { |
Ulf Adams | 9e16f0a | 2016-01-25 12:43:32 +0000 | [diff] [blame] | 928 | public AspectFunctionException(NoSuchThingException e) { |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 929 | super(e, Transience.PERSISTENT); |
| 930 | } |
| 931 | |
Ulf Adams | 9e16f0a | 2016-01-25 12:43:32 +0000 | [diff] [blame] | 932 | public AspectFunctionException(AspectCreationException e) { |
| 933 | super(e, Transience.PERSISTENT); |
Ulf Adams | d55d7af | 2016-01-19 11:03:22 +0000 | [diff] [blame] | 934 | } |
Dmitry Lomov | d83af9e | 2017-02-23 15:44:23 +0000 | [diff] [blame] | 935 | |
gregce | c564977 | 2021-07-08 13:10:19 -0700 | [diff] [blame] | 936 | public AspectFunctionException(ConfiguredValueCreationException e) { |
| 937 | super(e, Transience.PERSISTENT); |
| 938 | } |
| 939 | |
juliexxia | 6fe70c2 | 2020-05-18 14:38:42 -0700 | [diff] [blame] | 940 | public AspectFunctionException(InvalidExecGroupException e) { |
| 941 | super(e, Transience.PERSISTENT); |
| 942 | } |
| 943 | |
janakr | 0175ce3 | 2018-02-26 15:54:57 -0800 | [diff] [blame] | 944 | public AspectFunctionException(ActionConflictException cause) { |
Dmitry Lomov | d83af9e | 2017-02-23 15:44:23 +0000 | [diff] [blame] | 945 | super(cause, Transience.PERSISTENT); |
| 946 | } |
Ulf Adams | d55d7af | 2016-01-19 11:03:22 +0000 | [diff] [blame] | 947 | } |
Han-Wen Nienhuys | d08b27f | 2015-02-25 16:45:20 +0100 | [diff] [blame] | 948 | } |