diff options
Diffstat (limited to 'src')
11 files changed, 141 insertions, 15 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidResourceMergingActionBuilder.java index 48c5cf989e..65afc20314 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 @@ -240,7 +240,7 @@ public class AndroidResourceMergingActionBuilder { .build(context)); } - public ResourceContainer build(ActionConstructionContext context) { + public ResourceContainer build(RuleContext context) { CustomCommandLine.Builder parsedMergeBuilder = new CustomCommandLine.Builder().add("--tool").add("MERGE").add("--"); CustomCommandLine.Builder compiledMergeBuilder = @@ -267,6 +267,7 @@ public class AndroidResourceMergingActionBuilder { if (classJarOut != null) { jarAndManifestBuilder.addExecPath("--classJarOutput", classJarOut); + jarAndManifestBuilder.addLabel("--targetLabel", ruleContext.getLabel()); jarAndManifestOutputs.add(classJarOut); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/LibraryRGeneratorActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/LibraryRGeneratorActionBuilder.java index 36851bf144..14dfa203f9 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/LibraryRGeneratorActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/LibraryRGeneratorActionBuilder.java @@ -82,6 +82,7 @@ public class LibraryRGeneratorActionBuilder { } builder.addExecPath("--classJarOutput", rJavaClassJar); + builder.addLabel("--targetLabel", ruleContext.getLabel()); builder.addExecPath("--androidJar", sdk.getAndroidJar()); inputs.add(sdk.getAndroidJar()); 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 178c7e99ac..c4f1559998 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 @@ -113,6 +113,7 @@ public class RClassGeneratorActionBuilder { } builder.addExecPath("--classJarOutput", classJarOut); outs.add(classJarOut); + builder.addLabel("--targetLabel", ruleContext.getLabel()); // Create the spawn action. SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder(); diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java index 5b66d53a58..6617ddc57b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/RobolectricResourceSymbolsActionBuilder.java @@ -118,6 +118,8 @@ public class RobolectricResourceSymbolsActionBuilder { .addTransitive(dependencies.getTransitiveSymbolsBin()); builder.addExecPath("--classJarOutput", classJarOut); + builder.addLabel("--targetLabel", ruleContext.getLabel()); + SpawnAction.Builder spawnActionBuilder = new SpawnAction.Builder(); ParamFileInfo.Builder paramFile = ParamFileInfo.builder(ParameterFileType.SHELL_QUOTED); diff --git a/src/test/java/com/google/devtools/build/android/RClassGeneratorActionTest.java b/src/test/java/com/google/devtools/build/android/RClassGeneratorActionTest.java index 7e1d8741ca..a26c84e269 100644 --- a/src/test/java/com/google/devtools/build/android/RClassGeneratorActionTest.java +++ b/src/test/java/com/google/devtools/build/android/RClassGeneratorActionTest.java @@ -26,6 +26,7 @@ import java.nio.file.Path; import java.time.Instant; import java.util.Collections; import java.util.List; +import java.util.jar.JarInputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.junit.Assert; @@ -120,7 +121,9 @@ public class RClassGeneratorActionTest { "--library", libBarSymbols + "," + libBarManifest, "--classJarOutput", - jarPath.toString()) + jarPath.toString(), + "--targetLabel", + "//foo:foo") .toArray(new String[0])); assertThat(Files.exists(jarPath)).isTrue(); @@ -143,9 +146,14 @@ public class RClassGeneratorActionTest { "com/google/app/R$integer.class", "com/google/app/R$string.class", "com/google/app/R.class", + "META-INF/", "META-INF/MANIFEST.MF"); ZipMtimeAsserter.assertEntries(zipEntries); } + try (JarInputStream jar = new JarInputStream(Files.newInputStream(jarPath))) { + assertThat(jar.getManifest().getMainAttributes().getValue("Target-Label")) + .isEqualTo("//foo:foo"); + } } @Test @@ -189,6 +197,7 @@ public class RClassGeneratorActionTest { "com/google/bar/R$attr.class", "com/google/bar/R$drawable.class", "com/google/bar/R.class", + "META-INF/", "META-INF/MANIFEST.MF"); ZipMtimeAsserter.assertEntries(zipEntries); } @@ -232,6 +241,7 @@ public class RClassGeneratorActionTest { "com/google/app/R$integer.class", "com/google/app/R$string.class", "com/google/app/R.class", + "META-INF/", "META-INF/MANIFEST.MF"); ZipMtimeAsserter.assertEntries(zipEntries); } @@ -249,7 +259,7 @@ public class RClassGeneratorActionTest { try (ZipFile zip = new ZipFile(jarPath.toFile())) { List<? extends ZipEntry> zipEntries = Collections.list(zip.entries()); Iterable<String> entries = getZipFilenames(zipEntries); - assertThat(entries).containsExactly("META-INF/MANIFEST.MF"); + assertThat(entries).containsExactly("META-INF/", "META-INF/MANIFEST.MF"); ZipMtimeAsserter.assertEntries(zipEntries); } } @@ -298,6 +308,7 @@ public class RClassGeneratorActionTest { "com/custom/er/R$integer.class", "com/custom/er/R$string.class", "com/custom/er/R.class", + "META-INF/", "META-INF/MANIFEST.MF"); ZipMtimeAsserter.assertEntries(zipEntries); } @@ -328,7 +339,7 @@ public class RClassGeneratorActionTest { try (ZipFile zip = new ZipFile(jarPath.toFile())) { List<? extends ZipEntry> zipEntries = Collections.list(zip.entries()); Iterable<String> entries = getZipFilenames(zipEntries); - assertThat(entries).containsExactly("META-INF/MANIFEST.MF"); + assertThat(entries).containsExactly("META-INF/", "META-INF/MANIFEST.MF"); ZipMtimeAsserter.assertEntries(zipEntries); } } diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidCompiledResourceMergingAction.java b/src/tools/android/java/com/google/devtools/build/android/AndroidCompiledResourceMergingAction.java index 3fe61a32df..cd50c9fc06 100644 --- a/src/tools/android/java/com/google/devtools/build/android/AndroidCompiledResourceMergingAction.java +++ b/src/tools/android/java/com/google/devtools/build/android/AndroidCompiledResourceMergingAction.java @@ -91,7 +91,8 @@ public class AndroidCompiledResourceMergingAction { executorService); logger.fine(String.format("Merging finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); - AndroidResourceOutputs.createClassJar(generatedSources, options.classJarOutput); + AndroidResourceOutputs.createClassJar( + generatedSources, options.classJarOutput, options.targetLabel, options.injectingRuleKind); logger.fine( String.format("Create classJar finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceMergingAction.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceMergingAction.java index c67806088f..cbd53a512e 100644 --- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceMergingAction.java +++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceMergingAction.java @@ -193,6 +193,26 @@ public class AndroidResourceMergingAction { help = "If passed, resource merge conflicts will be treated as errors instead of warnings" ) public boolean throwOnResourceConflict; + + @Option( + name = "targetLabel", + defaultValue = "null", + category = "input", + documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, + effectTags = {OptionEffectTag.UNKNOWN}, + help = "A label to add to the output jar's manifest as 'Target-Label'" + ) + public String targetLabel; + + @Option( + name = "injectingRuleKind", + defaultValue = "null", + category = "input", + documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, + effectTags = {OptionEffectTag.UNKNOWN}, + help = "A string to add to the output jar's manifest as 'Injecting-Rule-Kind'" + ) + public String injectingRuleKind; } public static void main(String[] args) throws Exception { @@ -267,7 +287,11 @@ public class AndroidResourceMergingAction { } if (options.classJarOutput != null) { - AndroidResourceOutputs.createClassJar(generatedSources, options.classJarOutput); + AndroidResourceOutputs.createClassJar( + generatedSources, + options.classJarOutput, + options.targetLabel, + options.injectingRuleKind); logger.fine( String.format( "Create classJar finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); diff --git a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java index b277e010e2..41d942736f 100644 --- a/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java +++ b/src/tools/android/java/com/google/devtools/build/android/AndroidResourceOutputs.java @@ -37,13 +37,13 @@ import java.util.GregorianCalendar; import java.util.List; import java.util.Objects; import java.util.jar.Attributes; -import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.CRC32; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; +import javax.annotation.Nullable; /** Collects all the functionationality for an action to create the final output artifacts. */ public class AndroidResourceOutputs { @@ -127,7 +127,8 @@ public class AndroidResourceOutputs { super(zip, root, null); } - private byte[] manifestContent() throws IOException { + private byte[] manifestContent(@Nullable String targetLabel, @Nullable String injectingRuleKind) + throws IOException { Manifest manifest = new Manifest(); Attributes attributes = manifest.getMainAttributes(); attributes.put(Attributes.Name.MANIFEST_VERSION, "1.0"); @@ -135,6 +136,14 @@ public class AndroidResourceOutputs { if (attributes.getValue(createdBy) == null) { attributes.put(createdBy, "bazel"); } + if (targetLabel != null) { + // Enable add_deps support. add_deps expects this attribute in the jar manifest. + attributes.putValue("Target-Label", targetLabel); + } + if (injectingRuleKind != null) { + // add_deps support for aspects. Usually null. + attributes.putValue("Injecting-Rule-Kind", injectingRuleKind); + } ByteArrayOutputStream out = new ByteArrayOutputStream(); manifest.write(out); return out.toByteArray(); @@ -150,8 +159,10 @@ public class AndroidResourceOutputs { } } - void writeManifestContent() throws IOException { - addEntry(root.resolve(JarFile.MANIFEST_NAME), manifestContent()); + void writeManifestContent(@Nullable String targetLabel, @Nullable String injectingRuleKind) + throws IOException { + addEntry("META-INF/", new byte[] {}); + addEntry("META-INF/MANIFEST.MF", manifestContent(targetLabel, injectingRuleKind)); } } @@ -247,6 +258,10 @@ public class AndroidResourceOutputs { zipBuilder.addEntry(directoryPrefix + root.relativize(file), content, storageMethod); } + protected void addEntry(String entry, byte[] content) throws IOException { + zipBuilder.addEntry(entry, content, storageMethod); + } + protected void addDirEntry(Path file) throws IOException { Preconditions.checkArgument(file.startsWith(root), "%s does not start with %s", file, root); String entryName = directoryPrefix + root.relativize(file); @@ -336,14 +351,18 @@ public class AndroidResourceOutputs { } /** Creates a zip archive from all found R.class (and inner class) files. */ - public static void createClassJar(Path generatedClassesRoot, Path classJar) { + public static void createClassJar( + Path generatedClassesRoot, + Path classJar, + @Nullable String targetLabel, + @Nullable String injectingRuleKind) { try { Files.createDirectories(classJar.getParent()); try (final ZipBuilder zip = ZipBuilder.createFor(classJar)) { ClassJarBuildingVisitor visitor = new ClassJarBuildingVisitor(zip, generatedClassesRoot); Files.walkFileTree(generatedClassesRoot, visitor); + visitor.writeManifestContent(targetLabel, injectingRuleKind); visitor.writeEntries(); - visitor.writeManifestContent(); } } catch (IOException e) { throw new RuntimeException(e); diff --git a/src/tools/android/java/com/google/devtools/build/android/GenerateRobolectricResourceSymbolsAction.java b/src/tools/android/java/com/google/devtools/build/android/GenerateRobolectricResourceSymbolsAction.java index d6010bf0e9..b859904daa 100644 --- a/src/tools/android/java/com/google/devtools/build/android/GenerateRobolectricResourceSymbolsAction.java +++ b/src/tools/android/java/com/google/devtools/build/android/GenerateRobolectricResourceSymbolsAction.java @@ -104,6 +104,26 @@ public class GenerateRobolectricResourceSymbolsAction { help = "Path for the generated java class jar." ) public Path classJarOutput; + + @Option( + name = "targetLabel", + defaultValue = "null", + category = "input", + documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, + effectTags = {OptionEffectTag.UNKNOWN}, + help = "A label to add to the output jar's manifest as 'Target-Label'" + ) + public String targetLabel; + + @Option( + name = "injectingRuleKind", + defaultValue = "null", + category = "input", + documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, + effectTags = {OptionEffectTag.UNKNOWN}, + help = "A string to add to the output jar's manifest as 'Injecting-Rule-Kind'" + ) + public String injectingRuleKind; } public static void main(String[] args) throws Exception { @@ -176,7 +196,8 @@ public class GenerateRobolectricResourceSymbolsAction { logger.fine(String.format("Merging finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); - AndroidResourceOutputs.createClassJar(generatedSources, options.classJarOutput); + AndroidResourceOutputs.createClassJar( + generatedSources, options.classJarOutput, options.targetLabel, options.injectingRuleKind); logger.fine( String.format("Create classJar finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); diff --git a/src/tools/android/java/com/google/devtools/build/android/LibraryRClassGeneratorAction.java b/src/tools/android/java/com/google/devtools/build/android/LibraryRClassGeneratorAction.java index 2cce77e3cf..73a6c368e8 100644 --- a/src/tools/android/java/com/google/devtools/build/android/LibraryRClassGeneratorAction.java +++ b/src/tools/android/java/com/google/devtools/build/android/LibraryRClassGeneratorAction.java @@ -96,6 +96,26 @@ public class LibraryRClassGeneratorAction { metadataTags = {OptionMetadataTag.DEPRECATED} ) public List<Path> deprecatedSymbols; + + @Option( + name = "targetLabel", + defaultValue = "null", + category = "input", + documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, + effectTags = {OptionEffectTag.UNKNOWN}, + help = "A label to add to the output jar's manifest as 'Target-Label'" + ) + public String targetLabel; + + @Option( + name = "injectingRuleKind", + defaultValue = "null", + category = "input", + documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, + effectTags = {OptionEffectTag.UNKNOWN}, + help = "A string to add to the output jar's manifest as 'Injecting-Rule-Kind'" + ) + public String injectingRuleKind; } public static void main(String[] args) throws Exception { @@ -131,7 +151,11 @@ public class LibraryRClassGeneratorAction { logger.fine( String.format("R writing finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); - AndroidResourceOutputs.createClassJar(scopedTmp.getPath(), options.classJarOutput); + AndroidResourceOutputs.createClassJar( + scopedTmp.getPath(), + options.classJarOutput, + options.targetLabel, + options.injectingRuleKind); logger.fine( String.format( "Creating class jar finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); diff --git a/src/tools/android/java/com/google/devtools/build/android/RClassGeneratorAction.java b/src/tools/android/java/com/google/devtools/build/android/RClassGeneratorAction.java index bcfdb5fdb3..9213149e5b 100644 --- a/src/tools/android/java/com/google/devtools/build/android/RClassGeneratorAction.java +++ b/src/tools/android/java/com/google/devtools/build/android/RClassGeneratorAction.java @@ -137,6 +137,26 @@ public class RClassGeneratorAction { help = "Path for the generated jar of R.class files." ) public Path classJarOutput; + + @Option( + name = "targetLabel", + defaultValue = "null", + category = "input", + documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, + effectTags = {OptionEffectTag.UNKNOWN}, + help = "A label to add to the output jar's manifest as 'Target-Label'" + ) + public String targetLabel; + + @Option( + name = "injectingRuleKind", + defaultValue = "null", + category = "input", + documentationCategory = OptionDocumentationCategory.UNCATEGORIZED, + effectTags = {OptionEffectTag.UNKNOWN}, + help = "A string to add to the output jar's manifest as 'Injecting-Rule-Kind'" + ) + public String injectingRuleKind; } public static void main(String[] args) throws Exception { @@ -190,7 +210,8 @@ public class RClassGeneratorAction { } // We write .class files to temp, then jar them up after (we create a dummy jar, even if // there are no class files). - AndroidResourceOutputs.createClassJar(classOutPath, options.classJarOutput); + AndroidResourceOutputs.createClassJar( + classOutPath, options.classJarOutput, options.targetLabel, options.injectingRuleKind); logger.fine( String.format("createClassJar finished at %sms", timer.elapsed(TimeUnit.MILLISECONDS))); } finally { |