aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java
diff options
context:
space:
mode:
authorGravatar asteinb <asteinb@google.com>2018-05-25 11:16:34 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-05-25 11:17:48 -0700
commitc2cf1132a75d03cc37888fe8c2b9583c7ce198c5 (patch)
tree77d981b934797bb9e335cabf1c9c496023bb74e9 /src/main/java
parent2643d4b7543403eae52c038e769231f539938195 (diff)
Automated rollback of commit 372fbc2f016157b0331f83a20edad10d4b4cf9f7.
*** Reason for rollback *** Roll forward with fix: I was assuming that R.txt and symbols files are always set, but they can be null in some cases (especially in the old data processing pipeline). Properly handle them here. RELNOTES: none PiperOrigin-RevId: 198075743
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidDataConverter.java41
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java1
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java229
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java137
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java197
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java455
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java49
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/BusyBoxActionBuilder.java18
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidAssets.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java7
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java15
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/RClassGeneratorActionBuilder.java103
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java4
20 files changed, 398 insertions, 882 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java
index ed24747882..1e9f5c58d7 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AarImport.java
@@ -100,8 +100,7 @@ public class AarImport implements RuleConfiguredTargetFactory {
final AndroidDataContext dataContext = androidSemantics.makeContextForNative(ruleContext);
final ResourceApk resourceApk;
if (AndroidResources.decoupleDataProcessing(dataContext)) {
- StampedAndroidManifest manifest =
- AndroidManifest.forAarImport(androidManifestArtifact);
+ StampedAndroidManifest manifest = AndroidManifest.forAarImport(androidManifestArtifact);
boolean neverlink = JavaCommon.isNeverLink(ruleContext);
ValidatedAndroidResources validatedResources =
@@ -122,6 +121,7 @@ public class AarImport implements RuleConfiguredTargetFactory {
resourceApk =
androidManifest.packAarWithDataAndResources(
ruleContext,
+ dataContext,
AndroidAssets.forAarImport(assets),
AndroidResources.forAarImport(resources),
ResourceDependencies.fromRuleDeps(ruleContext, JavaCommon.isNeverLink(ruleContext)),
@@ -168,8 +168,6 @@ public class AarImport implements RuleConfiguredTargetFactory {
.addCompileTimeJarAsFullJar(mergedJar)
.build());
-
-
JavaConfiguration javaConfig = ruleContext.getFragment(JavaConfiguration.class);
// TODO(cnsun): need to pass the transitive classpath too to emit add dep command.
NestedSet<Artifact> directDeps = getCompileTimeJarsFromCollection(targets, /*isStrict=*/ true);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
index 0bc24677dd..96d4fb3e71 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java
@@ -261,6 +261,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
resourceApk =
applicationManifest.packBinaryWithDataAndResources(
ruleContext,
+ dataContext,
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_APK),
resourceDeps,
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java
index 0c8d4cf7cb..b344411ba8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinaryMobileInstall.java
@@ -101,6 +101,7 @@ public final class AndroidBinaryMobileInstall {
.addMobileInstallStubApplication(ruleContext)
.packIncrementalBinaryWithDataAndResources(
ruleContext,
+ dataContext,
ruleContext.getImplicitOutputArtifact(
AndroidRuleClasses.ANDROID_INCREMENTAL_RESOURCES_APK),
resourceDeps,
@@ -114,6 +115,7 @@ public final class AndroidBinaryMobileInstall {
.createSplitManifest(ruleContext, "android_resources", false)
.packIncrementalBinaryWithDataAndResources(
ruleContext,
+ dataContext,
getMobileInstallArtifact(ruleContext, "android_resources.ap_"),
resourceDeps,
ruleContext.getExpander().withDataLocations().tokenized("nocompress_extensions"),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDataConverter.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDataConverter.java
index 5aaf6cad99..28d242c033 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDataConverter.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidDataConverter.java
@@ -16,7 +16,6 @@ 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.actions.CommandLineItem.ParametrizedMapFn;
-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.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
@@ -26,6 +25,7 @@ import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;
+import javax.annotation.Nullable;
/**
* Factory for functions to convert a {@code T} to a commandline argument. Uses a certain convention
@@ -42,7 +42,7 @@ public class AndroidDataConverter<T> extends ParametrizedMapFn<T> {
.withRoots(MergableAndroidData::getResourceRoots)
.withRoots(MergableAndroidData::getAssetRoots)
.withLabel(MergableAndroidData::getLabel)
- .withArtifact(MergableAndroidData::getSymbols)
+ .maybeWithArtifact(MergableAndroidData::getSymbols)
.build();
/** Indicates the type of joiner between options expected by the command line. */
@@ -119,14 +119,6 @@ public class AndroidDataConverter<T> extends ParametrizedMapFn<T> {
return new Builder<>(joinerType);
}
- public void addDepsToCommandLine(
- CustomCommandLine.Builder cmdBuilder,
- NestedSet<? extends T> direct,
- NestedSet<? extends T> transitive) {
- cmdBuilder.addAll("--data", getVectorArg(transitive));
- cmdBuilder.addAll("--directData", getVectorArg(direct));
- }
-
public VectorArg<String> getVectorArg(NestedSet<? extends T> values) {
return VectorArg.join(joinerType.listSeparator).each(values).mapped(this);
}
@@ -145,31 +137,24 @@ public class AndroidDataConverter<T> extends ParametrizedMapFn<T> {
}
Builder<T> withRoots(Function<T, ImmutableList<PathFragment>> rootsFunction) {
- return with(new Function<T, String>() {
- @Override
- public String apply(T t) {
- return rootsToString(rootsFunction.apply(t));
- }
- });
+ return with(t -> rootsToString(rootsFunction.apply(t)));
}
Builder<T> withArtifact(Function<T, Artifact> artifactFunction) {
- return with(new Function<T, String>() {
- @Override
- public String apply(T t) {
- return artifactFunction.apply(t).getExecPathString();
- }
- });
+ return with(t -> artifactFunction.apply(t).getExecPathString());
+ }
+
+ Builder<T> maybeWithArtifact(Function<T, Artifact> nullableArtifactFunction) {
+ return with(
+ t -> {
+ @Nullable Artifact artifact = nullableArtifactFunction.apply(t);
+ return artifact == null ? "" : artifact.getExecPathString();
+ });
}
Builder<T> withLabel(Function<T, Label> labelFunction) {
// Escape labels, since they are known to contain separating characters (specifically, ':').
- return with(new Function<T, String>() {
- @Override
- public String apply(T t) {
- return joinerType.escape(labelFunction.apply(t).toString());
- }
- });
+ return with(t -> joinerType.escape(labelFunction.apply(t).toString()));
}
Builder<T> with(Function<T, String> stringFunction) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
index 67dbd5a85e..f4ed5d53eb 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLibrary.java
@@ -169,6 +169,7 @@ public abstract class AndroidLibrary implements RuleConfiguredTargetFactory {
resourceApk =
applicationManifest.packLibraryWithDataAndResources(
ruleContext,
+ dataContext,
resourceDeps,
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT),
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_MERGED_SYMBOLS),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
index e32d12c1b2..2dccf13cb6 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidLocalTestBase.java
@@ -117,6 +117,7 @@ public abstract class AndroidLocalTestBase implements RuleConfiguredTargetFactor
resourceApk =
applicationManifest.packBinaryWithDataAndResources(
ruleContext,
+ dataContext,
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_APK),
resourceDependencies,
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java
index be6c9baf15..4d99f6d6d7 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidManifestMergeHelper.java
@@ -71,4 +71,4 @@ public final class AndroidManifestMergeHelper {
.addCommandLine(commandLine.build())
.build(context));
}
-} \ No newline at end of file
+}
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 1d5256374b..9d945e2104 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
@@ -14,21 +14,10 @@
package com.google.devtools.build.lib.rules.android;
import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.ParamFileInfo;
-import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
-import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
-import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
-import com.google.devtools.build.lib.analysis.actions.SpawnAction;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
-import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.android.AndroidDataConverter.JoinerType;
-import com.google.devtools.build.lib.util.OS;
-import java.util.ArrayList;
-import java.util.List;
import javax.annotation.Nullable;
/**
@@ -52,9 +41,6 @@ public class AndroidResourceMergingActionBuilder {
.withArtifact(CompiledMergableAndroidData::getCompiledSymbols)
.build();
- private final RuleContext ruleContext;
- private final AndroidSdkProvider sdk;
-
// Inputs
private CompiledMergableAndroidData primary;
private ResourceDependencies dependencies;
@@ -70,12 +56,6 @@ public class AndroidResourceMergingActionBuilder {
private boolean throwOnResourceConflict;
private boolean useCompiledMerge;
- /** @param ruleContext The RuleContext that was used to create the SpawnAction.Builder. */
- public AndroidResourceMergingActionBuilder(RuleContext ruleContext) {
- this.ruleContext = ruleContext;
- this.sdk = AndroidSdkProvider.fromRuleContext(ruleContext);
- }
-
/**
* The primary resource for merging. This resource will overwrite any resource or data value in
* the transitive closure.
@@ -132,172 +112,102 @@ public class AndroidResourceMergingActionBuilder {
return this;
}
- private NestedSetBuilder<Artifact> createInputsForBuilder(CustomCommandLine.Builder builder) {
- // Use a FluentIterable to avoid flattening the NestedSets
- NestedSetBuilder<Artifact> inputs = NestedSetBuilder.naiveLinkOrder();
-
- builder.addExecPath("--androidJar", sdk.getAndroidJar());
- inputs.add(sdk.getAndroidJar());
-
- Preconditions.checkNotNull(primary.getManifest());
- builder.addExecPath("--primaryManifest", primary.getManifest());
- inputs.add(primary.getManifest());
-
- if (!Strings.isNullOrEmpty(customJavaPackage)) {
- // Sets an alternative java package for the generated R.java
- // this allows android rules to generate resources outside of the java{,tests} tree.
- builder.add("--packageForR", customJavaPackage);
- }
-
- if (throwOnResourceConflict) {
- builder.add("--throwOnResourceConflict");
- }
-
- return inputs;
+ private BusyBoxActionBuilder createInputsForBuilder(BusyBoxActionBuilder builder) {
+ return builder
+ .addAndroidJar()
+ .addInput("--primaryManifest", primary.getManifest())
+ .maybeAddFlag("--packageForR", customJavaPackage)
+ .maybeAddFlag("--throwOnResourceConflict", throwOnResourceConflict);
}
- private void buildCompiledResourceMergingAction(
- CustomCommandLine.Builder builder,
- List<Artifact> outputs,
- ActionConstructionContext context) {
- NestedSetBuilder<Artifact> inputs = createInputsForBuilder(builder);
-
+ private void buildCompiledResourceMergingAction(BusyBoxActionBuilder builder) {
Preconditions.checkNotNull(primary);
- builder.add("--primaryData", RESOURCE_CONTAINER_TO_ARG_FOR_COMPILED.map(primary));
- inputs.addAll(primary.getArtifacts());
- inputs.add(primary.getCompiledSymbols());
+
+ createInputsForBuilder(builder)
+ .addInput(
+ "--primaryData",
+ RESOURCE_CONTAINER_TO_ARG_FOR_COMPILED.map(primary),
+ Iterables.concat(
+ primary.getArtifacts(), ImmutableList.of(primary.getCompiledSymbols())));
if (dependencies != null) {
- RESOURCE_CONTAINER_TO_ARG_FOR_COMPILED.addDepsToCommandLine(
- builder,
- dependencies.getDirectResourceContainers(),
- dependencies.getTransitiveResourceContainers());
- inputs.addTransitive(dependencies.getTransitiveResources());
- inputs.addTransitive(dependencies.getTransitiveAssets());
- inputs.addTransitive(dependencies.getTransitiveCompiledSymbols());
+ builder
+ .addTransitiveFlag(
+ "--data",
+ dependencies.getTransitiveResourceContainers(),
+ RESOURCE_CONTAINER_TO_ARG_FOR_COMPILED)
+ .addTransitiveFlag(
+ "--directData",
+ dependencies.getDirectResourceContainers(),
+ RESOURCE_CONTAINER_TO_ARG_FOR_COMPILED)
+ .addTransitiveInputValues(dependencies.getTransitiveResources())
+ .addTransitiveInputValues(dependencies.getTransitiveAssets())
+ .addTransitiveInputValues(dependencies.getTransitiveCompiledSymbols());
}
- SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder();
- ParamFileInfo.Builder compiledParamFileInfo = ParamFileInfo.builder(ParameterFileType.UNQUOTED);
- compiledParamFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS);
- // Create the spawn action.
- ruleContext.registerAction(
- spawnActionBuilder
- .useDefaultShellEnvironment()
- .addTransitiveInputs(inputs.build())
- .addOutputs(ImmutableList.copyOf(outputs))
- .addCommandLine(builder.build(), compiledParamFileInfo.build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage("Merging compiled Android resources for %s", ruleContext.getLabel())
- .setMnemonic("AndroidCompiledResourceMerger")
- .build(context));
+ builder.buildAndRegister("Merging compiled Android resources", "AndroidCompiledResourceMerger");
}
- private void buildParsedResourceMergingAction(
- CustomCommandLine.Builder builder,
- List<Artifact> outputs,
- ActionConstructionContext context) {
- NestedSetBuilder<Artifact> inputs = createInputsForBuilder(builder);
-
+ private void buildParsedResourceMergingAction(BusyBoxActionBuilder builder) {
Preconditions.checkNotNull(primary);
- builder.add("--primaryData", RESOURCE_CONTAINER_TO_ARG.map(primary));
- inputs.addAll(primary.getArtifacts());
- inputs.add(primary.getSymbols());
+
+ createInputsForBuilder(builder)
+ .addInput(
+ "--primaryData",
+ RESOURCE_CONTAINER_TO_ARG.map(primary),
+ Iterables.concat(primary.getArtifacts(), ImmutableList.of(primary.getSymbols())));
if (dependencies != null) {
- RESOURCE_CONTAINER_TO_ARG.addDepsToCommandLine(
- builder,
- dependencies.getDirectResourceContainers(),
- dependencies.getTransitiveResourceContainers());
- inputs.addTransitive(dependencies.getTransitiveResources());
- inputs.addTransitive(dependencies.getTransitiveAssets());
- inputs.addTransitive(dependencies.getTransitiveSymbolsBin());
+ builder
+ .addTransitiveFlag(
+ "--data", dependencies.getTransitiveResourceContainers(), RESOURCE_CONTAINER_TO_ARG)
+ .addTransitiveFlag(
+ "--directData", dependencies.getDirectResourceContainers(), RESOURCE_CONTAINER_TO_ARG)
+ .addTransitiveInputValues(dependencies.getTransitiveResources())
+ .addTransitiveInputValues(dependencies.getTransitiveAssets())
+ .addTransitiveInputValues(dependencies.getTransitiveSymbolsBin());
}
- SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder();
- ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED);
- // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special
- // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting
- // semantics are very complicated (more so than in Bash), so let's just always use a parameter
- // file.
- // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating
- // list-type and list-of-list-type flags that use such problematic separators in favor of
- // multi-value flags (to remove one level of listing) and by changing all list separators to a
- // platform-safe character (= comma).
- paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS);
-
- // Create the spawn action.
- ruleContext.registerAction(
- spawnActionBuilder
- .useDefaultShellEnvironment()
- .addTransitiveInputs(inputs.build())
- .addOutputs(ImmutableList.copyOf(outputs))
- .addCommandLine(builder.build(), paramFileInfo.build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage("Merging Android resources for %s", ruleContext.getLabel())
- .setMnemonic("AndroidResourceMerger")
- .build(context));
+ builder.buildAndRegister("Merging Android resources", "AndroidResourceMerger");
}
- private void build(RuleContext context) {
- CustomCommandLine.Builder parsedMergeBuilder =
- new CustomCommandLine.Builder().add("--tool").add("MERGE").add("--");
- CustomCommandLine.Builder compiledMergeBuilder =
- new CustomCommandLine.Builder().add("--tool").add("MERGE_COMPILED").add("--");
- List<Artifact> parsedMergeOutputs = new ArrayList<>();
- List<Artifact> compiledMergeOutputs = new ArrayList<>();
+ private void build(AndroidDataContext dataContext) {
+ BusyBoxActionBuilder parsedMergeBuilder = BusyBoxActionBuilder.create(dataContext, "MERGE");
+ BusyBoxActionBuilder compiledMergeBuilder =
+ BusyBoxActionBuilder.create(dataContext, "MERGE_COMPILED");
- if (mergedResourcesOut != null) {
- parsedMergeBuilder.addExecPath("--resourcesOutput", mergedResourcesOut);
- parsedMergeOutputs.add(mergedResourcesOut);
- }
+ parsedMergeBuilder.addOutput("--resourcesOutput", mergedResourcesOut);
// TODO(corysmith): Move the data binding parsing out of the merging pass to enable faster
// aapt2 builds.
- if (dataBindingInfoZip != null) {
- parsedMergeBuilder.addExecPath("--dataBindingInfoOut", dataBindingInfoZip);
- parsedMergeOutputs.add(dataBindingInfoZip);
- }
-
- CustomCommandLine.Builder jarAndManifestBuilder =
- useCompiledMerge ? compiledMergeBuilder : parsedMergeBuilder;
- List<Artifact> jarAndManifestOutputs =
- useCompiledMerge ? compiledMergeOutputs : parsedMergeOutputs;
+ parsedMergeBuilder.maybeAddOutput("--dataBindingInfoOut", dataBindingInfoZip);
- if (classJarOut != null) {
- jarAndManifestBuilder.addExecPath("--classJarOutput", classJarOut);
- jarAndManifestBuilder.addLabel("--targetLabel", ruleContext.getLabel());
- jarAndManifestOutputs.add(classJarOut);
- }
+ (useCompiledMerge ? compiledMergeBuilder : parsedMergeBuilder)
+ .addOutput("--classJarOutput", classJarOut)
+ .addLabelFlag("--targetLabel")
- // For now, do manifest processing to remove placeholders that aren't handled by the legacy
- // manifest merger. Remove this once enough users migrate over to the new manifest merger.
- if (manifestOut != null) {
- jarAndManifestBuilder.addExecPath("--manifestOutput", manifestOut);
- jarAndManifestOutputs.add(manifestOut);
- }
+ // For now, do manifest processing to remove placeholders that aren't handled by the legacy
+ // manifest merger. Remove this once enough users migrate over to the new manifest merger.
+ .maybeAddOutput("--manifestOutput", manifestOut);
- if (!compiledMergeOutputs.isEmpty()) {
- buildCompiledResourceMergingAction(compiledMergeBuilder, compiledMergeOutputs, context);
+ if (useCompiledMerge) {
+ buildCompiledResourceMergingAction(compiledMergeBuilder);
}
- if (!parsedMergeOutputs.isEmpty()) {
- buildParsedResourceMergingAction(parsedMergeBuilder, parsedMergeOutputs, context);
- }
+ // Always make an action for merging parsed resources - the merged resources are still created
+ // this way.
+ buildParsedResourceMergingAction(parsedMergeBuilder);
}
- public ResourceContainer build(RuleContext ruleContext, ResourceContainer resourceContainer) {
- withPrimary(resourceContainer).build(ruleContext);
+ public ResourceContainer build(
+ AndroidDataContext dataContext, ResourceContainer resourceContainer) {
+ withPrimary(resourceContainer).build(dataContext);
// Return the full set of processed transitive dependencies.
ResourceContainer.Builder result = resourceContainer.toBuilder();
- if (classJarOut != null) {
- // ensure the classJar is propagated if it exists. Otherwise, AndroidCommon tries to make it.
- // TODO(corysmith): Centralize the class jar generation.
- result.setJavaClassJar(classJarOut);
- }
+
+ result.setJavaClassJar(classJarOut);
+
if (manifestOut != null) {
result.setManifest(manifestOut);
}
@@ -307,8 +217,9 @@ public class AndroidResourceMergingActionBuilder {
return result.build();
}
- public MergedAndroidResources build(RuleContext ruleContext, ParsedAndroidResources parsed) {
- withPrimary(parsed).build(ruleContext);
+ public MergedAndroidResources build(
+ AndroidDataContext dataContext, ParsedAndroidResources parsed) {
+ withPrimary(parsed).build(dataContext);
return MergedAndroidResources.of(
parsed,
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java
index a3bd4773d6..13976552ef 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceParsingActionBuilder.java
@@ -15,31 +15,16 @@ package com.google.devtools.build.lib.rules.android;
import static java.util.stream.Collectors.joining;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Streams;
import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.ParamFileInfo;
-import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
-import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
-import com.google.devtools.build.lib.analysis.actions.CustomCommandLine;
-import com.google.devtools.build.lib.analysis.actions.SpawnAction;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
-import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
-import com.google.devtools.build.lib.util.OS;
+import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion;
import com.google.devtools.build.lib.vfs.PathFragment;
-import java.util.ArrayList;
-import java.util.List;
import javax.annotation.Nullable;
/** Builder for creating $android_resource_parser action. */
public class AndroidResourceParsingActionBuilder {
- private final RuleContext ruleContext;
- private final AndroidSdkProvider sdk;
-
// These are only needed when parsing resources with data binding
@Nullable private Artifact manifest;
@Nullable private String javaPackage;
@@ -54,12 +39,6 @@ public class AndroidResourceParsingActionBuilder {
@Nullable private Artifact compiledSymbols;
@Nullable private Artifact dataBindingInfoZip;
- /** @param ruleContext The RuleContext that was used to create the SpawnAction.Builder. */
- public AndroidResourceParsingActionBuilder(RuleContext ruleContext) {
- this.ruleContext = ruleContext;
- this.sdk = AndroidSdkProvider.fromRuleContext(ruleContext);
- }
-
/** Set the artifact location for the output protobuf. */
public AndroidResourceParsingActionBuilder setOutput(Artifact output) {
this.output = output;
@@ -103,86 +82,32 @@ public class AndroidResourceParsingActionBuilder {
return Streams.stream(roots).map(Object::toString).collect(joining("#"));
}
- private void build(ActionConstructionContext context) {
- CustomCommandLine.Builder builder = new CustomCommandLine.Builder();
-
- // Set the busybox tool.
- builder.add("--tool").add("PARSE").add("--");
-
- NestedSetBuilder<Artifact> inputs = NestedSetBuilder.naiveLinkOrder();
-
+ private void build(AndroidDataContext dataContext) {
String resourceDirectories =
convertRoots(resources.getResourceRoots()) + ":" + convertRoots(assets.getAssetRoots());
- builder.add("--primaryData", resourceDirectories);
- inputs.addTransitive(
- NestedSetBuilder.<Artifact>naiveLinkOrder()
- .addAll(assets.getAssets())
- .addAll(resources.getResources())
- .build());
-
- Preconditions.checkNotNull(output);
- builder.addExecPath("--output", output);
-
- SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder();
- ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED);
- // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special
- // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting
- // semantics are very complicated (more so than in Bash), so let's just always use a parameter
- // file.
- // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating
- // list-type and list-of-list-type flags that use such problematic separators in favor of
- // multi-value flags (to remove one level of listing) and by changing all list separators to a
- // platform-safe character (= comma).
- paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS);
-
- // Create the spawn action.
- ruleContext.registerAction(
- spawnActionBuilder
- .useDefaultShellEnvironment()
- .addTransitiveInputs(inputs.build())
- .addOutputs(ImmutableList.of(output))
- .addCommandLine(builder.build(), paramFileInfo.build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage("Parsing Android resources for %s", ruleContext.getLabel())
- .setMnemonic("AndroidResourceParser")
- .build(context));
+ Iterable<Artifact> resourceArtifacts =
+ Iterables.concat(assets.getAssets(), resources.getResources());
+
+ BusyBoxActionBuilder.create(dataContext, "PARSE")
+ .addInput("--primaryData", resourceDirectories, resourceArtifacts)
+ .addOutput("--output", output)
+ .buildAndRegister("Parsing Android resources", "AndroidResourceParser");
if (compiledSymbols != null) {
- List<Artifact> outs = new ArrayList<>();
- CustomCommandLine.Builder flatFileBuilder = new CustomCommandLine.Builder();
- flatFileBuilder
- .add("--tool")
- .add("COMPILE_LIBRARY_RESOURCES")
- .add("--")
- .addExecPath("--aapt2", sdk.getAapt2().getExecutable())
- .add("--resources", resourceDirectories)
- .addExecPath("--output", compiledSymbols);
- inputs.add(sdk.getAapt2().getExecutable());
- outs.add(compiledSymbols);
-
- // The databinding needs to be processed before compilation, so the stripping happens here.
+ BusyBoxActionBuilder compiledBuilder =
+ BusyBoxActionBuilder.create(dataContext, "COMPILE_LIBRARY_RESOURCES")
+ .addAapt(AndroidAaptVersion.AAPT2)
+ .addInput("--resources", resourceDirectories, resourceArtifacts)
+ .addOutput("--output", compiledSymbols);
+
if (dataBindingInfoZip != null) {
- flatFileBuilder.addExecPath("--manifest", manifest);
- inputs.add(manifest);
- if (!Strings.isNullOrEmpty(javaPackage)) {
- flatFileBuilder.add("--packagePath", javaPackage);
- }
- flatFileBuilder.addExecPath("--dataBindingInfoOut", dataBindingInfoZip);
- outs.add(dataBindingInfoZip);
+ compiledBuilder
+ .addInput("--manifest", manifest)
+ .maybeAddFlag("--packagePath", javaPackage)
+ .addOutput("--dataBindingInfoOut", dataBindingInfoZip);
}
- // Create the spawn action.
- ruleContext.registerAction(
- new SpawnAction.Builder()
- .useDefaultShellEnvironment()
- .addTransitiveInputs(inputs.build())
- .addOutputs(ImmutableList.copyOf(outs))
- .addCommandLine(flatFileBuilder.build(), paramFileInfo.build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage("Compiling Android resources for %s", ruleContext.getLabel())
- .setMnemonic("AndroidResourceCompiler")
- .build(context));
+
+ compiledBuilder.buildAndRegister("Compiling Android resources", "AndroidResourceCompiler");
}
}
@@ -191,7 +116,9 @@ public class AndroidResourceParsingActionBuilder {
* parsed and compiled information.
*/
public ParsedAndroidResources build(
- AndroidResources androidResources, StampedAndroidManifest manifest) {
+ AndroidDataContext dataContext,
+ AndroidResources androidResources,
+ StampedAndroidManifest manifest) {
if (dataBindingInfoZip != null) {
// Manifest information is needed for data binding
setManifest(manifest.getManifest());
@@ -199,17 +126,17 @@ public class AndroidResourceParsingActionBuilder {
}
setResources(androidResources);
- build(ruleContext);
+ build(dataContext);
return ParsedAndroidResources.of(
- androidResources, output, compiledSymbols, ruleContext.getLabel(), manifest);
+ androidResources, output, compiledSymbols, dataContext.getLabel(), manifest);
}
- public ParsedAndroidAssets build(AndroidAssets assets) {
+ public ParsedAndroidAssets build(AndroidDataContext dataContext, AndroidAssets assets) {
setAssets(assets);
- build(ruleContext);
+ build(dataContext);
- return ParsedAndroidAssets.of(assets, output, ruleContext.getLabel());
+ return ParsedAndroidAssets.of(assets, output, dataContext.getLabel());
}
/**
@@ -217,8 +144,8 @@ public class AndroidResourceParsingActionBuilder {
* symbols.
*/
public ResourceContainer buildAndUpdate(
- RuleContext ruleContext, ResourceContainer resourceContainer) {
- build(ruleContext);
+ AndroidDataContext dataContext, ResourceContainer resourceContainer) {
+ build(dataContext);
ResourceContainer.Builder builder =
resourceContainer
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java
index 41abe2f7a3..13a7c04753 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java
@@ -14,19 +14,8 @@
package com.google.devtools.build.lib.rules.android;
import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.ParamFileInfo;
-import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
-import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.actions.ActionConstructionContext;
-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.analysis.actions.SpawnAction;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
-import java.util.ArrayList;
-import java.util.List;
+import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion;
/**
* Builder for creating $android_resource_validator action. This action validates merged resources
@@ -37,9 +26,6 @@ import java.util.List;
*/
public class AndroidResourceValidatorActionBuilder {
- private final RuleContext ruleContext;
- private final AndroidSdkProvider sdk;
-
// Inputs
private CompiledMergableAndroidData primary;
private Artifact mergedResources;
@@ -58,12 +44,6 @@ public class AndroidResourceValidatorActionBuilder {
private Artifact compiledSymbols;
private Artifact apkOut;
- /** @param ruleContext The RuleContext that was used to create the SpawnAction.Builder. */
- public AndroidResourceValidatorActionBuilder(RuleContext ruleContext) {
- this.ruleContext = ruleContext;
- this.sdk = AndroidSdkProvider.fromRuleContext(ruleContext);
- }
-
public AndroidResourceValidatorActionBuilder setStaticLibraryOut(Artifact staticLibraryOut) {
this.staticLibraryOut = staticLibraryOut;
return this;
@@ -116,19 +96,19 @@ public class AndroidResourceValidatorActionBuilder {
return this;
}
- private void build(ActionConstructionContext context) {
+ private void build(AndroidDataContext dataContext) {
if (rTxtOut != null) {
- createValidateAction(context);
+ createValidateAction(dataContext);
}
if (compiledSymbols != null) {
- createLinkStaticLibraryAction(context);
+ createLinkStaticLibraryAction(dataContext);
}
}
public ResourceContainer build(
- ActionConstructionContext context, ResourceContainer resourceContainer) {
- withPrimary(resourceContainer).build(context);
+ AndroidDataContext dataContext, ResourceContainer resourceContainer) {
+ withPrimary(resourceContainer).build(dataContext);
ResourceContainer.Builder builder = resourceContainer.toBuilder();
if (rTxtOut != null) {
@@ -146,17 +126,11 @@ public class AndroidResourceValidatorActionBuilder {
}
public ValidatedAndroidResources build(
- ActionConstructionContext context, MergedAndroidResources merged) {
- withPrimary(merged).build(context);
+ AndroidDataContext dataContext, MergedAndroidResources merged) {
+ withPrimary(merged).build(dataContext);
return ValidatedAndroidResources.of(
- merged,
- rTxtOut,
- sourceJarOut,
- apkOut,
- aapt2RTxtOut,
- aapt2SourceJarOut,
- staticLibraryOut);
+ merged, rTxtOut, sourceJarOut, apkOut, aapt2RTxtOut, aapt2SourceJarOut, staticLibraryOut);
}
public AndroidResourceValidatorActionBuilder setCompiledSymbols(Artifact compiledSymbols) {
@@ -175,130 +149,47 @@ public class AndroidResourceValidatorActionBuilder {
* <p>This allows the link action to replace the validate action for builds that use aapt2, as
* opposed to executing both actions.
*/
- private void createLinkStaticLibraryAction(ActionConstructionContext context) {
- Preconditions.checkNotNull(staticLibraryOut);
- Preconditions.checkNotNull(aapt2SourceJarOut);
- Preconditions.checkNotNull(aapt2RTxtOut);
+ private void createLinkStaticLibraryAction(AndroidDataContext dataContext) {
Preconditions.checkNotNull(resourceDeps);
- CustomCommandLine.Builder builder = new CustomCommandLine.Builder();
- ImmutableList.Builder<Artifact> inputs = ImmutableList.builder();
- ImmutableList.Builder<Artifact> outs = ImmutableList.builder();
-
- // Set the busybox tool.
- builder.add("--tool").add("LINK_STATIC_LIBRARY").add("--");
-
- builder.addExecPath("--aapt2", sdk.getAapt2().getExecutable());
-
- builder.add("--libraries").addExecPath(sdk.getAndroidJar());
- inputs.add(sdk.getAndroidJar());
-
- builder.addExecPath("--compiled", compiledSymbols);
- inputs.add(compiledSymbols);
+ BusyBoxActionBuilder builder =
+ BusyBoxActionBuilder.create(dataContext, "LINK_STATIC_LIBRARY")
+ .addAapt(AndroidAaptVersion.AAPT2)
+ .addInput("--libraries", dataContext.getSdk().getAndroidJar())
+ .addInput("--compiled", compiledSymbols)
+ .addInput("--manifest", primary.getManifest())
- builder.addExecPath("--manifest", primary.getManifest());
- inputs.add(primary.getManifest());
-
- if (!Strings.isNullOrEmpty(customJavaPackage)) {
- // Sets an alternative java package for the generated R.java
- // this allows android rules to generate resources outside of the java{,tests} tree.
- builder.add("--packageForR", customJavaPackage);
- }
+ // Sets an alternative java package for the generated R.java
+ // this allows android rules to generate resources outside of the java{,tests} tree.
+ .maybeAddFlag("--packageForR", customJavaPackage);
if (!resourceDeps.getTransitiveCompiledSymbols().isEmpty()) {
- builder.addExecPaths(
- "--compiledDep",
- VectorArg.join(context.getConfiguration().getHostPathSeparator())
- .each(resourceDeps.getTransitiveCompiledSymbols()));
- inputs.addAll(resourceDeps.getTransitiveCompiledSymbols());
- }
-
- builder.addExecPath("--sourceJarOut", aapt2SourceJarOut);
- outs.add(aapt2SourceJarOut);
-
- builder.addExecPath("--rTxtOut", aapt2RTxtOut);
- outs.add(aapt2RTxtOut);
-
- builder.addExecPath("--staticLibraryOut", staticLibraryOut);
- outs.add(staticLibraryOut);
-
- ruleContext.registerAction(
- new SpawnAction.Builder()
- .useDefaultShellEnvironment()
- .addTool(sdk.getAapt2())
- .addInputs(inputs.build())
- .addOutputs(outs.build())
- .addCommandLine(
- builder.build(), ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage(
- "Linking static android resource library for %s", ruleContext.getLabel())
- .setMnemonic("AndroidResourceLink")
- .build(context));
- }
-
- private void createValidateAction(ActionConstructionContext context) {
- CustomCommandLine.Builder builder = new CustomCommandLine.Builder();
-
- // Set the busybox tool.
- builder.add("--tool").add("VALIDATE").add("--");
-
- if (!Strings.isNullOrEmpty(sdk.getBuildToolsVersion())) {
- builder.add("--buildToolsVersion", sdk.getBuildToolsVersion());
- }
-
- builder.addExecPath("--aapt", sdk.getAapt().getExecutable());
-
- ImmutableList.Builder<Artifact> inputs = ImmutableList.builder();
-
- builder.addExecPath("--androidJar", sdk.getAndroidJar());
- inputs.add(sdk.getAndroidJar());
-
- Preconditions.checkNotNull(mergedResources);
- builder.addExecPath("--mergedResources", mergedResources);
- inputs.add(mergedResources);
-
- builder.addExecPath("--manifest", primary.getManifest());
- inputs.add(primary.getManifest());
-
- if (debug) {
- builder.add("--debug");
- }
-
- if (!Strings.isNullOrEmpty(customJavaPackage)) {
- // Sets an alternative java package for the generated R.java
- // this allows android rules to generate resources outside of the java{,tests} tree.
- builder.add("--packageForR", customJavaPackage);
- }
- List<Artifact> outs = new ArrayList<>();
- Preconditions.checkNotNull(rTxtOut);
- builder.addExecPath("--rOutput", rTxtOut);
- outs.add(rTxtOut);
-
- Preconditions.checkNotNull(sourceJarOut);
- builder.addExecPath("--srcJarOutput", sourceJarOut);
- outs.add(sourceJarOut);
-
- if (apkOut != null) {
- builder.addExecPath("--packagePath", apkOut);
- outs.add(apkOut);
+ builder.addTransitiveVectoredInput(
+ "--compiledDep", resourceDeps.getTransitiveCompiledSymbols());
}
- SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder();
- // Create the spawn action.
- ruleContext.registerAction(
- spawnActionBuilder
- .useDefaultShellEnvironment()
- .addTool(sdk.getAapt())
- .addInputs(inputs.build())
- .addOutputs(ImmutableList.copyOf(outs))
- .addCommandLine(
- builder.build(), ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage("Validating Android resources for %s", ruleContext.getLabel())
- .setMnemonic("AndroidResourceValidator")
- .build(context));
+ builder
+ .addOutput("--sourceJarOut", aapt2SourceJarOut)
+ .addOutput("--rTxtOut", aapt2RTxtOut)
+ .addOutput("--staticLibraryOut", staticLibraryOut)
+ .buildAndRegister("Linking static android resource library", "AndroidResourceLink");
+ }
+
+ private void createValidateAction(AndroidDataContext dataContext) {
+ BusyBoxActionBuilder.create(dataContext, "VALIDATE")
+ .maybeAddFlag("--buildToolsVersion", dataContext.getSdk().getBuildToolsVersion())
+ .addAapt(AndroidAaptVersion.AAPT)
+ .addAndroidJar()
+ .addInput("--mergedResources", mergedResources)
+ .addInput("--manifest", primary.getManifest())
+ .maybeAddFlag("--debug", debug)
+
+ // Sets an alternative java package for the generated R.java
+ // this allows android rules to generate resources outside of the java{,tests} tree.
+ .maybeAddFlag("--packageForR", customJavaPackage)
+ .addOutput("--rOutput", rTxtOut)
+ .addOutput("--srcJarOutput", sourceJarOut)
+ .maybeAddOutput("--packagePath", apkOut)
+ .buildAndRegister("Validating Android resources", "AndroidResourceValidator");
}
}
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 3417f538c6..58c0a6669a 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
@@ -13,55 +13,45 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.android;
-import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.ParamFileInfo;
-import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
-import com.google.devtools.build.lib.analysis.RuleContext;
-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.analysis.actions.SpawnAction;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
-import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion;
-import com.google.devtools.build.lib.rules.android.ResourceContainerConverter.ToArg;
-import com.google.devtools.build.lib.rules.android.ResourceContainerConverter.ToArg.Includes;
-import com.google.devtools.build.lib.util.OS;
-import java.util.ArrayList;
+import com.google.devtools.build.lib.rules.android.AndroidDataConverter.JoinerType;
import java.util.Collections;
import java.util.List;
/** Builder for creating resource processing action. */
public class AndroidResourcesProcessorBuilder {
- private static final ResourceContainerConverter.ToArg AAPT2_RESOURCE_DEP_TO_ARG =
- ResourceContainerConverter.builder()
- .include(Includes.ResourceRoots)
- .include(Includes.Manifest)
- .include(Includes.Aapt2RTxt)
- .include(Includes.SymbolsBin)
- .include(Includes.CompiledSymbols)
- .withSeparator(ToArg.SeparatorType.COLON_COMMA)
- .toArgConverter();
-
- private static final ResourceContainerConverter.ToArg AAPT2_RESOURCE_DEP_TO_ARG_NO_PARSE =
- ResourceContainerConverter.builder()
- .include(Includes.ResourceRoots)
- .include(Includes.Manifest)
- .include(Includes.Aapt2RTxt)
- .include(Includes.CompiledSymbols)
- .withSeparator(ToArg.SeparatorType.COLON_COMMA)
- .toArgConverter();
-
- private static final ResourceContainerConverter.ToArg RESOURCE_DEP_TO_ARG =
- ResourceContainerConverter.builder()
- .include(Includes.ResourceRoots)
- .include(Includes.Manifest)
- .include(Includes.RTxt)
- .include(Includes.SymbolsBin)
- .withSeparator(ToArg.SeparatorType.COLON_COMMA)
- .toArgConverter();
+ private static final AndroidDataConverter<ValidatedAndroidData> AAPT2_RESOURCE_DEP_TO_ARG =
+ AndroidDataConverter.<ValidatedAndroidData>builder(JoinerType.COLON_COMMA)
+ .withRoots(ValidatedAndroidData::getResourceRoots)
+ .withRoots(ValidatedAndroidData::getAssetRoots)
+ .withArtifact(ValidatedAndroidData::getManifest)
+ .maybeWithArtifact(ValidatedAndroidData::getAapt2RTxt)
+ .maybeWithArtifact(ValidatedAndroidData::getCompiledSymbols)
+ .maybeWithArtifact(ValidatedAndroidData::getSymbols)
+ .build();
+
+ private static final AndroidDataConverter<ValidatedAndroidData>
+ AAPT2_RESOURCE_DEP_TO_ARG_NO_PARSE =
+ AndroidDataConverter.<ValidatedAndroidData>builder(JoinerType.COLON_COMMA)
+ .withRoots(ValidatedAndroidData::getResourceRoots)
+ .withRoots(ValidatedAndroidData::getAssetRoots)
+ .withArtifact(ValidatedAndroidData::getManifest)
+ .maybeWithArtifact(ValidatedAndroidData::getAapt2RTxt)
+ .maybeWithArtifact(ValidatedAndroidData::getCompiledSymbols)
+ .build();
+
+ private static final AndroidDataConverter<ValidatedAndroidData> RESOURCE_DEP_TO_ARG =
+ AndroidDataConverter.<ValidatedAndroidData>builder(JoinerType.COLON_COMMA)
+ .withRoots(ValidatedAndroidData::getResourceRoots)
+ .withRoots(ValidatedAndroidData::getAssetRoots)
+ .withArtifact(ValidatedAndroidData::getManifest)
+ .maybeWithArtifact(ValidatedAndroidData::getRTxt)
+ .maybeWithArtifact(ValidatedAndroidData::getSymbols)
+ .build();
private ResourceDependencies resourceDependencies = ResourceDependencies.empty();
private AssetDependencies assetDependencies = AssetDependencies.empty();
@@ -75,10 +65,7 @@ public class AndroidResourcesProcessorBuilder {
private ResourceFilterFactory resourceFilterFactory = ResourceFilterFactory.empty();
private List<String> uncompressedExtensions = Collections.emptyList();
private Artifact apkOut;
- private final AndroidSdkProvider sdk;
- private SpawnAction.Builder spawnActionBuilder;
private String customJavaPackage;
- private final RuleContext ruleContext;
private String versionCode;
private String applicationId;
private String versionName;
@@ -97,13 +84,6 @@ public class AndroidResourcesProcessorBuilder {
private boolean useCompiledResourcesForMerge;
private boolean isTestWithResources = false;
- /** @param ruleContext The RuleContext that was used to create the SpawnAction.Builder. */
- public AndroidResourcesProcessorBuilder(RuleContext ruleContext) {
- this.sdk = AndroidSdkProvider.fromRuleContext(ruleContext);
- this.ruleContext = ruleContext;
- this.spawnActionBuilder = new SpawnAction.Builder();
- }
-
/**
* The output zip for resource-processed data binding expressions (i.e. a zip of .xml files).
*
@@ -227,9 +207,10 @@ public class AndroidResourcesProcessorBuilder {
* @return a {@link ResourceApk} containing the processed resource, asset, and manifest
* information.
*/
- public ResourceApk buildWithoutLocalResources(StampedAndroidManifest manifest) {
+ public ResourceApk buildWithoutLocalResources(
+ AndroidDataContext dataContext, StampedAndroidManifest manifest) {
- build(AndroidResources.empty(), AndroidAssets.empty(), manifest);
+ build(dataContext, AndroidResources.empty(), AndroidAssets.empty(), manifest);
return ResourceApk.fromTransitiveResources(
resourceDependencies,
@@ -238,8 +219,9 @@ public class AndroidResourcesProcessorBuilder {
rTxtOut);
}
- public ResourceContainer build(ResourceContainer primary) {
+ public ResourceContainer build(AndroidDataContext dataContext, ResourceContainer primary) {
build(
+ dataContext,
primary.getAndroidResources(),
primary.getAndroidAssets(),
ProcessedAndroidManifest.from(primary));
@@ -265,14 +247,15 @@ public class AndroidResourcesProcessorBuilder {
}
public ProcessedAndroidData build(
+ AndroidDataContext dataContext,
AndroidResources primaryResources,
AndroidAssets primaryAssets,
StampedAndroidManifest primaryManifest) {
if (aaptVersion == AndroidAaptVersion.AAPT2) {
- createAapt2ApkAction(primaryResources, primaryAssets, primaryManifest);
+ createAapt2ApkAction(dataContext, primaryResources, primaryAssets, primaryManifest);
} else {
- createAaptAction(primaryResources, primaryAssets, primaryManifest);
+ createAaptAction(dataContext, primaryResources, primaryAssets, primaryManifest);
}
// Wrap the new manifest, if any
@@ -288,12 +271,12 @@ public class AndroidResourcesProcessorBuilder {
primaryResources,
symbols,
/* compiledSymbols = */ null,
- ruleContext.getLabel(),
+ dataContext.getLabel(),
processedManifest);
// Wrap the parsed and merged assets
ParsedAndroidAssets parsedAssets =
- ParsedAndroidAssets.of(primaryAssets, symbols, ruleContext.getLabel());
+ ParsedAndroidAssets.of(primaryAssets, symbols, dataContext.getLabel());
MergedAndroidAssets mergedAssets =
MergedAndroidAssets.of(parsedAssets, mergedResourcesOut, assetDependencies);
@@ -349,289 +332,145 @@ public class AndroidResourcesProcessorBuilder {
}
private void createAapt2ApkAction(
+ AndroidDataContext dataContext,
AndroidResources primaryResources,
AndroidAssets primaryAssets,
StampedAndroidManifest primaryManifest) {
- List<Artifact> outs = new ArrayList<>();
- // TODO(corysmith): Convert to an immutable list builder, as there is no benefit to a NestedSet
- // here, as it will already have been flattened.
- NestedSetBuilder<Artifact> inputs = NestedSetBuilder.naiveLinkOrder();
- CustomCommandLine.Builder builder = new CustomCommandLine.Builder();
+ BusyBoxActionBuilder builder =
+ BusyBoxActionBuilder.create(dataContext, "AAPT2_PACKAGE").addAapt(AndroidAaptVersion.AAPT2);
- // Set the busybox tool.
- builder.add("--tool").add("AAPT2_PACKAGE").add("--");
-
- builder.addExecPath("--aapt2", sdk.getAapt2().getExecutable());
if (resourceDependencies != null) {
- ResourceContainerConverter.addToCommandLine(
- resourceDependencies,
- builder,
- useCompiledResourcesForMerge
- ? AAPT2_RESOURCE_DEP_TO_ARG_NO_PARSE
- : AAPT2_RESOURCE_DEP_TO_ARG);
- inputs
- .addTransitive(resourceDependencies.getTransitiveResources())
- .addTransitive(resourceDependencies.getTransitiveAssets())
- .addTransitive(resourceDependencies.getTransitiveManifests())
- .addTransitive(resourceDependencies.getTransitiveAapt2RTxt())
- .addTransitive(resourceDependencies.getTransitiveCompiledSymbols());
+ builder
+ .addTransitiveFlag(
+ "--data",
+ resourceDependencies.getTransitiveResourceContainers(),
+ useCompiledResourcesForMerge
+ ? AAPT2_RESOURCE_DEP_TO_ARG_NO_PARSE
+ : AAPT2_RESOURCE_DEP_TO_ARG)
+ .addTransitiveFlag(
+ "--directData",
+ resourceDependencies.getDirectResourceContainers(),
+ useCompiledResourcesForMerge
+ ? AAPT2_RESOURCE_DEP_TO_ARG_NO_PARSE
+ : AAPT2_RESOURCE_DEP_TO_ARG)
+ .addTransitiveInputValues(resourceDependencies.getTransitiveResources())
+ .addTransitiveInputValues(resourceDependencies.getTransitiveAssets())
+ .addTransitiveInputValues(resourceDependencies.getTransitiveManifests())
+ .addTransitiveInputValues(resourceDependencies.getTransitiveAapt2RTxt())
+ .addTransitiveInputValues(resourceDependencies.getTransitiveCompiledSymbols());
if (!useCompiledResourcesForMerge) {
- inputs.addTransitive(resourceDependencies.getTransitiveSymbolsBin());
+ builder.addTransitiveInputValues(resourceDependencies.getTransitiveSymbolsBin());
}
}
- addAssetDeps(builder, inputs);
-
- if (useCompiledResourcesForMerge) {
- builder.add("--useCompiledResourcesForMerge");
- }
-
- if (conditionalKeepRules) {
- builder.add("--conditionalKeepRules");
- }
+ addAssetDeps(builder)
+ .maybeAddFlag("--useCompiledResourcesForMerge", useCompiledResourcesForMerge)
+ .maybeAddFlag("--conditionalKeepRules", conditionalKeepRules);
- configureCommonFlags(primaryResources, primaryAssets, primaryManifest, outs, inputs, builder);
-
- ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED);
- // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special
- // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting
- // semantics are very complicated (more so than in Bash), so let's just always use a parameter
- // file.
- // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating
- // list-type and list-of-list-type flags that use such problematic separators in favor of
- // multi-value flags (to remove one level of listing) and by changing all list separators to a
- // platform-safe character (= comma).
- paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS);
-
- // Create the spawn action.
- ruleContext.registerAction(
- this.spawnActionBuilder
- .useDefaultShellEnvironment()
- .addTool(sdk.getAapt2())
- .addTransitiveInputs(inputs.build())
- .addOutputs(ImmutableList.<Artifact>copyOf(outs))
- .addCommandLine(builder.build(), paramFileInfo.build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage("Processing Android resources for %s", ruleContext.getLabel())
- .setMnemonic("AndroidAapt2")
- .build(ruleContext));
+ configureCommonFlags(dataContext, primaryResources, primaryAssets, primaryManifest, builder)
+ .buildAndRegister("Processing Android resources", "AndroidAapt2");
}
private void createAaptAction(
+ AndroidDataContext dataContext,
AndroidResources primaryResources,
AndroidAssets primaryAssets,
StampedAndroidManifest primaryManifest) {
- List<Artifact> outs = new ArrayList<>();
- // TODO(corysmith): Convert to an immutable list builder, as there is no benefit to a NestedSet
- // here, as it will already have been flattened.
- NestedSetBuilder<Artifact> inputs = NestedSetBuilder.naiveLinkOrder();
- CustomCommandLine.Builder builder = new CustomCommandLine.Builder();
-
- // Set the busybox tool.
- builder.add("--tool").add("PACKAGE").add("--");
+ BusyBoxActionBuilder builder = BusyBoxActionBuilder.create(dataContext, "PACKAGE");
if (resourceDependencies != null) {
- ResourceContainerConverter.addToCommandLine(
- resourceDependencies, builder, RESOURCE_DEP_TO_ARG);
- inputs
- .addTransitive(resourceDependencies.getTransitiveResources())
- .addTransitive(resourceDependencies.getTransitiveAssets())
- .addTransitive(resourceDependencies.getTransitiveManifests())
- .addTransitive(resourceDependencies.getTransitiveRTxt())
- .addTransitive(resourceDependencies.getTransitiveSymbolsBin());
+ builder
+ .addTransitiveFlag(
+ "--data", resourceDependencies.getTransitiveResourceContainers(), RESOURCE_DEP_TO_ARG)
+ .addTransitiveFlag(
+ "--directData",
+ resourceDependencies.getDirectResourceContainers(),
+ RESOURCE_DEP_TO_ARG)
+ .addTransitiveInputValues(resourceDependencies.getTransitiveResources())
+ .addTransitiveInputValues(resourceDependencies.getTransitiveAssets())
+ .addTransitiveInputValues(resourceDependencies.getTransitiveManifests())
+ .addTransitiveInputValues(resourceDependencies.getTransitiveRTxt())
+ .addTransitiveInputValues(resourceDependencies.getTransitiveSymbolsBin());
}
- addAssetDeps(builder, inputs);
+ addAssetDeps(builder).addAapt(AndroidAaptVersion.AAPT);
- builder.addExecPath("--aapt", sdk.getAapt().getExecutable());
- configureCommonFlags(primaryResources, primaryAssets, primaryManifest, outs, inputs, builder);
-
- ImmutableList<String> filteredResources =
- resourceFilterFactory.getResourcesToIgnoreInExecution();
- if (!filteredResources.isEmpty()) {
- builder.addAll("--prefilteredResources", VectorArg.join(",").each(filteredResources));
- }
+ configureCommonFlags(dataContext, primaryResources, primaryAssets, primaryManifest, builder)
+ .maybeAddVectoredFlag(
+ "--prefilteredResources", resourceFilterFactory.getResourcesToIgnoreInExecution())
+ .buildAndRegister("Processing Android resources", "AaptPackage");
+ }
- ParamFileInfo.Builder paramFileInfo = ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED);
- // Some flags (e.g. --mainData) may specify lists (or lists of lists) separated by special
- // characters (colon, semicolon, hashmark, ampersand) that don't work on Windows, and quoting
- // semantics are very complicated (more so than in Bash), so let's just always use a parameter
- // file.
- // TODO(laszlocsomor), TODO(corysmith): restructure the Android BusyBux's flags by deprecating
- // list-type and list-of-list-type flags that use such problematic separators in favor of
- // multi-value flags (to remove one level of listing) and by changing all list separators to a
- // platform-safe character (= comma).
- paramFileInfo.setUseAlways(OS.getCurrent() == OS.WINDOWS);
-
- // Create the spawn action.
- ruleContext.registerAction(
- this.spawnActionBuilder
- .useDefaultShellEnvironment()
- .addTool(sdk.getAapt())
- .addTransitiveInputs(inputs.build())
- .addOutputs(ImmutableList.copyOf(outs))
- .addCommandLine(builder.build(), paramFileInfo.build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage("Processing Android resources for %s", ruleContext.getLabel())
- .setMnemonic("AaptPackage")
- .build(ruleContext));
- }
-
- private void addAssetDeps(CustomCommandLine.Builder builder, NestedSetBuilder<Artifact> inputs) {
+ private BusyBoxActionBuilder addAssetDeps(BusyBoxActionBuilder builder) {
if (assetDependencies == null || assetDependencies.getTransitiveAssets().isEmpty()) {
- return;
+ return builder;
}
- builder
- .addAll(
+ return builder
+ .addTransitiveFlag(
"--directAssets",
- AndroidDataConverter.MERGABLE_DATA_CONVERTER.getVectorArg(
- assetDependencies.getDirectParsedAssets()))
- .addAll(
+ assetDependencies.getDirectParsedAssets(),
+ AndroidDataConverter.MERGABLE_DATA_CONVERTER)
+ .addTransitiveFlag(
"--assets",
- AndroidDataConverter.MERGABLE_DATA_CONVERTER.getVectorArg(
- assetDependencies.getTransitiveParsedAssets()));
-
- inputs.addTransitive(assetDependencies.getTransitiveAssets());
- inputs.addTransitive(assetDependencies.getTransitiveSymbols());
+ assetDependencies.getTransitiveParsedAssets(),
+ AndroidDataConverter.MERGABLE_DATA_CONVERTER)
+ .addTransitiveInputValues(assetDependencies.getTransitiveAssets())
+ .addTransitiveInputValues(assetDependencies.getTransitiveSymbols());
}
- private void configureCommonFlags(
+ private BusyBoxActionBuilder configureCommonFlags(
+ AndroidDataContext dataContext,
AndroidResources primaryResources,
AndroidAssets primaryAssets,
StampedAndroidManifest primaryManifest,
- List<Artifact> outs,
- NestedSetBuilder<Artifact> inputs,
- CustomCommandLine.Builder builder) {
-
- // Add data
- builder.add(
- "--primaryData",
- String.format(
- "%s:%s:%s",
- AndroidDataConverter.rootsToString(primaryResources.getResourceRoots()),
- AndroidDataConverter.rootsToString(primaryAssets.getAssetRoots()),
- primaryManifest.getManifest().getExecPathString()));
- inputs.addAll(primaryResources.getResources());
- inputs.addAll(primaryAssets.getAssets());
- inputs.add(primaryManifest.getManifest());
-
- if (!Strings.isNullOrEmpty(sdk.getBuildToolsVersion())) {
- builder.add("--buildToolsVersion", sdk.getBuildToolsVersion());
- }
-
- builder.addExecPath("--androidJar", sdk.getAndroidJar());
- inputs.add(sdk.getAndroidJar());
-
- if (isLibrary) {
- builder.add("--packageType").add("LIBRARY");
- }
-
- if (rTxtOut != null) {
- builder.addExecPath("--rOutput", rTxtOut);
- outs.add(rTxtOut);
- }
-
- if (symbols != null) {
- builder.addExecPath("--symbolsOut", symbols);
- outs.add(symbols);
- }
- if (sourceJarOut != null) {
- builder.addExecPath("--srcJarOutput", sourceJarOut);
- outs.add(sourceJarOut);
- }
- if (proguardOut != null) {
- builder.addExecPath("--proguardOutput", proguardOut);
- outs.add(proguardOut);
- }
-
- if (mainDexProguardOut != null) {
- builder.addExecPath("--mainDexProguardOutput", mainDexProguardOut);
- outs.add(mainDexProguardOut);
- }
-
- if (manifestOut != null) {
- builder.addExecPath("--manifestOutput", manifestOut);
- outs.add(manifestOut);
- }
-
- if (mergedResourcesOut != null) {
- builder.addExecPath("--resourcesOutput", mergedResourcesOut);
- outs.add(mergedResourcesOut);
- }
-
- if (apkOut != null) {
- builder.addExecPath("--packagePath", apkOut);
- outs.add(apkOut);
- }
-
- // Always pass density and resource configuration filter strings to execution, even when
- // filtering in analysis. Filtering in analysis cannot remove resources from Filesets, and, in
- // addition, aapt needs access to resource filters to generate pseudolocalized resources and
- // because its resource filtering is somewhat stricter for locales, and
- // resource processing needs access to densities to add them to the manifest.
- if (resourceFilterFactory.hasConfigurationFilters()) {
- builder.add("--resourceConfigs", resourceFilterFactory.getConfigurationFilterString());
- }
- if (resourceFilterFactory.hasDensities()) {
- builder.add("--densities", resourceFilterFactory.getDensityString());
- }
- if (!uncompressedExtensions.isEmpty()) {
- builder.addAll("--uncompressedExtensions", VectorArg.join(",").each(uncompressedExtensions));
- }
- if (!crunchPng) {
- builder.add("--useAaptCruncher=no");
- }
- if (debug) {
- builder.add("--debug");
- }
-
- if (versionCode != null) {
- builder.add("--versionCode", versionCode);
- }
-
- if (versionName != null) {
- builder.add("--versionName", versionName);
- }
-
- if (applicationId != null) {
- builder.add("--applicationId", applicationId);
- }
-
- if (dataBindingInfoZip != null) {
- builder.addExecPath("--dataBindingInfoOut", dataBindingInfoZip);
- outs.add(dataBindingInfoZip);
- }
-
- if (!Strings.isNullOrEmpty(customJavaPackage)) {
- // Sets an alternative java package for the generated R.java
- // this allows android rules to generate resources outside of the java{,tests} tree.
- builder.add("--packageForR", customJavaPackage);
- }
-
- if (featureOf != null) {
- builder.addExecPath("--featureOf", featureOf);
- inputs.add(featureOf);
- }
-
- if (featureAfter != null) {
- builder.addExecPath("--featureAfter", featureAfter);
- inputs.add(featureAfter);
- }
-
- if (throwOnResourceConflict) {
- builder.add("--throwOnResourceConflict");
- }
-
- if (packageUnderTest != null) {
- builder.add("--packageUnderTest", packageUnderTest);
- }
-
- if (isTestWithResources) {
- builder.add("--isTestWithResources");
- }
+ BusyBoxActionBuilder builder) {
+
+ return builder
+ .addInput(
+ "--primaryData",
+ String.format(
+ "%s:%s:%s",
+ AndroidDataConverter.rootsToString(primaryResources.getResourceRoots()),
+ AndroidDataConverter.rootsToString(primaryAssets.getAssetRoots()),
+ primaryManifest.getManifest().getExecPathString()),
+ Iterables.concat(
+ primaryResources.getResources(),
+ primaryAssets.getAssets(),
+ ImmutableList.of(primaryManifest.getManifest())))
+ .maybeAddFlag("--buildToolsVersion", dataContext.getSdk().getBuildToolsVersion())
+ .addAndroidJar()
+ .maybeAddFlag("--packageType", isLibrary)
+ .maybeAddFlag("LIBRARY", isLibrary)
+ .maybeAddOutput("--rOutput", rTxtOut)
+ .maybeAddOutput("--symbolsOut", symbols)
+ .maybeAddOutput("--srcJarOutput", sourceJarOut)
+ .maybeAddOutput("--proguardOutput", proguardOut)
+ .maybeAddOutput("--mainDexProguardOutput", mainDexProguardOut)
+ .maybeAddOutput("--manifestOutput", manifestOut)
+ .maybeAddOutput("--resourcesOutput", mergedResourcesOut)
+ .maybeAddOutput("--packagePath", apkOut)
+
+ // Always pass density and resource configuration filter strings to execution, even when
+ // filtering in analysis. Filtering in analysis cannot remove resources from Filesets, and,
+ // in addition, aapt needs access to resource filters to generate pseudolocalized resources
+ // and because its resource filtering is somewhat stricter for locales, and resource
+ // processing needs access to densities to add them to the manifest.
+ .maybeAddFlag("--resourceConfigs", resourceFilterFactory.getConfigurationFilterString())
+ .maybeAddFlag("--densities", resourceFilterFactory.getDensityString())
+ .maybeAddVectoredFlag("--uncompressedExtensions", uncompressedExtensions)
+ .maybeAddFlag("--useAaptCruncher=no", !crunchPng)
+ .maybeAddFlag("--debug", debug)
+ .maybeAddFlag("--versionCode", versionCode)
+ .maybeAddFlag("--versionName", versionName)
+ .maybeAddFlag("--applicationId", applicationId)
+ .maybeAddOutput("--dataBindingInfoOut", dataBindingInfoZip)
+ .maybeAddFlag("--packageForR", customJavaPackage)
+ .maybeAddInput("--featureOf", featureOf)
+ .maybeAddInput("--featureAfter", featureAfter)
+ .maybeAddFlag("--throwOnResourceConflict", throwOnResourceConflict)
+ .maybeAddFlag("--packageUnderTest", packageUnderTest)
+ .maybeAddFlag("--isTestWithResources", isTestWithResources);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
index 900f1056a9..d93b8a2b7f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ApplicationManifest.java
@@ -370,6 +370,7 @@ public final class ApplicationManifest {
public ResourceApk packTestWithDataAndResources(
RuleContext ruleContext,
+ AndroidDataContext dataContext,
Artifact resourceApk,
ResourceDependencies resourceDeps,
@Nullable Artifact rTxt,
@@ -390,7 +391,7 @@ public final class ApplicationManifest {
.build();
AndroidResourcesProcessorBuilder builder =
- new AndroidResourcesProcessorBuilder(ruleContext)
+ new AndroidResourcesProcessorBuilder()
.setLibrary(false)
.setApkOut(resourceContainer.getApk())
.setUncompressedExtensions(ImmutableList.of())
@@ -417,16 +418,16 @@ public final class ApplicationManifest {
.setSymbols(resourceContainer.getSymbols())
.setSourceJarOut(resourceContainer.getJavaSourceJar());
}
- ResourceContainer processed = builder.build(resourceContainer);
+ ResourceContainer processed = builder.build(dataContext, resourceContainer);
ResourceContainer finalContainer =
- new RClassGeneratorActionBuilder(ruleContext)
+ new RClassGeneratorActionBuilder()
.targetAaptVersion(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext))
.withDependencies(resourceDeps)
.setClassJarOut(
ruleContext.getImplicitOutputArtifact(
AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR))
- .build(processed);
+ .build(dataContext, processed);
return ResourceApk.of(finalContainer, resourceDeps, proguardCfg, mainDexProguardCfg);
}
@@ -434,6 +435,7 @@ public final class ApplicationManifest {
/** Packages up the manifest with resource and assets from the LocalResourceContainer. */
public ResourceApk packAarWithDataAndResources(
RuleContext ruleContext,
+ AndroidDataContext dataContext,
AndroidAssets assets,
AndroidResources resources,
ResourceDependencies resourceDeps,
@@ -455,14 +457,14 @@ public final class ApplicationManifest {
ruleContext.getImplicitOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR);
resourceContainer =
- new AndroidResourceParsingActionBuilder(ruleContext)
+ new AndroidResourceParsingActionBuilder()
.setAssets(assets)
.setResources(resources)
.setOutput(symbols)
- .buildAndUpdate(ruleContext, resourceContainer);
+ .buildAndUpdate(dataContext, resourceContainer);
ResourceContainer merged =
- new AndroidResourceMergingActionBuilder(ruleContext)
+ new AndroidResourceMergingActionBuilder()
.setJavaPackage(resourceContainer.getJavaPackage())
.withDependencies(resourceDeps)
.setMergedResourcesOut(mergedResources)
@@ -473,10 +475,10 @@ public final class ApplicationManifest {
.getConfiguration()
.getFragment(AndroidConfiguration.class)
.throwOnResourceConflict())
- .build(ruleContext, resourceContainer);
+ .build(dataContext, resourceContainer);
ResourceContainer processed =
- new AndroidResourceValidatorActionBuilder(ruleContext)
+ new AndroidResourceValidatorActionBuilder()
.setJavaPackage(merged.getJavaPackage())
.setDebug(ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT)
.setMergedResources(mergedResources)
@@ -489,7 +491,7 @@ public final class ApplicationManifest {
.setAapt2RTxtOut(merged.getAapt2RTxt())
.setAapt2SourceJarOut(merged.getAapt2JavaSourceJar())
.setStaticLibraryOut(merged.getStaticLibrary())
- .build(ruleContext, merged);
+ .build(dataContext, merged);
return ResourceApk.of(processed, resourceDeps);
}
@@ -497,6 +499,7 @@ public final class ApplicationManifest {
/* Creates an incremental apk from assets and data. */
public ResourceApk packIncrementalBinaryWithDataAndResources(
RuleContext ruleContext,
+ AndroidDataContext dataContext,
Artifact resourceApk,
ResourceDependencies resourceDeps,
List<String> uncompressedExtensions,
@@ -525,7 +528,7 @@ public final class ApplicationManifest {
.build();
ResourceContainer processed =
- new AndroidResourcesProcessorBuilder(ruleContext)
+ new AndroidResourcesProcessorBuilder()
.setLibrary(false)
.setApkOut(resourceContainer.getApk())
.setResourceFilterFactory(resourceFilterFactory)
@@ -544,7 +547,7 @@ public final class ApplicationManifest {
.getFragment(AndroidConfiguration.class)
.throwOnResourceConflict())
.setPackageUnderTest(null)
- .build(resourceContainer);
+ .build(dataContext, resourceContainer);
// Intentionally skip building an R class JAR - incremental binaries handle this separately.
@@ -555,6 +558,7 @@ public final class ApplicationManifest {
// TODO(bazel-team): this method calls for some refactoring, 15+ params including some nullables.
public ResourceApk packBinaryWithDataAndResources(
RuleContext ruleContext,
+ AndroidDataContext dataContext,
Artifact resourceApk,
ResourceDependencies resourceDeps,
@Nullable Artifact rTxt,
@@ -600,7 +604,7 @@ public final class ApplicationManifest {
}
ResourceContainer processed =
- new AndroidResourcesProcessorBuilder(ruleContext)
+ new AndroidResourcesProcessorBuilder()
.setLibrary(false)
.setApkOut(resourceContainer.getApk())
.setResourceFilterFactory(resourceFilterFactory)
@@ -626,22 +630,23 @@ public final class ApplicationManifest {
.setRTxtOut(resourceContainer.getRTxt())
.setSymbols(resourceContainer.getSymbols())
.setSourceJarOut(resourceContainer.getJavaSourceJar())
- .build(resourceContainer);
+ .build(dataContext, resourceContainer);
ResourceContainer finalContainer =
- new RClassGeneratorActionBuilder(ruleContext)
+ new RClassGeneratorActionBuilder()
.targetAaptVersion(AndroidAaptVersion.chooseTargetAaptVersion(ruleContext))
.withDependencies(resourceDeps)
.setClassJarOut(
ruleContext.getImplicitOutputArtifact(
AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR))
- .build(processed);
+ .build(dataContext, processed);
return ResourceApk.of(finalContainer, resourceDeps, proguardCfg, mainDexProguardCfg);
}
public ResourceApk packLibraryWithDataAndResources(
RuleContext ruleContext,
+ AndroidDataContext dataContext,
ResourceDependencies resourceDeps,
Artifact rTxt,
Artifact symbols,
@@ -689,7 +694,7 @@ public final class ApplicationManifest {
targetAaptVersion == AndroidAaptVersion.AAPT2 && androidConfiguration.skipParsingAction();
AndroidResourceParsingActionBuilder parsingBuilder =
- new AndroidResourceParsingActionBuilder(ruleContext)
+ new AndroidResourceParsingActionBuilder()
.setAssets(assets)
.setResources(resources)
.setOutput(resourceContainer.getSymbols())
@@ -708,10 +713,10 @@ public final class ApplicationManifest {
.setManifest(resourceContainer.getManifest())
.setJavaPackage(resourceContainer.getJavaPackage());
}
- resourceContainer = parsingBuilder.buildAndUpdate(ruleContext, resourceContainer);
+ resourceContainer = parsingBuilder.buildAndUpdate(dataContext, resourceContainer);
ResourceContainer merged =
- new AndroidResourceMergingActionBuilder(ruleContext)
+ new AndroidResourceMergingActionBuilder()
.setJavaPackage(resourceContainer.getJavaPackage())
.withDependencies(resourceDeps)
.setThrowOnResourceConflict(androidConfiguration.throwOnResourceConflict())
@@ -721,10 +726,10 @@ public final class ApplicationManifest {
.setManifestOut(manifestOut)
.setClassJarOut(rJavaClassJar)
.setDataBindingInfoZip(dataBindingInfoZip)
- .build(ruleContext, resourceContainer);
+ .build(dataContext, resourceContainer);
ResourceContainer processed =
- new AndroidResourceValidatorActionBuilder(ruleContext)
+ new AndroidResourceValidatorActionBuilder()
.setJavaPackage(merged.getJavaPackage())
.setDebug(ruleContext.getConfiguration().getCompilationMode() != CompilationMode.OPT)
.setMergedResources(mergedResources)
@@ -737,7 +742,7 @@ public final class ApplicationManifest {
.setAapt2RTxtOut(merged.getAapt2RTxt())
.setAapt2SourceJarOut(merged.getAapt2JavaSourceJar())
.setStaticLibraryOut(merged.getStaticLibrary())
- .build(ruleContext, merged);
+ .build(dataContext, merged);
return ResourceApk.of(processed, resourceDeps);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/BusyBoxActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/BusyBoxActionBuilder.java
index 07552fe2c1..16e55f8993 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/BusyBoxActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/BusyBoxActionBuilder.java
@@ -18,6 +18,7 @@ import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.ParamFileInfo;
import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
+import com.google.devtools.build.lib.analysis.FilesToRunProvider;
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.analysis.actions.SpawnAction;
@@ -49,7 +50,7 @@ public final class BusyBoxActionBuilder {
private final AndroidDataContext dataContext;
private final NestedSetBuilder<Artifact> inputs = NestedSetBuilder.naiveLinkOrder();
private final ImmutableList.Builder<Artifact> outputs = ImmutableList.builder();
- private final ImmutableList.Builder<Artifact> tools = ImmutableList.builder();
+ private final SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder();
private final CustomCommandLine.Builder commandLine = CustomCommandLine.builder();
public static BusyBoxActionBuilder create(
@@ -287,16 +288,16 @@ public final class BusyBoxActionBuilder {
/** Adds aapt to the command line and inputs. */
public BusyBoxActionBuilder addAapt(AndroidAaptVersion aaptVersion) {
- Artifact aapt;
+ FilesToRunProvider aapt;
if (aaptVersion == AndroidAaptVersion.AAPT2) {
- aapt = dataContext.getSdk().getAapt2().getExecutable();
- commandLine.addExecPath("--aapt2", aapt);
+ aapt = dataContext.getSdk().getAapt2();
+ commandLine.addExecPath("--aapt2", aapt.getExecutable());
} else {
- aapt = dataContext.getSdk().getAapt().getExecutable();
- commandLine.addExecPath("--aapt", aapt);
+ aapt = dataContext.getSdk().getAapt();
+ commandLine.addExecPath("--aapt", aapt.getExecutable());
}
- tools.add(aapt);
+ spawnActionBuilder.addTool(aapt);
return this;
}
@@ -315,11 +316,10 @@ public final class BusyBoxActionBuilder {
*/
public void buildAndRegister(String message, String mnemonic) {
dataContext.registerAction(
- new SpawnAction.Builder()
+ spawnActionBuilder
.useDefaultShellEnvironment()
.addTransitiveInputs(inputs.build())
.addOutputs(outputs.build())
- .addTools(tools.build())
.addCommandLine(commandLine.build(), FORCED_PARAM_FILE_INFO)
.setExecutable(dataContext.getBusybox())
.setProgressMessage("%s for %s", message, dataContext.getLabel())
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java
index da7ceda7b4..29da58659f 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/MergedAndroidResources.java
@@ -54,7 +54,7 @@ public class MergedAndroidResources extends ParsedAndroidResources {
"Should not use compiled merge if no compiled symbols are available!");
AndroidResourceMergingActionBuilder builder =
- new AndroidResourceMergingActionBuilder(dataContext.getRuleContext())
+ new AndroidResourceMergingActionBuilder()
.setJavaPackage(parsed.getJavaPackage())
.withDependencies(resourceDeps)
.setThrowOnResourceConflict(androidConfiguration.throwOnResourceConflict())
@@ -72,7 +72,7 @@ public class MergedAndroidResources extends ParsedAndroidResources {
dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_ZIP))
.setClassJarOut(
dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR))
- .build(dataContext.getRuleContext(), parsed);
+ .build(dataContext, parsed);
}
public static MergedAndroidResources of(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidAssets.java b/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidAssets.java
index 265f22f9d6..b1b2971045 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidAssets.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidAssets.java
@@ -24,9 +24,9 @@ public class ParsedAndroidAssets extends AndroidAssets implements MergableAndroi
public static ParsedAndroidAssets parseFrom(AndroidDataContext dataContext, AndroidAssets assets)
throws InterruptedException {
- return new AndroidResourceParsingActionBuilder(dataContext.getRuleContext())
+ return new AndroidResourceParsingActionBuilder()
.setOutput(dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_ASSET_SYMBOLS))
- .build(assets);
+ .build(dataContext, assets);
}
public static ParsedAndroidAssets of(AndroidAssets assets, Artifact symbols, Label label) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java
index 4ff37879c9..83b49b62d1 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ParsedAndroidResources.java
@@ -40,15 +40,14 @@ public class ParsedAndroidResources extends AndroidResources
boolean isAapt2 = aaptVersion == AndroidAaptVersion.AAPT2;
- AndroidResourceParsingActionBuilder builder =
- new AndroidResourceParsingActionBuilder(dataContext.getRuleContext());
+ AndroidResourceParsingActionBuilder builder = new AndroidResourceParsingActionBuilder();
if (enableDataBinding && isAapt2) {
// TODO(corysmith): Centralize the data binding processing and zipping into a single
// action. Data binding processing needs to be triggered here as well as the merger to
// avoid aapt2 from throwing an error during compilation.
builder.setDataBindingInfoZip(
- DataBinding.getSuffixedInfoFile(dataContext.getRuleContext(), "_unused"));
+ DataBinding.getSuffixedInfoFile(dataContext.getActionConstructionContext(), "_unused"));
}
return builder
@@ -57,7 +56,7 @@ public class ParsedAndroidResources extends AndroidResources
isAapt2
? dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_COMPILED_SYMBOLS)
: null)
- .build(resources, manifest);
+ .build(dataContext, resources, manifest);
}
public static ParsedAndroidResources of(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java b/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java
index cbb1034924..a9d4267978 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ProcessedAndroidData.java
@@ -95,6 +95,7 @@ public class ProcessedAndroidData {
.setFeatureOf(featureOf)
.setFeatureAfter(featureAfter);
return buildActionForBinary(
+ dataContext,
errorConsumer,
builder,
manifest,
@@ -121,6 +122,7 @@ public class ProcessedAndroidData {
.setApkOut(apkOut);
return buildActionForBinary(
+ dataContext,
ruleContext,
builder,
manifest,
@@ -134,6 +136,7 @@ public class ProcessedAndroidData {
}
private static ProcessedAndroidData buildActionForBinary(
+ AndroidDataContext dataContext,
RuleErrorConsumer errorConsumer,
AndroidResourcesProcessorBuilder builder,
StampedAndroidManifest manifest,
@@ -159,7 +162,7 @@ public class ProcessedAndroidData {
.setCrunchPng(crunchPng)
.withResourceDependencies(resourceDeps)
.withAssetDependencies(assetDeps)
- .build(resources, assets, manifest);
+ .build(dataContext, resources, assets, manifest);
}
/** Processes Android data (assets, resources, and manifest) for android_local_test targets. */
@@ -186,7 +189,7 @@ public class ProcessedAndroidData {
.setCrunchPng(false)
.withResourceDependencies(resourceDeps)
.withAssetDependencies(assetDeps)
- .build(resources, assets, manifest);
+ .build(dataContext, resources, assets, manifest);
}
/** Processes Android data (assets, resources, and manifest) for android_test targets. */
@@ -213,7 +216,7 @@ public class ProcessedAndroidData {
.withResourceDependencies(resourceDeps)
.withAssetDependencies(assetDeps);
- return builder.build(resources, assets, manifest);
+ return builder.build(dataContext, resources, assets, manifest);
}
/**
@@ -249,7 +252,7 @@ public class ProcessedAndroidData {
StampedAndroidManifest manifest,
String proguardPrefix,
Map<String, String> manifestValues) {
- return new AndroidResourcesProcessorBuilder(dataContext.getRuleContext())
+ return new AndroidResourcesProcessorBuilder()
// Settings
.setDebug(dataContext.useDebug())
.setJavaPackage(manifest.getPackage())
@@ -321,12 +324,12 @@ public class ProcessedAndroidData {
*/
public ResourceApk generateRClass(AndroidDataContext dataContext, AndroidAaptVersion aaptVersion)
throws InterruptedException {
- return new RClassGeneratorActionBuilder(dataContext.getRuleContext())
+ return new RClassGeneratorActionBuilder()
.targetAaptVersion(aaptVersion)
.withDependencies(resourceDeps)
.setClassJarOut(
dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_RESOURCES_CLASS_JAR))
- .build(this);
+ .build(dataContext, this);
}
/**
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/RClassGeneratorActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/RClassGeneratorActionBuilder.java
index 849881297c..c4e33f1eee 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/RClassGeneratorActionBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/RClassGeneratorActionBuilder.java
@@ -13,21 +13,9 @@
// limitations under the License.
package com.google.devtools.build.lib.rules.android;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
-import com.google.devtools.build.lib.actions.ParamFileInfo;
-import com.google.devtools.build.lib.actions.ParameterFile.ParameterFileType;
-import com.google.devtools.build.lib.analysis.RuleContext;
-import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.Builder;
-import com.google.devtools.build.lib.analysis.actions.CustomCommandLine.VectorArg;
-import com.google.devtools.build.lib.analysis.actions.SpawnAction;
-import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
-import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.android.AndroidConfiguration.AndroidAaptVersion;
import com.google.devtools.build.lib.rules.android.AndroidDataConverter.JoinerType;
-import java.util.ArrayList;
-import java.util.List;
import java.util.function.Function;
/** Builds up the spawn action for $android_rclass_generator. */
@@ -42,18 +30,12 @@ public class RClassGeneratorActionBuilder {
.with(chooseDepsToArg(AndroidAaptVersion.AAPT2))
.build();
- private final RuleContext ruleContext;
private ResourceDependencies dependencies;
private Artifact classJarOut;
private AndroidAaptVersion version;
- /** @param ruleContext The RuleContext that is used to create a SpawnAction.Builder. */
- public RClassGeneratorActionBuilder(RuleContext ruleContext) {
- this.ruleContext = ruleContext;
- }
-
public RClassGeneratorActionBuilder withDependencies(ResourceDependencies resourceDeps) {
this.dependencies = resourceDeps;
return this;
@@ -69,72 +51,43 @@ public class RClassGeneratorActionBuilder {
return this;
}
- public ResourceContainer build(ResourceContainer primary) {
- build(primary.getRTxt(), ProcessedAndroidManifest.from(primary));
+ public ResourceContainer build(AndroidDataContext dataContext, ResourceContainer primary) {
+ build(dataContext, primary.getRTxt(), ProcessedAndroidManifest.from(primary));
return primary.toBuilder().setJavaClassJar(classJarOut).build();
}
- public ResourceApk build(ProcessedAndroidData data) {
- build(data.getRTxt(), data.getManifest());
+ public ResourceApk build(AndroidDataContext dataContext, ProcessedAndroidData data) {
+ build(dataContext, data.getRTxt(), data.getManifest());
return data.withValidatedResources(classJarOut);
}
- private void build(Artifact rTxt, ProcessedAndroidManifest manifest) {
- Builder builder = new Builder();
-
- // Set the busybox tool.
- builder.add("--tool").add("GENERATE_BINARY_R").add("--");
-
- NestedSetBuilder<Artifact> inputs = NestedSetBuilder.naiveLinkOrder();
- inputs.addAll(
- ruleContext
- .getExecutablePrerequisite("$android_resources_busybox", Mode.HOST)
- .getRunfilesSupport()
- .getRunfilesArtifacts());
-
- List<Artifact> outs = new ArrayList<>();
- builder.addExecPath("--primaryRTxt", rTxt);
- inputs.add(rTxt);
- builder.addExecPath("--primaryManifest", manifest.getManifest());
- inputs.add(manifest.getManifest());
- if (!Strings.isNullOrEmpty(manifest.getPackage())) {
- builder.add("--packageForR", manifest.getPackage());
+ private void build(
+ AndroidDataContext dataContext, Artifact rTxt, ProcessedAndroidManifest manifest) {
+ BusyBoxActionBuilder builder =
+ BusyBoxActionBuilder.create(dataContext, "GENERATE_BINARY_R")
+ .addInput("--primaryRTxt", rTxt)
+ .addInput("--primaryManifest", manifest.getManifest())
+ .maybeAddFlag("--packageForR", manifest.getPackage());
+
+ if (dependencies != null && !dependencies.getResourceContainers().isEmpty()) {
+ builder
+ .addTransitiveFlagForEach(
+ "--library",
+ dependencies.getResourceContainers(),
+ version == AndroidAaptVersion.AAPT2 ? AAPT2_CONVERTER : AAPT_CONVERTER)
+ .addTransitiveInputValues(
+ version == AndroidAaptVersion.AAPT2
+ ? dependencies.getTransitiveAapt2RTxt()
+ : dependencies.getTransitiveRTxt())
+ .addTransitiveInputValues(dependencies.getTransitiveManifests());
}
- if (dependencies != null) {
- if (!dependencies.getResourceContainers().isEmpty()) {
- builder.addAll(
- VectorArg.addBefore("--library")
- .each(dependencies.getResourceContainers())
- .mapped(version == AndroidAaptVersion.AAPT2 ? AAPT2_CONVERTER : AAPT_CONVERTER));
- if (version == AndroidAaptVersion.AAPT2) {
- inputs.addTransitive(dependencies.getTransitiveAapt2RTxt());
- } else {
- inputs.addTransitive(dependencies.getTransitiveRTxt());
- }
- inputs.addTransitive(dependencies.getTransitiveManifests());
- }
- }
- builder.addExecPath("--classJarOutput", classJarOut);
- outs.add(classJarOut);
- builder.addLabel("--targetLabel", ruleContext.getLabel());
-
- // Create the spawn action.
- SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder();
-
- ruleContext.registerAction(
- spawnActionBuilder
- .useDefaultShellEnvironment()
- .addTransitiveInputs(inputs.build())
- .addOutputs(ImmutableList.<Artifact>copyOf(outs))
- .addCommandLine(
- builder.build(), ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED).build())
- .setExecutable(
- ruleContext.getExecutablePrerequisite("$android_resources_busybox", Mode.HOST))
- .setProgressMessage("Generating R Classes: %s", ruleContext.getLabel())
- .setMnemonic("RClassGenerator")
- .build(ruleContext));
+
+ builder
+ .addOutput("--classJarOutput", classJarOut)
+ .addLabelFlag("--targetLabel")
+ .buildAndRegister("Generating R Classes", "RClassGenerator");
}
private static Function<ValidatedAndroidData, String> chooseDepsToArg(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java
index 46048e90a1..99d545d097 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ResourceApk.java
@@ -304,7 +304,7 @@ public final class ResourceApk {
StampedAndroidManifest manifest)
throws InterruptedException {
- return new AndroidResourcesProcessorBuilder(dataContext.getRuleContext())
+ return new AndroidResourcesProcessorBuilder()
.setLibrary(true)
.setRTxtOut(dataContext.createOutputArtifact(AndroidRuleClasses.ANDROID_R_TXT))
.setManifestOut(
@@ -316,6 +316,6 @@ public final class ResourceApk {
.withAssetDependencies(assetDeps)
.setDebug(dataContext.useDebug())
.setThrowOnResourceConflict(dataContext.getAndroidConfig().throwOnResourceConflict())
- .buildWithoutLocalResources(manifest);
+ .buildWithoutLocalResources(dataContext, manifest);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java b/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java
index 7abd103de8..b84803e4f0 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/ValidatedAndroidResources.java
@@ -56,7 +56,7 @@ public class ValidatedAndroidResources extends MergedAndroidResources
AndroidDataContext dataContext, MergedAndroidResources merged, AndroidAaptVersion aaptVersion)
throws InterruptedException {
AndroidResourceValidatorActionBuilder builder =
- new AndroidResourceValidatorActionBuilder(dataContext.getRuleContext())
+ new AndroidResourceValidatorActionBuilder()
.setJavaPackage(merged.getJavaPackage())
.setDebug(dataContext.useDebug())
.setMergedResources(merged.getMergedResources())
@@ -82,7 +82,7 @@ public class ValidatedAndroidResources extends MergedAndroidResources
AndroidRuleClasses.ANDROID_RESOURCES_AAPT2_LIBRARY_APK));
}
- return builder.build(dataContext.getRuleContext(), merged);
+ return builder.build(dataContext, merged);
}
static ValidatedAndroidResources of(