diff options
Diffstat (limited to 'src/main/java')
6 files changed, 308 insertions, 154 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java index d205930765..0d39a8696d 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java @@ -38,11 +38,6 @@ import java.util.List; */ public class AndroidResourceMergingActionBuilder { - private static final ResourceContainerConverter.ToArtifacts RESOURCE_CONTAINER_TO_ARTIFACTS = - ResourceContainerConverter.builder() - .includeResourceRoots() - .includeSymbolsBin() - .toArtifactConverter(); private static final ResourceContainerConverter.ToArg RESOURCE_CONTAINER_TO_ARG = ResourceContainerConverter.builder() .includeResourceRoots() @@ -138,14 +133,18 @@ public class AndroidResourceMergingActionBuilder { Preconditions.checkNotNull(primary); builder.add("--primaryData", RESOURCE_CONTAINER_TO_ARG.apply(primary)); - inputs.addTransitive(RESOURCE_CONTAINER_TO_ARTIFACTS.apply(primary)); + inputs.addAll(primary.getArtifacts()); + inputs.add(primary.getSymbols()); Preconditions.checkNotNull(primary.getManifest()); builder.addExecPath("--primaryManifest", primary.getManifest()); inputs.add(primary.getManifest()); - ResourceContainerConverter.convertDependencies( - dependencies, builder, inputs, RESOURCE_CONTAINER_TO_ARG, RESOURCE_CONTAINER_TO_ARTIFACTS); + if (dependencies != null) { + ResourceContainerConverter.addToCommandLine(dependencies, builder, RESOURCE_CONTAINER_TO_ARG); + inputs.addTransitive(dependencies.getTransitiveResourceRoots()); + inputs.addTransitive(dependencies.getTransitiveSymbolsBin()); + } List<Artifact> outs = new ArrayList<>(); if (classJarOut != null) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java index 158a659e54..6fd04a2088 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java @@ -37,15 +37,6 @@ import java.util.List; */ public class AndroidResourcesProcessorBuilder { - private static final ResourceContainerConverter.ToArtifacts AAPT2_RESOURCE_DEP_TO_ARTIFACTS = - ResourceContainerConverter.builder() - .includeResourceRoots() - .includeManifest() - .includeAapt2RTxt() - .includeSymbolsBin() - .includeStaticLibrary() - .toArtifactConverter(); - private static final ResourceContainerConverter.ToArg AAPT2_RESOURCE_DEP_TO_ARG = ResourceContainerConverter.builder() .includeResourceRoots() @@ -56,20 +47,6 @@ public class AndroidResourcesProcessorBuilder { .withSeparator(SeparatorType.COLON_COMMA) .toArgConverter(); - private static final ResourceContainerConverter.ToArtifacts RESOURCE_CONTAINER_TO_ARTIFACTS = - ResourceContainerConverter.builder() - .includeResourceRoots() - .includeManifest() - .toArtifactConverter(); - - private static final ResourceContainerConverter.ToArtifacts RESOURCE_DEP_TO_ARTIFACTS = - ResourceContainerConverter.builder() - .includeResourceRoots() - .includeManifest() - .includeRTxt() - .includeSymbolsBin() - .toArtifactConverter(); - private static final ResourceContainerConverter.ToArg RESOURCE_CONTAINER_TO_ARG = ResourceContainerConverter.builder() .includeResourceRoots() @@ -289,8 +266,15 @@ public class AndroidResourcesProcessorBuilder { builder.add("--tool").add("AAPT2_PACKAGE").add("--"); builder.addExecPath("--aapt2", sdk.getAapt2().getExecutable()); - ResourceContainerConverter.convertDependencies( - dependencies, builder, inputs, AAPT2_RESOURCE_DEP_TO_ARG, AAPT2_RESOURCE_DEP_TO_ARTIFACTS); + if (dependencies != null) { + ResourceContainerConverter.addToCommandLine(dependencies, builder, AAPT2_RESOURCE_DEP_TO_ARG); + inputs + .addTransitive(dependencies.getTransitiveResourceRoots()) + .addTransitive(dependencies.getTransitiveManifests()) + .addTransitive(dependencies.getTransitiveAapt2RTxt()) + .addTransitive(dependencies.getTransitiveSymbolsBin()) + .addTransitive(dependencies.getTransitiveStaticLib()); + } configureCommonFlags(outs, inputs, builder); @@ -349,8 +333,14 @@ public class AndroidResourcesProcessorBuilder { // Set the busybox tool. builder.add("--tool").add("PACKAGE").add("--"); - ResourceContainerConverter.convertDependencies( - dependencies, builder, inputs, RESOURCE_DEP_TO_ARG, RESOURCE_DEP_TO_ARTIFACTS); + if (dependencies != null) { + ResourceContainerConverter.addToCommandLine(dependencies, builder, RESOURCE_DEP_TO_ARG); + inputs + .addTransitive(dependencies.getTransitiveResourceRoots()) + .addTransitive(dependencies.getTransitiveManifests()) + .addTransitive(dependencies.getTransitiveRTxt()) + .addTransitive(dependencies.getTransitiveSymbolsBin()); + } builder.addExecPath("--aapt", sdk.getAapt().getExecutable()); configureCommonFlags(outs, inputs, builder); @@ -404,7 +394,8 @@ public class AndroidResourcesProcessorBuilder { // Add data builder.add("--primaryData", RESOURCE_CONTAINER_TO_ARG.apply(primary)); - inputs.addTransitive(RESOURCE_CONTAINER_TO_ARTIFACTS.apply(primary)); + inputs.addAll(primary.getArtifacts()); + inputs.add(primary.getManifest()); if (!Strings.isNullOrEmpty(sdk.getBuildToolsVersion())) { builder.add("--buildToolsVersion", sdk.getBuildToolsVersion()); diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java index 2c1a217ab7..d152872aa7 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProvider.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.rules.android; import com.google.auto.value.AutoValue; +import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.nestedset.NestedSet; @@ -28,9 +29,24 @@ public abstract class AndroidResourcesProvider implements TransitiveInfoProvider Label label, NestedSet<ResourceContainer> transitiveAndroidResources, NestedSet<ResourceContainer> directAndroidResources, + NestedSet<Artifact> transitiveResourceRoots, + NestedSet<Artifact> transitiveManifests, + NestedSet<Artifact> transitiveAapt2RTxt, + NestedSet<Artifact> transitiveSymbolsBin, + NestedSet<Artifact> transitiveStaticLib, + NestedSet<Artifact> transitiveRTxt, boolean isResourcesOnly) { return new AutoValue_AndroidResourcesProvider( - label, transitiveAndroidResources, directAndroidResources, isResourcesOnly); + label, + transitiveAndroidResources, + directAndroidResources, + transitiveResourceRoots, + transitiveManifests, + transitiveAapt2RTxt, + transitiveSymbolsBin, + transitiveStaticLib, + transitiveRTxt, + isResourcesOnly); } /** Returns the label that is associated with this piece of information. */ @@ -42,6 +58,18 @@ public abstract class AndroidResourcesProvider implements TransitiveInfoProvider /** Returns the immediate ResourceContainers for the label. */ public abstract NestedSet<ResourceContainer> getDirectAndroidResources(); + public abstract NestedSet<Artifact> getTransitiveResourceRoots(); + + public abstract NestedSet<Artifact> getTransitiveManifests(); + + public abstract NestedSet<Artifact> getTransitiveAapt2RTxt(); + + public abstract NestedSet<Artifact> getTransitiveSymbolsBin(); + + public abstract NestedSet<Artifact> getTransitiveStaticLib(); + + public abstract NestedSet<Artifact> getTransitiveRTxt(); + /** * Returns whether the targets contained within this provider only represent android resources or * also contain other information. diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceContainerConverter.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceContainerConverter.java index 16a8c2845a..22037439d4 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceContainerConverter.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceContainerConverter.java @@ -18,17 +18,11 @@ import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.base.Joiner; import com.google.common.base.Preconditions; -import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; import com.google.common.collect.Iterators; -import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine; import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg; -import com.google.devtools.build.lib.collect.nestedset.NestedSet; -import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; -import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.rules.android.ResourceContainer.ResourceType; -import javax.annotation.Nullable; /** * Factory for functions to convert a {@link ResourceContainer} to a commandline argument, or a @@ -47,10 +41,6 @@ public class ResourceContainerConverter { String listSeparator(); } - interface ToArtifacts extends Function<ResourceContainer, NestedSet<Artifact>> { - - } - static class Builder { private boolean includeResourceRoots; @@ -183,41 +173,6 @@ public class ResourceContainerConverter { } }; } - - ToArtifacts toArtifactConverter() { - return new ToArtifacts() { - @Override - public NestedSet<Artifact> apply(ResourceContainer container) { - NestedSetBuilder<Artifact> artifacts = NestedSetBuilder.naiveLinkOrder(); - if (includeResourceRoots) { - artifacts.addAll(container.getArtifacts()); - } - if (includeManifest) { - addIfNotNull(container.getManifest(), artifacts); - } - if (includeRTxt) { - addIfNotNull(container.getRTxt(), artifacts); - } - if (includeSymbolsBin) { - addIfNotNull(container.getSymbols(), artifacts); - } - if (includeAapt2RTxt) { - addIfNotNull(container.getAapt2RTxt(), artifacts); - } - if (includeStaticLibrary) { - addIfNotNull(container.getStaticLibrary(), artifacts); - } - return artifacts.build(); - } - }; - } - } - - private static void addIfNotNull( - @Nullable Artifact artifact, NestedSetBuilder<Artifact> artifacts) { - if (artifact != null) { - artifacts.add(artifact); - } } @VisibleForTesting @@ -232,36 +187,17 @@ public class ResourceContainerConverter { * Convert ResourceDependencies to commandline args and artifacts, assuming the commandline * arguments should be split into direct deps and transitive deps. */ - static void convertDependencies( - ResourceDependencies dependencies, - CustomCommandLine.Builder cmdBuilder, - NestedSetBuilder<Artifact> inputs, - ToArg toArg, - ToArtifacts toArtifacts) { - - if (dependencies != null) { - if (!dependencies.getTransitiveResources().isEmpty()) { - cmdBuilder.addAll( - "--data", - VectorArg.join(toArg.listSeparator()) - .each(dependencies.getTransitiveResources()) - .mapped(toArg)); - } - if (!dependencies.getDirectResources().isEmpty()) { - cmdBuilder.addAll( - "--directData", - VectorArg.join(toArg.listSeparator()) - .each(dependencies.getDirectResources()) - .mapped(toArg)); - } - // This flattens the nested set. Since each ResourceContainer needs to be transformed into - // Artifacts, and the NestedSetBuilder.wrap doesn't support lazy Iterator evaluation - // and SpawnActionBuilder.addInputs evaluates Iterables, it becomes necessary to make the - // best effort and let it get flattened. - inputs.addTransitive( - NestedSetBuilder.wrap( - Order.NAIVE_LINK_ORDER, - FluentIterable.from(dependencies.getResources()).transformAndConcat(toArtifacts))); - } + static void addToCommandLine( + ResourceDependencies dependencies, CustomCommandLine.Builder cmdBuilder, ToArg toArg) { + cmdBuilder.addAll( + "--data", + VectorArg.join(toArg.listSeparator()) + .each(dependencies.getTransitiveResources()) + .mapped(toArg)); + cmdBuilder.addAll( + "--directData", + VectorArg.join(toArg.listSeparator()) + .each(dependencies.getDirectResources()) + .mapped(toArg)); } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java index 92d4eebdbb..a41319016c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceDependencies.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.rules.android; import com.google.common.collect.ImmutableList; +import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.cmdline.Label; @@ -47,9 +48,20 @@ public final class ResourceDependencies { * properly maintain ordering and ease of merging. */ private final NestedSet<ResourceContainer> directResources; - /** - * Whether the resources of the current rule should be treated as neverlink. - */ + + private final NestedSet<Artifact> transitiveResourceRoots; + + private final NestedSet<Artifact> transitiveManifests; + + private final NestedSet<Artifact> transitiveAapt2RTxt; + + private final NestedSet<Artifact> transitiveSymbolsBin; + + private final NestedSet<Artifact> transitiveStaticLib; + + private final NestedSet<Artifact> transitiveRTxt; + + /** Whether the resources of the current rule should be treated as neverlink. */ private final boolean neverlink; public static ResourceDependencies fromRuleResources(RuleContext ruleContext, boolean neverlink) { @@ -59,48 +71,143 @@ public final class ResourceDependencies { NestedSetBuilder<ResourceContainer> transitiveDependencies = NestedSetBuilder.naiveLinkOrder(); NestedSetBuilder<ResourceContainer> directDependencies = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveResourceRoots = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveManifests = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveAapt2RTxt = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveSymbolsBin = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveStaticLib = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveRTxt = NestedSetBuilder.naiveLinkOrder(); extractFromAttributes( - ImmutableList.of("resources"), ruleContext, transitiveDependencies, directDependencies); - return new ResourceDependencies(neverlink, - transitiveDependencies.build(), directDependencies.build()); + ImmutableList.of("resources"), + ruleContext, + transitiveDependencies, + directDependencies, + transitiveResourceRoots, + transitiveManifests, + transitiveAapt2RTxt, + transitiveSymbolsBin, + transitiveStaticLib, + transitiveRTxt); + return new ResourceDependencies( + neverlink, + transitiveDependencies.build(), + directDependencies.build(), + transitiveResourceRoots.build(), + transitiveManifests.build(), + transitiveAapt2RTxt.build(), + transitiveSymbolsBin.build(), + transitiveStaticLib.build(), + transitiveRTxt.build()); } public static ResourceDependencies fromRuleDeps(RuleContext ruleContext, boolean neverlink) { NestedSetBuilder<ResourceContainer> transitiveDependencies = NestedSetBuilder.naiveLinkOrder(); NestedSetBuilder<ResourceContainer> directDependencies = NestedSetBuilder.naiveLinkOrder(); - extractFromAttributes(AndroidCommon.TRANSITIVE_ATTRIBUTES, ruleContext, transitiveDependencies, - directDependencies); - return new ResourceDependencies(neverlink, - transitiveDependencies.build(), directDependencies.build()); + NestedSetBuilder<Artifact> transitiveResourceRoots = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveManifests = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveAapt2RTxt = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveSymbolsBin = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveStaticLib = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveRTxt = NestedSetBuilder.naiveLinkOrder(); + extractFromAttributes( + AndroidCommon.TRANSITIVE_ATTRIBUTES, + ruleContext, + transitiveDependencies, + directDependencies, + transitiveResourceRoots, + transitiveManifests, + transitiveAapt2RTxt, + transitiveSymbolsBin, + transitiveStaticLib, + transitiveRTxt); + return new ResourceDependencies( + neverlink, + transitiveDependencies.build(), + directDependencies.build(), + transitiveResourceRoots.build(), + transitiveManifests.build(), + transitiveAapt2RTxt.build(), + transitiveSymbolsBin.build(), + transitiveStaticLib.build(), + transitiveRTxt.build()); } public static ResourceDependencies fromRuleResourceAndDeps(RuleContext ruleContext, boolean neverlink) { NestedSetBuilder<ResourceContainer> transitiveDependencies = NestedSetBuilder.naiveLinkOrder(); NestedSetBuilder<ResourceContainer> directDependencies = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveResourceRoots = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveManifests = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveAapt2RTxt = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveSymbolsBin = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveStaticLib = NestedSetBuilder.naiveLinkOrder(); + NestedSetBuilder<Artifact> transitiveRTxt = NestedSetBuilder.naiveLinkOrder(); if (hasResourceAttribute(ruleContext)) { extractFromAttributes( - ImmutableList.of("resources"), ruleContext, transitiveDependencies, directDependencies); + ImmutableList.of("resources"), + ruleContext, + transitiveDependencies, + directDependencies, + transitiveResourceRoots, + transitiveManifests, + transitiveAapt2RTxt, + transitiveSymbolsBin, + transitiveStaticLib, + transitiveRTxt); } if (directDependencies.isEmpty()) { // There are no resources, so this library will forward the direct and transitive dependencies // without changes. - extractFromAttributes(AndroidCommon.TRANSITIVE_ATTRIBUTES, ruleContext, - transitiveDependencies, directDependencies); + extractFromAttributes( + AndroidCommon.TRANSITIVE_ATTRIBUTES, + ruleContext, + transitiveDependencies, + directDependencies, + transitiveResourceRoots, + transitiveManifests, + transitiveAapt2RTxt, + transitiveSymbolsBin, + transitiveStaticLib, + transitiveRTxt); } else { // There are resources, so the direct dependencies and the transitive will be merged into // the transitive dependencies. This maintains the relationship of the resources being // directly on the rule. - extractFromAttributes(AndroidCommon.TRANSITIVE_ATTRIBUTES, ruleContext, - transitiveDependencies, transitiveDependencies); + extractFromAttributes( + AndroidCommon.TRANSITIVE_ATTRIBUTES, + ruleContext, + transitiveDependencies, + transitiveDependencies, + transitiveResourceRoots, + transitiveManifests, + transitiveAapt2RTxt, + transitiveSymbolsBin, + transitiveStaticLib, + transitiveRTxt); } - return new ResourceDependencies(neverlink, - transitiveDependencies.build(), directDependencies.build()); + return new ResourceDependencies( + neverlink, + transitiveDependencies.build(), + directDependencies.build(), + transitiveResourceRoots.build(), + transitiveManifests.build(), + transitiveAapt2RTxt.build(), + transitiveSymbolsBin.build(), + transitiveStaticLib.build(), + transitiveRTxt.build()); } - private static void extractFromAttributes(Iterable<String> attributeNames, - RuleContext ruleContext, NestedSetBuilder<ResourceContainer> builderForTransitive, - NestedSetBuilder<ResourceContainer> builderForDirect) { + private static void extractFromAttributes( + Iterable<String> attributeNames, + RuleContext ruleContext, + NestedSetBuilder<ResourceContainer> builderForTransitive, + NestedSetBuilder<ResourceContainer> builderForDirect, + NestedSetBuilder<Artifact> transitiveResourceRoots, + NestedSetBuilder<Artifact> transitiveManifests, + NestedSetBuilder<Artifact> transitiveAapt2RTxt, + NestedSetBuilder<Artifact> transitiveSymbolsBin, + NestedSetBuilder<Artifact> transitiveStaticLib, + NestedSetBuilder<Artifact> transitiveRTxt) { AttributeMap attributes = ruleContext.attributes(); for (String attr : attributeNames) { if (!attributes.has(attr, BuildType.LABEL_LIST) && !attributes.has(attr, BuildType.LABEL)) { @@ -110,6 +217,12 @@ public final class ResourceDependencies { ruleContext.getPrerequisites(attr, Mode.TARGET, AndroidResourcesProvider.class)) { builderForTransitive.addTransitive(resources.getTransitiveAndroidResources()); builderForDirect.addTransitive(resources.getDirectAndroidResources()); + transitiveResourceRoots.addTransitive(resources.getTransitiveResourceRoots()); + transitiveManifests.addTransitive(resources.getTransitiveManifests()); + transitiveAapt2RTxt.addTransitive(resources.getTransitiveAapt2RTxt()); + transitiveSymbolsBin.addTransitive(resources.getTransitiveSymbolsBin()); + transitiveStaticLib.addTransitive(resources.getTransitiveStaticLib()); + transitiveRTxt.addTransitive(resources.getTransitiveRTxt()); } } } @@ -138,26 +251,54 @@ public final class ResourceDependencies { * is the only resource dependency. The most common case is the AndroidTest rule. */ public static ResourceDependencies empty() { - return new ResourceDependencies(false, - NestedSetBuilder.<ResourceContainer>emptySet(Order.NAIVE_LINK_ORDER), - NestedSetBuilder.<ResourceContainer>emptySet(Order.NAIVE_LINK_ORDER)); + return new ResourceDependencies( + false, + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER), + NestedSetBuilder.emptySet(Order.NAIVE_LINK_ORDER)); } private ResourceDependencies( boolean neverlink, NestedSet<ResourceContainer> transitiveResources, - NestedSet<ResourceContainer> directResources) { + NestedSet<ResourceContainer> directResources, + NestedSet<Artifact> transitiveResourceRoots, + NestedSet<Artifact> transitiveManifests, + NestedSet<Artifact> transitiveAapt2RTxt, + NestedSet<Artifact> transitiveSymbolsBin, + NestedSet<Artifact> transitiveStaticLib, + NestedSet<Artifact> transitiveRTxt) { this.neverlink = neverlink; this.transitiveResources = transitiveResources; this.directResources = directResources; + this.transitiveResourceRoots = transitiveResourceRoots; + this.transitiveManifests = transitiveManifests; + this.transitiveAapt2RTxt = transitiveAapt2RTxt; + this.transitiveSymbolsBin = transitiveSymbolsBin; + this.transitiveStaticLib = transitiveStaticLib; + this.transitiveRTxt = transitiveRTxt; } /** Returns a copy of this instance with filtered resources. The original object is unchanged. */ public ResourceDependencies filter(RuleContext ruleContext, ResourceFilter filter) { + // Note that this doesn't filter any of the dependent artifacts. This + // means that if any resource changes, the corresponding actions will get + // re-executed return new ResourceDependencies( neverlink, filter.filterDependencies(ruleContext, transitiveResources), - filter.filterDependencies(ruleContext, directResources)); + filter.filterDependencies(ruleContext, directResources), + transitiveResourceRoots, + transitiveManifests, + transitiveAapt2RTxt, + transitiveSymbolsBin, + transitiveStaticLib, + transitiveRTxt); } /** @@ -180,6 +321,34 @@ public final class ResourceDependencies { if (neverlink) { return ResourceDependencies.empty().toProvider(label, isResourcesOnly); } + NestedSetBuilder<Artifact> transitiveResourceRoots = NestedSetBuilder.naiveLinkOrder(); + transitiveResourceRoots.addTransitive(this.transitiveResourceRoots); + transitiveResourceRoots.addAll(newDirectResource.getArtifacts()); + NestedSetBuilder<Artifact> transitiveManifests = NestedSetBuilder.naiveLinkOrder(); + transitiveManifests.addTransitive(this.transitiveManifests); + if (newDirectResource.getManifest() != null) { + transitiveManifests.add(newDirectResource.getManifest()); + } + NestedSetBuilder<Artifact> transitiveAapt2RTxt = NestedSetBuilder.naiveLinkOrder(); + transitiveAapt2RTxt.addTransitive(this.transitiveAapt2RTxt); + if (newDirectResource.getAapt2RTxt() != null) { + transitiveAapt2RTxt.add(newDirectResource.getAapt2RTxt()); + } + NestedSetBuilder<Artifact> transitiveSymbolsBin = NestedSetBuilder.naiveLinkOrder(); + transitiveSymbolsBin.addTransitive(this.transitiveSymbolsBin); + if (newDirectResource.getSymbols() != null) { + transitiveSymbolsBin.add(newDirectResource.getSymbols()); + } + NestedSetBuilder<Artifact> transitiveStaticLib = NestedSetBuilder.naiveLinkOrder(); + transitiveStaticLib.addTransitive(this.transitiveStaticLib); + if (newDirectResource.getStaticLibrary() != null) { + transitiveStaticLib.add(newDirectResource.getStaticLibrary()); + } + NestedSetBuilder<Artifact> transitiveRTxt = NestedSetBuilder.naiveLinkOrder(); + transitiveRTxt.addTransitive(this.transitiveRTxt); + if (newDirectResource.getRTxt() != null) { + transitiveRTxt.add(newDirectResource.getRTxt()); + } return AndroidResourcesProvider.create( label, NestedSetBuilder.<ResourceContainer>naiveLinkOrder() @@ -187,6 +356,12 @@ public final class ResourceDependencies { .addTransitive(directResources) .build(), NestedSetBuilder.<ResourceContainer>naiveLinkOrder().add(newDirectResource).build(), + transitiveResourceRoots.build(), + transitiveManifests.build(), + transitiveAapt2RTxt.build(), + transitiveSymbolsBin.build(), + transitiveStaticLib.build(), + transitiveRTxt.build(), isResourcesOnly); } @@ -208,7 +383,16 @@ public final class ResourceDependencies { return ResourceDependencies.empty().toProvider(label, isResourcesOnly); } return AndroidResourcesProvider.create( - label, transitiveResources, directResources, isResourcesOnly); + label, + transitiveResources, + directResources, + transitiveResourceRoots, + transitiveManifests, + transitiveAapt2RTxt, + transitiveSymbolsBin, + transitiveStaticLib, + transitiveRTxt, + isResourcesOnly); } /** Provides an NestedSet of the direct and transitive resources. */ @@ -226,4 +410,28 @@ public final class ResourceDependencies { public NestedSet<ResourceContainer> getDirectResources() { return directResources; } + + public NestedSet<Artifact> getTransitiveResourceRoots() { + return transitiveResourceRoots; + } + + public NestedSet<Artifact> getTransitiveManifests() { + return transitiveManifests; + } + + public NestedSet<Artifact> getTransitiveAapt2RTxt() { + return transitiveAapt2RTxt; + } + + public NestedSet<Artifact> getTransitiveSymbolsBin() { + return transitiveSymbolsBin; + } + + public NestedSet<Artifact> getTransitiveStaticLib() { + return transitiveStaticLib; + } + + public NestedSet<Artifact> getTransitiveRTxt() { + return transitiveRTxt; + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java index 64b99d3d66..e752d82108 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java @@ -13,7 +13,6 @@ // limitations under the License. package com.google.devtools.build.lib.rules.android; -import com.google.common.collect.FluentIterable; import com.google.common.collect.Iterables; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType; @@ -26,8 +25,6 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.rules.android.ResourceContainerConverter.Builder.SeparatorType; import com.google.devtools.build.lib.util.OS; -import java.util.ArrayList; -import java.util.List; /** * Builder for generating R classes for robolectric action. @@ -37,13 +34,6 @@ import java.util.List; */ public class RobolectricResourceSymbolsActionBuilder { - private static final ResourceContainerConverter.ToArtifacts RESOURCE_CONTAINER_TO_ARTIFACTS = - ResourceContainerConverter.builder() - .includeResourceRoots() - .includeManifest() - .includeRTxt() - .includeSymbolsBin() - .toArtifactConverter(); private static final ResourceContainerConverter.ToArg RESOURCE_CONTAINER_TO_ARG = ResourceContainerConverter.builder() .includeResourceRoots() @@ -80,7 +70,7 @@ public class RobolectricResourceSymbolsActionBuilder { // Set the busybox tool. builder.add("--tool").add("GENERATE_ROBOLECTRIC_R").add("--"); - List<Artifact> inputs = new ArrayList<>(); + NestedSetBuilder<Artifact> inputs = NestedSetBuilder.stableOrder(); builder.addExecPath("--androidJar", sdk.getAndroidJar()); inputs.add(sdk.getAndroidJar()); @@ -93,9 +83,11 @@ public class RobolectricResourceSymbolsActionBuilder { .mapped(RESOURCE_CONTAINER_TO_ARG)); } - // This flattens the nested set. - Iterables.addAll(inputs, FluentIterable.from(dependencies.getResources()) - .transformAndConcat(RESOURCE_CONTAINER_TO_ARTIFACTS)); + inputs + .addTransitive(dependencies.getTransitiveResourceRoots()) + .addTransitive(dependencies.getTransitiveManifests()) + .addTransitive(dependencies.getTransitiveRTxt()) + .addTransitive(dependencies.getTransitiveSymbolsBin()); builder.addExecPath("--classJarOutput", classJarOut); SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder(); @@ -117,7 +109,7 @@ public class RobolectricResourceSymbolsActionBuilder { ruleContext.registerAction( spawnActionBuilder .useDefaultShellEnvironment() - .addInputs(inputs) + .addTransitiveInputs(inputs.build()) .addOutput(classJarOut) .setCommandLine(builder.build()) .setExecutable( |