diff options
Diffstat (limited to 'src')
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 = [ |