diff options
author | juliexxia <juliexxia@google.com> | 2017-12-08 12:37:36 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2017-12-08 12:39:05 -0800 |
commit | 865b8887daca1477216ebe2527ad35f07081c778 (patch) | |
tree | de52e4a5e10438071730bddbfc5c9c57af19726d /src/main/java/com/google/devtools/build/lib/analysis | |
parent | 5f47d9a7e94011735bddc34b86bbd96633cbf464 (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.java | 53 | ||||
-rw-r--r-- | src/main/java/com/google/devtools/build/lib/analysis/configuredtargets/RuleConfiguredTarget.java | 21 |
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) { |