aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidBinary.java29
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/android/AndroidRuleClasses.java7
-rw-r--r--src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java20
3 files changed, 47 insertions, 9 deletions
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 81db9ac7cf..e0a057fe97 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
@@ -121,6 +121,15 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
JavaSemantics javaSemantics,
AndroidSemantics androidSemantics,
List<String> depsAttributes) throws InterruptedException {
+
+ if (getMultidexMode(ruleContext) != MultidexMode.LEGACY
+ && ruleContext.attributes().isAttributeValueExplicitlySpecified(
+ "main_dex_proguard_specs")) {
+ ruleContext.attributeError("main_dex_proguard_specs", "The 'main_dex_proguard_specs' "
+ + "attribute is only allowed if 'multidex' is set to 'legacy'");
+ return null;
+ }
+
// TODO(bazel-team): Find a way to simplify this code.
// treeKeys() means that the resulting map sorts the entries by key, which is necessary to
// ensure determinism.
@@ -1005,7 +1014,7 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
// Process the input jar through Proguard into an intermediate, streamlined jar.
Artifact strippedJar = AndroidBinary.getDxArtifact(ruleContext, "main_dex_intermediate.jar");
AndroidSdkProvider sdk = AndroidSdkProvider.fromRuleContext(ruleContext);
- ruleContext.registerAction(new SpawnAction.Builder()
+ SpawnAction.Builder streamlinedBuilder = new SpawnAction.Builder()
.addOutput(strippedJar)
.setExecutable(sdk.getProguard())
.setProgressMessage("Generating streamlined input jar for main dex classes list")
@@ -1021,10 +1030,20 @@ public abstract class AndroidBinary implements RuleConfiguredTargetFactory {
.addArgument("-forceprocessing")
.addArgument("-dontoptimize")
.addArgument("-dontobfuscate")
- .addArgument("-dontpreverify")
- .addArgument("-include")
- .addInputArgument(sdk.getMainDexClasses())
- .build(ruleContext));
+ .addArgument("-dontpreverify");
+
+ List<Artifact> specs = ruleContext.getPrerequisiteArtifacts(
+ "main_dex_proguard_specs", Mode.TARGET).list();
+ if (specs.isEmpty()) {
+ specs = ImmutableList.of(sdk.getMainDexClasses());
+ }
+
+ for (Artifact spec : specs) {
+ streamlinedBuilder.addArgument("-include");
+ streamlinedBuilder.addInputArgument(spec);
+ }
+
+ ruleContext.registerAction(streamlinedBuilder.build(ruleContext));
// Create the main dex classes list.
Artifact mainDexList = AndroidBinary.getDxArtifact(ruleContext, "main_dex_list.txt");
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 2b80cb1b7a..bbab1a54ab 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
@@ -650,6 +650,13 @@ com/google/common/base/Objects.class
Must be used with <code>multidex="manual_main_dex"</code>.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
.add(attr("main_dex_list", LABEL).legacyAllowAnyFileType())
+ /* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(main_dex_proguard_specs) -->
+ Files to be used as the Proguard specifications to determine classes that must be kept in
+ the main dex.
+ ${SYNOPSIS}
+ Only allowed if the <code>multidex</code> attribute is set to <code>legacy</code>.
+ <!-- #END_BLAZE_RULE.ATTRIBUTE --> */
+ .add(attr("main_dex_proguard_specs", LABEL_LIST).legacyAllowAnyFileType())
/* <!-- #BLAZE_RULE($android_binary_base).ATTRIBUTE(proguard_specs) -->
Files to be used as Proguard specification.
${SYNOPSIS}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
index 3d9b5d3509..ff22af1993 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
@@ -749,7 +749,7 @@ public abstract class BuildViewTestCase extends FoundationTestCase {
String... lines) throws Exception {
eventCollector.clear();
ConfiguredTarget target = scratchConfiguredTarget(packageName, ruleName,
- lines);
+ lines);
assertFalse(
"Rule '" + "//" + packageName + ":" + ruleName + "' did contain an error",
view.hasErrors(target));
@@ -1411,7 +1411,7 @@ public abstract class BuildViewTestCase extends FoundationTestCase {
protected String getErrorMsgWrongAttributeValue(String value, String... expected) {
return String.format("has to be one of %s instead of '%s'",
- StringUtil.joinEnglishList(ImmutableSet.copyOf(expected), "or", "'"), value);
+ StringUtil.joinEnglishList(ImmutableSet.copyOf(expected), "or", "'"), value);
}
protected String getErrorMsgMandatoryProviderMissing(String offendingRule, String providerName) {
@@ -1535,9 +1535,21 @@ public abstract class BuildViewTestCase extends FoundationTestCase {
*/
protected Artifact artifactByPath(Iterable<Artifact> artifacts, String... suffixes) {
Artifact artifact = getFirstArtifactEndingWith(artifacts, suffixes[0]);
-
+ Action action = null;
for (int i = 1; i < suffixes.length; i++) {
- artifacts = getGeneratingAction(artifact).getInputs();
+ if (artifact == null) {
+ if (action == null) {
+ throw new IllegalStateException("No suffix " + suffixes[0] + " among artifacts: "
+ + ActionsTestUtil.baseArtifactNames(artifacts));
+ } else {
+ throw new IllegalStateException("No suffix " + suffixes[i]
+ + " among inputs of action " + action.describe() + ": "
+ + ActionsTestUtil.baseArtifactNames(artifacts));
+ }
+ }
+
+ action = getGeneratingAction(artifact);
+ artifacts = action.getInputs();
artifact = getFirstArtifactEndingWith(artifacts, suffixes[i]);
}