aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/analysis
diff options
context:
space:
mode:
authorGravatar juliexxia <juliexxia@google.com>2017-12-08 12:37:36 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2017-12-08 12:39:05 -0800
commit865b8887daca1477216ebe2527ad35f07081c778 (patch)
treede52e4a5e10438071730bddbfc5c9c57af19726d /src/main/java/com/google/devtools/build/lib/analysis
parent5f47d9a7e94011735bddc34b86bbd96633cbf464 (diff)
Add --implicit_deps custom filtering to configuredtargetqueryenvironment.
This implementation requires adding an interned list of LabelAndConfiguration objects to each RuleConfiguredTarget ('implicit' is an attribute describer, not a dep describer so filtering needs to happen while attribute information still exists). PiperOrigin-RevId: 178411882
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/analysis')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/Util.java53
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/RuleConfiguredTarget.java21
2 files changed, 73 insertions, 1 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/Util.java b/src/main/java/com/google/devtools/build/lib/analysis/Util.java
index e40c3ea5ac..aa12b40463 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/Util.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/Util.java
@@ -14,9 +14,17 @@
package com.google.devtools.build.lib.analysis;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Sets;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.collect.compacthashset.CompactHashSet;
+import com.google.devtools.build.lib.packages.AttributeMap;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.vfs.PathFragment;
+import java.util.List;
+import java.util.Set;
/**
* Utility methods for use by ConfiguredTarget implementations.
@@ -61,4 +69,49 @@ public abstract class Util {
public static boolean containsHyphen(PathFragment path) {
return path.getPathString().indexOf('-') >= 0;
}
+
+ // ---------- Implicit dependency extractor
+
+ /*
+ * Given a RuleContext, find all the implicit deps aka deps that weren't explicitly set in the
+ * build file and all toolchain deps.
+ * note: nodes that are depended on both implicitly and explicitly are considered explicit.
+ */
+ public static ImmutableSet<LabelAndConfiguration> findImplicitDeps(RuleContext ruleContext) {
+ // (1) Consider rule attribute dependencies.
+ Set<LabelAndConfiguration> maybeImplicitDeps = CompactHashSet.create();
+ Set<LabelAndConfiguration> explicitDeps = CompactHashSet.create();
+ AttributeMap attributes = ruleContext.attributes();
+ ListMultimap<String, ? extends TransitiveInfoCollection> targetMap =
+ ruleContext.getConfiguredTargetMap();
+ for (String attrName : attributes.getAttributeNames()) {
+ List<? extends TransitiveInfoCollection> attrValues = targetMap.get(attrName);
+ if (attrValues != null && !attrValues.isEmpty()) {
+ if (attributes.isAttributeValueExplicitlySpecified(attrName)) {
+ addLabelsAndConfigs(explicitDeps, attrValues);
+ } else {
+ addLabelsAndConfigs(maybeImplicitDeps, attrValues);
+ }
+ }
+ }
+ // (2) Consider toolchain dependencies
+ ToolchainContext toolchainContext = ruleContext.getToolchainContext();
+ if (toolchainContext != null) {
+ BuildConfiguration config = ruleContext.getConfiguration();
+ for (Label toolchain : toolchainContext.getResolvedToolchainLabels()) {
+ maybeImplicitDeps.add(LabelAndConfiguration.of(toolchain, config));
+ }
+ maybeImplicitDeps.add(
+ LabelAndConfiguration.of(toolchainContext.getExecutionPlatform().label(), config));
+ maybeImplicitDeps.add(
+ LabelAndConfiguration.of(toolchainContext.getTargetPlatform().label(), config));
+ }
+ return ImmutableSet.copyOf(Sets.difference(maybeImplicitDeps, explicitDeps));
+ }
+
+ private static void addLabelsAndConfigs(
+ Set<LabelAndConfiguration> set, List<? extends TransitiveInfoCollection> deps) {
+ deps.forEach(
+ target -> set.add(LabelAndConfiguration.of(target.getLabel(), target.getConfiguration())));
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/RuleConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/RuleConfiguredTarget.java
index 7a8a27e4b0..d95c4d31ac 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/RuleConfiguredTarget.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/RuleConfiguredTarget.java
@@ -15,19 +15,24 @@ package com.google.devtools.build.lib.analysis.configuredtargets;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Interner;
import com.google.devtools.build.lib.analysis.ConfiguredTarget;
import com.google.devtools.build.lib.analysis.FileProvider;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
+import com.google.devtools.build.lib.analysis.LabelAndConfiguration;
import com.google.devtools.build.lib.analysis.RuleConfiguredTargetBuilder;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.RunfilesProvider;
import com.google.devtools.build.lib.analysis.TransitiveInfoProvider;
import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMap;
import com.google.devtools.build.lib.analysis.TransitiveInfoProviderMapBuilder;
+import com.google.devtools.build.lib.analysis.Util;
import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider;
import com.google.devtools.build.lib.analysis.config.RunUnder;
import com.google.devtools.build.lib.analysis.skylark.SkylarkApiProvider;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.concurrent.BlazeInterners;
import com.google.devtools.build.lib.packages.ConfiguredAttributeMapper;
import com.google.devtools.build.lib.packages.Info;
import com.google.devtools.build.lib.packages.OutputFile;
@@ -57,6 +62,16 @@ public final class RuleConfiguredTarget extends AbstractConfiguredTarget {
SPLIT,
DONT_CHECK
}
+ /** A set of this target's implicitDeps. */
+ private final ImmutableSet<LabelAndConfiguration> implicitDeps;
+
+ /*
+ * An interner for the implicitDeps set. {@link Util.findImplicitDeps} is called upon every
+ * construction of a RuleConfiguredTarget and we expect many of these targets to contain the same
+ * set of implicit deps so this reduces the memory load per build.
+ */
+ private static final Interner<ImmutableSet<LabelAndConfiguration>> IMPLICIT_DEPS_INTERNER =
+ BlazeInterners.newWeakInterner();
private final TransitiveInfoProviderMap providers;
private final ImmutableMap<Label, ConfigMatchingProvider> configConditions;
@@ -79,9 +94,9 @@ public final class RuleConfiguredTarget extends AbstractConfiguredTarget {
}
}
-
this.providers = providerBuilder.build();
this.configConditions = ruleContext.getConfigConditions();
+ this.implicitDeps = IMPLICIT_DEPS_INTERNER.intern(Util.findImplicitDeps(ruleContext));
// If this rule is the run_under target, then check that we have an executable; note that
// run_under is only set in the target configuration, and the target must also be analyzed for
@@ -109,6 +124,10 @@ public final class RuleConfiguredTarget extends AbstractConfiguredTarget {
return configConditions;
}
+ public ImmutableSet<LabelAndConfiguration> getImplicitDeps() {
+ return implicitDeps;
+ }
+
@Nullable
@Override
public <P extends TransitiveInfoProvider> P getProvider(Class<P> providerClass) {