aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java171
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourcesProcessorBuilder.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java3
-rw-r--r--src/test/shell/bazel/android/BUILD1
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java10
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java109
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/AndroidResourceValidatorAction.java181
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/BUILD8
-rw-r--r--src/tools/android/java/com/google/devtools/build/android/BUILD.tools8
9 files changed, 451 insertions, 42 deletions
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
new file mode 100644
index 0000000000..3305bcf361
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceValidatorActionBuilder.java
@@ -0,0 +1,171 @@
+// Copyright 2016 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.lib.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.analysis.RuleConfiguredTarget.Mode;
+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.collect.nestedset.NestedSetBuilder;
+import com.google.devtools.build.lib.rules.android.AndroidResourcesProvider.ResourceContainer;
+import com.google.devtools.build.lib.rules.android.AndroidResourcesProvider.ResourceType;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Builder for creating $android_resource_validator action. This action validates merged resources
+ * of an android_library via aapt, and writes out an R.txt file (mostly to serve as a dependency for
+ * the android_binary -- otherwise the merger step could have generated the R.txt).
+ *
+ * <p>This is split from merging, so that it can happen off of the compilation critical path.
+ */
+class AndroidResourceValidatorActionBuilder {
+
+ private final RuleContext ruleContext;
+ private final AndroidSdkProvider sdk;
+
+ // Inputs
+ private ResourceContainer primary;
+ private Artifact mergedResources;
+
+ // Outputs
+ private Artifact rTxtOut;
+ private Artifact sourceJarOut;
+
+ // Flags
+ private String customJavaPackage;
+ private boolean debug;
+
+ /** @param ruleContext The RuleContext that was used to create the SpawnAction.Builder. */
+ public AndroidResourceValidatorActionBuilder(RuleContext ruleContext) {
+ this.ruleContext = ruleContext;
+ this.sdk = AndroidSdkProvider.fromRuleContext(ruleContext);
+ }
+
+ /** The primary resource container. We mostly propagate its values, but update the R.txt. */
+ public AndroidResourceValidatorActionBuilder withPrimary(ResourceContainer primary) {
+ this.primary = primary;
+ return this;
+ }
+
+ public AndroidResourceValidatorActionBuilder setMergedResources(Artifact mergedResources) {
+ this.mergedResources = mergedResources;
+ return this;
+ }
+
+ public AndroidResourceValidatorActionBuilder setJavaPackage(String customJavaPackage) {
+ this.customJavaPackage = customJavaPackage;
+ return this;
+ }
+
+ public AndroidResourceValidatorActionBuilder setDebug(boolean debug) {
+ this.debug = debug;
+ return this;
+ }
+
+ public AndroidResourceValidatorActionBuilder setRTxtOut(Artifact rTxtOut) {
+ this.rTxtOut = rTxtOut;
+ return this;
+ }
+
+ public AndroidResourceValidatorActionBuilder setSourceJarOut(Artifact sourceJarOut) {
+ this.sourceJarOut = sourceJarOut;
+ return this;
+ }
+
+ public ResourceContainer build(ActionConstructionContext context) {
+ CustomCommandLine.Builder builder = new CustomCommandLine.Builder();
+
+ if (!Strings.isNullOrEmpty(sdk.getBuildToolsVersion())) {
+ builder.add("--buildToolsVersion").add(sdk.getBuildToolsVersion());
+ }
+
+ builder.addExecPath("--aapt", sdk.getAapt().getExecutable());
+
+ // Use a FluentIterable to avoid flattening the NestedSets
+ NestedSetBuilder<Artifact> inputs = NestedSetBuilder.naiveLinkOrder();
+ inputs.addAll(
+ ruleContext
+ .getExecutablePrerequisite("$android_resource_validator", Mode.HOST)
+ .getRunfilesSupport()
+ .getRunfilesArtifactsWithoutMiddlemen());
+
+ builder.addExecPath("--annotationJar", sdk.getAnnotationsJar());
+ inputs.add(sdk.getAnnotationsJar());
+
+ 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").add(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);
+
+ SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder();
+ // Create the spawn action.
+ ruleContext.registerAction(
+ spawnActionBuilder
+ .addTool(sdk.getAapt())
+ .addTransitiveInputs(inputs.build())
+ .addOutputs(ImmutableList.copyOf(outs))
+ .setCommandLine(builder.build())
+ .setExecutable(
+ ruleContext.getExecutablePrerequisite("$android_resource_validator", Mode.HOST))
+ .setProgressMessage("Validating Android resources for " + ruleContext.getLabel())
+ .setMnemonic("AndroidResourceValidator")
+ .build(context));
+
+ // Return the full set of validated transitive dependencies.
+ return new ResourceContainer(
+ primary.getLabel(),
+ primary.getJavaPackage(),
+ primary.getRenameManifestPackage(),
+ primary.getConstantsInlined(),
+ primary.getApk(),
+ primary.getManifest(),
+ sourceJarOut,
+ primary.getArtifacts(ResourceType.ASSETS),
+ primary.getArtifacts(ResourceType.RESOURCES),
+ primary.getRoots(ResourceType.ASSETS),
+ primary.getRoots(ResourceType.RESOURCES),
+ primary.isManifestExported(),
+ rTxtOut,
+ primary.getSymbolsTxt());
+ }
+}
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 789c3dcacf..be7ae3047b 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
@@ -289,7 +289,7 @@ public class AndroidResourcesProcessorBuilder {
if (!Strings.isNullOrEmpty(customJavaPackage)) {
// Sets an alternative java package for the generated R.java
- // this is allows android rules to generate resources outside of the java{,tests} tree.
+ // this allows android rules to generate resources outside of the java{,tests} tree.
builder.add("--packageForR").add(customJavaPackage);
}
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
index 6e14804023..7582f81564 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java
@@ -172,6 +172,7 @@ public final class AndroidRuleClasses {
public static final String DEFAULT_RESOURCE_MERGER = "//tools/android:resource_merger";
public static final String DEFAULT_RESOURCE_PARSER = "//tools/android:resource_parser";
public static final String DEFAULT_RESOURCE_SHRINKER = "//tools/android:resource_shrinker";
+ public static final String DEFAULT_RESOURCE_VALIDATOR = "//tools/android:resource_validator";
public static final String DEFAULT_SDK = "//tools/android:sdk";
/**
@@ -413,6 +414,8 @@ public final class AndroidRuleClasses {
env.getToolsLabel(DEFAULT_RESOURCE_MERGER)))
.add(attr("$android_resource_parser", LABEL).cfg(HOST).exec().value(
env.getToolsLabel(DEFAULT_RESOURCE_PARSER)))
+ .add(attr("$android_resource_validator", LABEL).cfg(HOST).exec().value(
+ env.getToolsLabel(DEFAULT_RESOURCE_VALIDATOR)))
.add(attr("$android_resource_shrinker", LABEL).cfg(HOST).exec().value(
env.getToolsLabel(DEFAULT_RESOURCE_SHRINKER)))
.build();
diff --git a/src/test/shell/bazel/android/BUILD b/src/test/shell/bazel/android/BUILD
index 3861a9e1f5..0bd8a35e72 100644
--- a/src/test/shell/bazel/android/BUILD
+++ b/src/test/shell/bazel/android/BUILD
@@ -20,6 +20,7 @@ sh_test(
"//src/tools/android/java/com/google/devtools/build/android:AndroidResourceMergingAction_deploy.jar",
"//src/tools/android/java/com/google/devtools/build/android:AndroidResourceParsingAction_deploy.jar",
"//src/tools/android/java/com/google/devtools/build/android:AndroidResourceProcessingAction_deploy.jar",
+ "//src/tools/android/java/com/google/devtools/build/android:AndroidResourceValidatorAction_deploy.jar",
"//src/tools/android/java/com/google/devtools/build/android:RClassGeneratorAction_deploy.jar",
"//src/tools/android/java/com/google/devtools/build/android:ResourceShrinkerAction_deploy.jar",
"//src/tools/android/java/com/google/devtools/build/android/incrementaldeployment:srcs",
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java
index cc78940086..322180b1a2 100644
--- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java
+++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessingAction.java
@@ -13,8 +13,6 @@
// limitations under the License.
package com.google.devtools.build.android;
-import static java.nio.charset.StandardCharsets.UTF_8;
-
import com.android.builder.core.VariantConfiguration;
import com.android.builder.core.VariantConfiguration.Type;
import com.android.ide.common.internal.AaptCruncher;
@@ -38,7 +36,6 @@ import com.google.devtools.common.options.OptionsBase;
import com.google.devtools.common.options.OptionsParser;
import com.google.devtools.common.options.TriState;
import java.io.IOException;
-import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -283,12 +280,7 @@ public class AndroidResourceProcessingAction {
}
if (options.packageType == Type.LIBRARY) {
- Files.createDirectories(dummyManifest.getParent());
- Files.write(dummyManifest, String.format(
- "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
- + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\""
- + " package=\"%s\">"
- + "</manifest>", options.packageForR).getBytes(UTF_8));
+ resourceProcessor.writeDummyManifestForAapt(dummyManifest, options.packageForR);
processedData = new MergedAndroidData(
processedData.getResourceDir(),
processedData.getAssetDir(),
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java
index 6e2f340623..53b7f8a9d6 100644
--- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java
+++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceProcessor.java
@@ -418,12 +418,12 @@ public class AndroidResourceProcessor {
Collection<String> splits,
MergedAndroidData primaryData,
List<DependencyAndroidData> dependencyData,
- Path sourceOut,
- Path packageOut,
- Path proguardOut,
- Path mainDexProguardOut,
- Path publicResourcesOut,
- Path dataBindingInfoOut)
+ @Nullable Path sourceOut,
+ @Nullable Path packageOut,
+ @Nullable Path proguardOut,
+ @Nullable Path mainDexProguardOut,
+ @Nullable Path publicResourcesOut,
+ @Nullable Path dataBindingInfoOut)
throws IOException, InterruptedException, LoggedErrorException, UnrecognizedSplitsException {
Path androidManifest = primaryData.getManifest();
final Path resourceDir = processDataBindings(primaryData.getResourceDir(), dataBindingInfoOut,
@@ -433,7 +433,69 @@ public class AndroidResourceProcessor {
if (publicResourcesOut != null) {
prepareOutputPath(publicResourcesOut.getParent());
}
+ runAapt(aapt,
+ androidJar,
+ buildToolsVersion,
+ variantType,
+ debug,
+ customPackageForR,
+ aaptOptions,
+ resourceConfigs,
+ splits,
+ androidManifest,
+ resourceDir,
+ assetsDir,
+ sourceOut,
+ packageOut,
+ proguardOut,
+ mainDexProguardOut,
+ publicResourcesOut);
+ // The R needs to be created for each library in the dependencies,
+ // but only if the current project is not a library.
+ if (sourceOut != null && variantType != VariantConfiguration.Type.LIBRARY) {
+ writeDependencyPackageRJavaFiles(
+ dependencyData, customPackageForR, androidManifest, sourceOut);
+ }
+ // Reset the output date stamps.
+ if (proguardOut != null) {
+ Files.setLastModifiedTime(proguardOut, FileTime.fromMillis(0L));
+ }
+ if (mainDexProguardOut != null) {
+ Files.setLastModifiedTime(mainDexProguardOut, FileTime.fromMillis(0L));
+ }
+ if (packageOut != null) {
+ Files.setLastModifiedTime(packageOut, FileTime.fromMillis(0L));
+ if (!splits.isEmpty()) {
+ Iterable<Path> splitFilenames = findAndRenameSplitPackages(packageOut, splits);
+ for (Path splitFilename : splitFilenames) {
+ Files.setLastModifiedTime(splitFilename, FileTime.fromMillis(0L));
+ }
+ }
+ }
+ if (publicResourcesOut != null && Files.exists(publicResourcesOut)) {
+ Files.setLastModifiedTime(publicResourcesOut, FileTime.fromMillis(0L));
+ }
+ }
+ public void runAapt(
+ Path aapt,
+ Path androidJar,
+ @Nullable FullRevision buildToolsVersion,
+ VariantConfiguration.Type variantType,
+ boolean debug,
+ String customPackageForR,
+ AaptOptions aaptOptions,
+ Collection<String> resourceConfigs,
+ Collection<String> splits,
+ Path androidManifest,
+ Path resourceDir,
+ Path assetsDir,
+ Path sourceOut,
+ @Nullable Path packageOut,
+ @Nullable Path proguardOut,
+ @Nullable Path mainDexProguardOut,
+ @Nullable Path publicResourcesOut)
+ throws InterruptedException, LoggedErrorException, IOException {
AaptCommandBuilder commandBuilder =
new AaptCommandBuilder(aapt)
.forBuildToolsVersion(buildToolsVersion)
@@ -485,32 +547,6 @@ public class AndroidResourceProcessor {
throw new LoggedErrorException(
e.getCmdLineError(), getOutputWithSourceContext(aapt, e.getOutput()), e.getCmdLine());
}
-
- // The R needs to be created for each library in the dependencies,
- // but only if the current project is not a library.
- if (sourceOut != null && variantType != VariantConfiguration.Type.LIBRARY) {
- writeDependencyPackageRJavaFiles(
- dependencyData, customPackageForR, androidManifest, sourceOut);
- }
- // Reset the output date stamps.
- if (proguardOut != null) {
- Files.setLastModifiedTime(proguardOut, FileTime.fromMillis(0L));
- }
- if (mainDexProguardOut != null) {
- Files.setLastModifiedTime(mainDexProguardOut, FileTime.fromMillis(0L));
- }
- if (packageOut != null) {
- Files.setLastModifiedTime(packageOut, FileTime.fromMillis(0L));
- if (!splits.isEmpty()) {
- Iterable<Path> splitFilenames = findAndRenameSplitPackages(packageOut, splits);
- for (Path splitFilename : splitFilenames) {
- Files.setLastModifiedTime(splitFilename, FileTime.fromMillis(0L));
- }
- }
- }
- if (publicResourcesOut != null && Files.exists(publicResourcesOut)) {
- Files.setLastModifiedTime(publicResourcesOut, FileTime.fromMillis(0L));
- }
}
/** Adds 10 lines of source to each syntax error. Very useful for debugging. */
@@ -956,6 +992,15 @@ public class AndroidResourceProcessor {
Files.write(manifestOut, xmlDocument.prettyPrint().getBytes(UTF_8));
}
+ public void writeDummyManifestForAapt(Path dummyManifest, String packageForR) throws IOException {
+ Files.createDirectories(dummyManifest.getParent());
+ Files.write(dummyManifest, String.format(
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ + "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\""
+ + " package=\"%s\">"
+ + "</manifest>", packageForR).getBytes(UTF_8));
+ }
+
/**
* Overwrite the package attribute of {@code <manifest>} in an AndroidManifest.xml file.
*
diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceValidatorAction.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceValidatorAction.java
new file mode 100644
index 0000000000..df8c9489a8
--- /dev/null
+++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceValidatorAction.java
@@ -0,0 +1,181 @@
+// Copyright 2015 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+package com.google.devtools.build.android;
+
+import com.android.builder.core.VariantConfiguration;
+import com.android.builder.core.VariantConfiguration.Type;
+import com.android.utils.StdLogger;
+import com.google.common.base.Preconditions;
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.android.AndroidResourceProcessor.AaptConfigOptions;
+import com.google.devtools.build.android.AndroidResourceProcessor.FlagAaptOptions;
+import com.google.devtools.build.android.Converters.ExistingPathConverter;
+import com.google.devtools.build.android.Converters.PathConverter;
+import com.google.devtools.common.options.Option;
+import com.google.devtools.common.options.OptionsBase;
+import com.google.devtools.common.options.OptionsParser;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+/**
+ * Validates merged resources for an android_library via AAPT. Takes as input, the merged resources
+ * from {@link AndroidResourceMergingAction}.
+ */
+public class AndroidResourceValidatorAction {
+
+ private static final StdLogger stdLogger = new StdLogger(StdLogger.Level.WARNING);
+
+ private static final Logger logger =
+ Logger.getLogger(AndroidResourceValidatorAction.class.getName());
+
+ /** Flag specifications for this action. */
+ public static final class Options extends OptionsBase {
+
+ @Option(
+ name = "mergedResources",
+ defaultValue = "null",
+ converter = ExistingPathConverter.class,
+ category = "input",
+ help = "Path to the read merged resources archive."
+ )
+ public Path mergedResources;
+
+ @Option(
+ name = "manifest",
+ defaultValue = "null",
+ converter = ExistingPathConverter.class,
+ category = "input",
+ help = "Path for the AndroidManifest.xml."
+ )
+ public Path manifest;
+
+ @Option(
+ name = "packageForR",
+ defaultValue = "null",
+ category = "config",
+ help = "Custom java package to generate the R symbols files."
+ )
+ public String packageForR;
+
+ @Option(
+ name = "srcJarOutput",
+ defaultValue = "null",
+ converter = PathConverter.class,
+ category = "output",
+ help = "Path for the generated java source jar."
+ )
+ public Path srcJarOutput;
+
+ @Option(
+ name = "rOutput",
+ defaultValue = "null",
+ converter = PathConverter.class,
+ category = "output",
+ help = "Path to where the R.txt should be written."
+ )
+ public Path rOutput;
+ }
+
+ public static void main(String[] args) throws Exception {
+ final Stopwatch timer = Stopwatch.createStarted();
+ OptionsParser optionsParser =
+ OptionsParser.newOptionsParser(Options.class, AaptConfigOptions.class);
+ optionsParser.parseAndExitUponError(args);
+ AaptConfigOptions aaptConfigOptions = optionsParser.getOptions(AaptConfigOptions.class);
+ Options options = optionsParser.getOptions(Options.class);
+
+ final AndroidResourceProcessor resourceProcessor = new AndroidResourceProcessor(stdLogger);
+ VariantConfiguration.Type packageType = Type.LIBRARY;
+
+ Preconditions.checkNotNull(options.rOutput);
+ Preconditions.checkNotNull(options.srcJarOutput);
+ try (ScopedTemporaryDirectory scopedTmp =
+ new ScopedTemporaryDirectory("resource_validator_tmp")) {
+ Path tmp = scopedTmp.getPath();
+ Path expandedOut = tmp.resolve("tmp-expanded");
+ Path resources = expandedOut.resolve("res");
+ Path assets = expandedOut.resolve("assets");
+ Path generatedSources = tmp.resolve("generated_resources");
+ Path dummyManifest = tmp.resolve("manifest-aapt-dummy/AndroidManifest.xml");
+
+ unpackZip(options.mergedResources, expandedOut);
+ logger.fine(String.format("unpacked zip at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
+
+ // We need to make the manifest aapt safe (w.r.t., placeholders). For now, just stub it out.
+ resourceProcessor.writeDummyManifestForAapt(dummyManifest, options.packageForR);
+
+ resourceProcessor.runAapt(
+ aaptConfigOptions.aapt,
+ aaptConfigOptions.androidJar,
+ aaptConfigOptions.buildToolsVersion,
+ packageType,
+ aaptConfigOptions.debug,
+ options.packageForR,
+ new FlagAaptOptions(aaptConfigOptions),
+ aaptConfigOptions.resourceConfigs,
+ ImmutableList.<String>of(),
+ dummyManifest,
+ resources,
+ assets,
+ generatedSources,
+ null, /* packageOut */
+ null, /* proguardOut */
+ null, /* mainDexProguardOut */
+ null /* publicResourcesOut */);
+ logger.fine(String.format("aapt finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
+
+ resourceProcessor.copyRToOutput(
+ generatedSources, options.rOutput, VariantConfiguration.Type.LIBRARY == packageType);
+
+ resourceProcessor.createSrcJar(
+ generatedSources, options.srcJarOutput, VariantConfiguration.Type.LIBRARY == packageType);
+ } catch (Exception e) {
+ logger.log(java.util.logging.Level.SEVERE, "Unexpected", e);
+ throw e;
+ } finally {
+ resourceProcessor.shutdown();
+ }
+ logger.fine(String.format("Resources merged in %sms", timer.elapsed(TimeUnit.MILLISECONDS)));
+ }
+
+ private static void unpackZip(Path mergedResources, Path expandedOut) throws IOException {
+ byte[] buffer = new byte[4096];
+ try (ZipInputStream zis =
+ new ZipInputStream(new BufferedInputStream(Files.newInputStream(mergedResources)))) {
+ ZipEntry z = zis.getNextEntry();
+ while (z != null) {
+ String entryName = z.getName();
+ Path outputPath = expandedOut.resolve(entryName);
+ Files.createDirectories(outputPath.getParent());
+ try (OutputStream out = new BufferedOutputStream(Files.newOutputStream(outputPath))) {
+ int count = zis.read(buffer);
+ while (count != -1) {
+ out.write(buffer, 0, count);
+ count = zis.read(buffer);
+ }
+ }
+ z = zis.getNextEntry();
+ }
+ }
+ }
+}
diff --git a/src/tools/android/java/com/google/devtools/build/android/BUILD b/src/tools/android/java/com/google/devtools/build/android/BUILD
index 6dc6b4b2ce..d8df5b4103 100644
--- a/src/tools/android/java/com/google/devtools/build/android/BUILD
+++ b/src/tools/android/java/com/google/devtools/build/android/BUILD
@@ -50,6 +50,14 @@ java_binary(
)
java_binary(
+ name = "AndroidResourceValidatorAction",
+ main_class = "com.google.devtools.build.android.AndroidResourceValidatorAction",
+ runtime_deps = [
+ ":android_builder_lib",
+ ],
+)
+
+java_binary(
name = "ManifestMergerAction",
main_class = "com.google.devtools.build.android.ManifestMergerAction",
runtime_deps = [
diff --git a/src/tools/android/java/com/google/devtools/build/android/BUILD.tools b/src/tools/android/java/com/google/devtools/build/android/BUILD.tools
index 3a08124f58..444bf4f699 100644
--- a/src/tools/android/java/com/google/devtools/build/android/BUILD.tools
+++ b/src/tools/android/java/com/google/devtools/build/android/BUILD.tools
@@ -38,6 +38,14 @@ java_binary(
)
java_binary(
+ name = "AndroidResourceValidatorAction",
+ main_class = "com.google.devtools.build.android.AndroidResourceValidatorAction",
+ runtime_deps = [
+ ":classes",
+ ],
+)
+
+java_binary(
name = "ManifestMergerAction",
main_class = "com.google.devtools.build.android.ManifestMergerAction",
runtime_deps = [