Move RuleConfiguredTargetFactory to lib.analysis
This is part of splitting up the build-base library into separate libraries for
analysis, exec, and rules.
PiperOrigin-RevId: 164446955
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java
index 23df295..5b2646a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspect.java
@@ -50,7 +50,7 @@
* <p>For more information about aspects, see {@link
* com.google.devtools.build.lib.packages.AspectClass}.
*
- * @see com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory
+ * @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory
* @see com.google.devtools.build.lib.packages.AspectClass
*/
@Immutable
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
index 2d13abd..9f16d96 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
@@ -48,7 +48,6 @@
import com.google.devtools.build.lib.packages.RuleClassProvider;
import com.google.devtools.build.lib.packages.RuleErrorConsumer;
import com.google.devtools.build.lib.packages.Target;
-import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.rules.SkylarkModules;
import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
import com.google.devtools.build.lib.syntax.Environment;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java
index 028c8c5..a01910a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java
@@ -33,7 +33,7 @@
*
* <p>Created by {@link RuleConfiguredTargetBuilder}. There is an instance of this class for every
* analyzed rule. For more information about how analysis works, see {@link
- * com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory}.
+ * com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory}.
*/
public final class RuleConfiguredTarget extends AbstractConfiguredTarget {
/**
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
index fc7bcf6..a11536a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetBuilder.java
@@ -52,9 +52,9 @@
*
* <p>This is used to tell Bazel which {@link TransitiveInfoProvider}s are produced by the analysis
* of a configured target. For more information about analysis, see
- * {@link com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory}.
+ * {@link com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory}.
*
- * @see com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory
+ * @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory
*/
public final class RuleConfiguredTargetBuilder {
private final RuleContext ruleContext;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetFactory.java
new file mode 100644
index 0000000..30b1ef3
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTargetFactory.java
@@ -0,0 +1,120 @@
+// 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.devtools.build.lib.actions.ActionAnalysisMetadata;
+import com.google.devtools.build.lib.packages.RuleClass;
+
+/**
+ * A shortcut class to the appropriate specialization of {@code RuleClass.ConfiguredTargetFactory}.
+ *
+ * <p>Here follows an overview of how loading and analysis works in Bazel:
+ *
+ * <p>Actions (i.e. commands that are run during the build) are created by configured targets
+ * (see {@link ConfiguredTarget}), which are a pair of a target (e.g. <code>//src:bazel</code>) and
+ * a {@link com.google.devtools.build.lib.analysis.config.BuildConfiguration}, which is a blob of
+ * data that contains extra information about how the target should be built (for example, for which
+ * platform or with which C++ preprocessor definitions). Accordingly, a target can give rise to
+ * multiple configured targets, for example, if it needs to be built both for the host and the
+ * target configuration.
+ *
+ * <p>The process of creating the appropriate {@link com.google.devtools.build.lib.actions.Action}s
+ * for a configured target is called "analysis". The analysis of a configured target is composed of
+ * the following steps (which process is orchestrated by
+ * {@link com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction}):
+ * <ol>
+ * <li>The corresponding {@link com.google.devtools.build.lib.packages.Target} is loaded, i.e.
+ * the BUILD file is parsed.</li>
+ * <li>Its direct dependencies are analyzed, during which in turn indirect dependencies are
+ * also analyzed.</li>
+ * <li>Aspects specified by the configured target are analyzed. These can be thought of as
+ * visitations of the transitive dependencies of the target. For more information, see
+ * {@link com.google.devtools.build.lib.packages.AspectClass}.
+ * <li>The configured target and the actions it generates are created based on the data from the
+ * previous two steps.</li>
+ * </ol>
+ *
+ * Targets can be of three main kinds (plus a few special ones which are not important for
+ * understanding the big picture):
+ * <p>
+ * <li>Input and output files. These represent either a file that is in the source tree or a
+ * file produced by during the build. Not every file produced during the build has a
+ * corresponding output file target.</li>
+ * <li>Rules. These describe things a build actually does. Each rule has a class (e.g.
+ * <code>cc_binary</code>). Rule classes can be defined either in Skylark using the
+ * <code>rule()</code> function or in Java code by implementing
+ * {@link com.google.devtools.build.lib.analysis.RuleDefinition}.</li>
+ * </p>
+ * <p>During the analysis of a configured target, the following pieces of data are available:
+ * <ul>
+ * <li>The corresponding target itself. This is necessary so that the analysis has access to e.g.
+ * the attributes a rule has in the BUILD file.</li>
+ * <li>The {@link com.google.devtools.build.lib.analysis.TransitiveInfoCollection}s of direct
+ * dependencies. They are used to gather information from the transitive closure, for example,
+ * the include path entries for C++ compilation or all the object files that need to be
+ * compiled into a C++ binary.</li>
+ * <li>The configuration, which is used to determine which compiler to use and to get access
+ * to some command line options of Bazel that influence analysis.</li>
+ * <li>Skyframe, for requesting arbitrary Skyframe nodes. This is an escape hatch that should be
+ * used when other mechanisms provided are not suitable and allows one to e.g. read arbitrary
+ * files. With great power...
+ * </ul>
+ *
+ * <p>Analysis of non-rule configured targets is special-cased and is not covered here.
+ *
+ * <p>The analysis of a rule itself is done by implementations {@link RuleConfiguredTargetFactory}
+ * (there should be one for each rule class). The data above is available using the
+ * {@link RuleContext} argument passed into its create() method. It should
+ * result in three things:
+ * <ul>
+ * <li>A set of actions. These should be passed to
+ * {@link RuleContext#registerAction(ActionAnalysisMetadata...)}, although for more
+ * common cases (e.g. {@link com.google.devtools.build.lib.analysis.actions.SpawnAction}),
+ * shortcuts are provided.</li>
+ * <li>A set of artifacts (files produced by actions). These should be created using methods of
+ * {@link RuleContext}. Each artifact thus created must have a generating action.</li>
+ * <li>A set of {@link com.google.devtools.build.lib.analysis.TransitiveInfoProvider}s that are
+ * passed on to direct dependencies. These must be registered using
+ * {@link com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder#add(
+ * Class, com.google.devtools.build.lib.analysis.TransitiveInfoProvider)}
+ * </li>
+ * </ul>
+ *
+ * <p>Configured targets are currently allowed to create artifacts at any exec path. It would be
+ * better if they could be constrained to a subtree based on the label of the configured target,
+ * but this is currently not feasible because multiple rules violate this constraint and the
+ * output format is part of its interface.
+ *
+ * <p>In principle, multiple configured targets should not create actions with conflicting
+ * outputs. There are still a few exceptions to this rule that are slated to be eventually
+ * removed, we have provisions to handle this case (Action instances that share at least one
+ * output file are required to be exactly the same), but this does put some pressure on the design
+ * and we are eventually planning to eliminate this option.
+ *
+ * <p>These restrictions together make it possible to:
+ * <ul>
+ * <li>Correctly cache the analysis phase; by tightly constraining what a configured target is
+ * allowed to access and what it is not, we can know when it needs to invalidate a particular
+ * one and when it can reuse an already existing one.
+ * <li>Serialize / deserialize individual configured targets at will, making it possible for
+ * example to swap out part of the analysis state if there is memory pressure or to move them in
+ * persistent storage so that the state can be reconstructed at a different time or in a
+ * different process. The stretch goal is to eventually facilitate cross-user caching of this
+ * information.
+ * </ul>
+ *
+ */
+public interface RuleConfiguredTargetFactory
+ extends RuleClass.ConfiguredTargetFactory<ConfiguredTarget, RuleContext> {
+}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index cc05d3b..f5c3e36 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -109,7 +109,7 @@
* are not persisted that check the name of this class, so update those tests if you change this
* class's name.
*
- * @see com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory
+ * @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory
*/
public final class RuleContext extends TargetContext
implements ActionConstructionContext, ActionRegistry, RuleErrorConsumer {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleDefinition.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleDefinition.java
index 2096b2b..1e27956 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleDefinition.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleDefinition.java
@@ -17,8 +17,6 @@
import com.google.auto.value.AutoValue;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
-import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
-
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java
index b3b4894..5cb79fd 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoCollection.java
@@ -27,14 +27,14 @@
*
* <p>Represents the information made available by a {@link ConfiguredTarget} to other ones that
* depend on it. For more information about the analysis phase, see {@link
- * com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory}.
+ * com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory}.
*
* <p>Implementations of build rules should <b>not</b> hold on to references to the {@link
* TransitiveInfoCollection}s representing their direct prerequisites in order to reduce their
* memory footprint (otherwise, the referenced object could refer one of its direct dependencies in
* turn, thereby making the size of the objects reachable from a single instance unbounded).
*
- * @see com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory
+ * @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory
* @see TransitiveInfoProvider
*/
@SkylarkModule(
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProvider.java
index f2b4919..32455e8 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/TransitiveInfoProvider.java
@@ -18,7 +18,7 @@
* Contains rolled-up data about the transitive closure of a configured target.
*
* For more information about how analysis works, see
- * {@link com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory}.
+ * {@link com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory}.
* TransitiveInfoProviders need to be serializable, and for that reason they must conform to
* the following restrictions:
*
@@ -57,7 +57,7 @@
* implementation of NestedSet you pick.
*
* @see TransitiveInfoCollection
- * @see com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory
+ * @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory
*/
public interface TransitiveInfoProvider {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/constraints/Environment.java b/src/main/java/com/google/devtools/build/lib/analysis/constraints/Environment.java
index dfdc7e4..4648d17 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/constraints/Environment.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/constraints/Environment.java
@@ -19,13 +19,13 @@
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
+import com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.packages.EnvironmentGroup;
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
import com.google.devtools.build.lib.packages.Target;
-import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory;
/**
* Implementation for the environment rule.