// Copyright 2014 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.devtools.build.lib.analysis; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; import com.google.common.collect.Sets; import com.google.common.eventbus.EventBus; import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; import com.google.devtools.build.lib.actions.ActionGraph; import com.google.devtools.build.lib.actions.ActionLookupValue; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ArtifactFactory; import com.google.devtools.build.lib.actions.ArtifactOwner; import com.google.devtools.build.lib.actions.PackageRoots; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection; import com.google.devtools.build.lib.analysis.config.BuildOptions; import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException; import com.google.devtools.build.lib.analysis.constraints.TopLevelConstraintSemantics; import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory; import com.google.devtools.build.lib.analysis.test.CoverageReportActionFactory.CoverageReportActionsWrapper; import com.google.devtools.build.lib.analysis.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible; import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.ExtendedEventHandler; import com.google.devtools.build.lib.packages.AspectClass; import com.google.devtools.build.lib.packages.AspectDescriptor; import com.google.devtools.build.lib.packages.AspectParameters; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.NativeAspectClass; import com.google.devtools.build.lib.packages.NoSuchPackageException; import com.google.devtools.build.lib.packages.NoSuchTargetException; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.packages.TargetUtils; import com.google.devtools.build.lib.pkgcache.PackageManager.PackageManagerStatistics; import com.google.devtools.build.lib.profiler.Profiler; import com.google.devtools.build.lib.profiler.SilentCloseable; import com.google.devtools.build.lib.skyframe.AspectValue; import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey; import com.google.devtools.build.lib.skyframe.AspectValue.AspectValueKey; import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey; import com.google.devtools.build.lib.skyframe.CoverageReportValue; import com.google.devtools.build.lib.skyframe.PrepareAnalysisPhaseValue; import com.google.devtools.build.lib.skyframe.SkyframeAnalysisResult; import com.google.devtools.build.lib.skyframe.SkyframeBuildView; import com.google.devtools.build.lib.skyframe.SkyframeExecutor; import com.google.devtools.build.lib.skyframe.TargetPatternPhaseValue; import com.google.devtools.build.lib.syntax.SkylarkImport; import com.google.devtools.build.lib.syntax.SkylarkImports; import com.google.devtools.build.lib.syntax.SkylarkImports.SkylarkImportSyntaxException; import com.google.devtools.build.lib.util.Pair; import com.google.devtools.build.lib.util.RegexFilter; import com.google.devtools.build.skyframe.SkyKey; import com.google.devtools.build.skyframe.WalkableGraph; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import java.util.logging.Logger; import java.util.stream.Collectors; import javax.annotation.Nullable; /** * The BuildView presents a semantically-consistent and transitively-closed * dependency graph for some set of packages. * *

Package design

* *

This package contains the Blaze dependency analysis framework (aka * "analysis phase"). The goal of this code is to perform semantic analysis of * all of the build targets required for a given build, to report * errors/warnings for any problems in the input, and to construct an "action * graph" (see {@code lib.actions} package) correctly representing the work to * be done during the execution phase of the build. * *

Configurations the inputs to a build come from two sources: the * intrinsic inputs, specified in the BUILD file, are called targets. * The environmental inputs, coming from the build tool, the command-line, or * configuration files, are called the configuration. Only when a * target and a configuration are combined is there sufficient information to * perform a build.

* *

Targets are implemented by the {@link Target} hierarchy in the {@code * lib.packages} code. Configurations are implemented by {@link * BuildConfiguration}. The pair of these together is represented by an * instance of class {@link ConfiguredTarget}; this is the root of a hierarchy * with different implementations for each kind of target: source file, derived * file, rules, etc. * *

The framework code in this package (as opposed to its subpackages) is * responsible for constructing the {@code ConfiguredTarget} graph for a given * target and configuration, taking care of such issues as: *

* *

See also {@link ConfiguredTarget} which documents some important * invariants. */ public class BuildView { private static final Logger logger = Logger.getLogger(BuildView.class.getName()); private final BlazeDirectories directories; private final SkyframeExecutor skyframeExecutor; private final SkyframeBuildView skyframeBuildView; private final ConfiguredRuleClassProvider ruleClassProvider; /** * A factory class to create the coverage report action. May be null. */ @Nullable private final CoverageReportActionFactory coverageReportActionFactory; public BuildView(BlazeDirectories directories, ConfiguredRuleClassProvider ruleClassProvider, SkyframeExecutor skyframeExecutor, CoverageReportActionFactory coverageReportActionFactory) { this.directories = directories; this.coverageReportActionFactory = coverageReportActionFactory; this.ruleClassProvider = ruleClassProvider; this.skyframeExecutor = Preconditions.checkNotNull(skyframeExecutor); this.skyframeBuildView = skyframeExecutor.getSkyframeBuildView(); } /** The number of targets freshly evaluated in the last analysis run. */ public int getTargetsVisited() { return skyframeBuildView.getEvaluatedTargetKeys().size(); } public int getActionsConstructed() { return skyframeBuildView.getEvaluatedActionCount(); } public PackageManagerStatistics getAndClearPkgManagerStatistics() { return skyframeExecutor.getPackageManager().getAndClearStatistics(); } private ArtifactFactory getArtifactFactory() { return skyframeBuildView.getArtifactFactory(); } /** Returns the collection of configured targets corresponding to any of the provided targets. */ @VisibleForTesting static LinkedHashSet filterTestsByTargets( Collection targets, Set