diff options
author | tomlu <tomlu@google.com> | 2018-02-08 09:31:48 -0800 |
---|---|---|
committer | Copybara-Service <copybara-piper@google.com> | 2018-02-08 09:33:22 -0800 |
commit | 13962bf49cc756b49d9f114baf454f428a18acac (patch) | |
tree | 7a6728c98378e4afe1b886e7e1bd2ed3175d379c /third_party/ijar | |
parent | c89e1f3d662f78ec995209a8c3fd83dc26630f79 (diff) |
Accept --target_label, --injecting_rule_kind in ijar.
The values (if present) are written into the manifest with this format:
Target-Label: <label>
Injecting-Rule-Kind: <kind>
In the future, JavaBuilder will make sure of this instead of command line arguments to find owners for jars for its add_dep commands.
PiperOrigin-RevId: 185006704
Diffstat (limited to 'third_party/ijar')
-rw-r--r-- | third_party/ijar/ijar.cc | 62 | ||||
-rw-r--r-- | third_party/ijar/test/IjarTests.java | 13 |
2 files changed, 71 insertions, 4 deletions
diff --git a/third_party/ijar/ijar.cc b/third_party/ijar/ijar.cc index 144120ebf3..d7742ee1ac 100644 --- a/third_party/ijar/ijar.cc +++ b/third_party/ijar/ijar.cc @@ -36,6 +36,14 @@ bool StripClass(u1*& classdata_out, const u1* classdata_in, size_t in_length); const char* CLASS_EXTENSION = ".class"; const size_t CLASS_EXTENSION_LENGTH = strlen(CLASS_EXTENSION); +const char *MANIFEST_HEADER = + "Manifest-Version: 1.0\n" + "Created-By: bazel\n"; +// These attributes are used by JavaBuilder, Turbine, and ijar. +// They must all be kept in sync. +const char *TARGET_LABEL_KEY = "Target-Label: "; +const char *INJECTING_RULE_KIND_KEY = "Injecting-Rule-Kind: "; + // ZipExtractorProcessor that select only .class file and use // StripClass to generate an interface class, storing as a new file // in the specified ZipBuilder. @@ -105,9 +113,39 @@ void JarStripperProcessor::Process(const char* filename, const u4 attr, } } +// Copies the string into the buffer without the null terminator, returns length +static size_t WriteStr(u1 *buf, const char *str) { + size_t len = strlen(str); + memcpy(buf, str, len); + return len; +} + +static void WriteManifest(ZipBuilder *out, const char *target_label, + const char *injecting_rule_kind) { + if (target_label == NULL) { + return; + } + out->WriteEmptyFile("META-INF/"); + u1 *start = out->NewFile("META-INF/MANIFEST.MF", 0); + u1 *buf = start; + buf += WriteStr(buf, MANIFEST_HEADER); + buf += WriteStr(buf, TARGET_LABEL_KEY); + buf += WriteStr(buf, target_label); + *buf++ = '\n'; + if (injecting_rule_kind) { + buf += WriteStr(buf, INJECTING_RULE_KIND_KEY); + buf += WriteStr(buf, injecting_rule_kind); + *buf++ = '\n'; + } + size_t total_len = buf - start; + out->FinishFile(total_len); +} + // Opens "file_in" (a .jar file) for reading, and writes an interface // .jar to "file_out". -void OpenFilesAndProcessJar(const char *file_out, const char *file_in) { +static void OpenFilesAndProcessJar(const char *file_out, const char *file_in, + const char *target_label, + const char *injecting_rule_kind) { JarStripperProcessor processor; std::unique_ptr<ZipExtractor> in(ZipExtractor::Create(file_in, &processor)); if (in.get() == NULL) { @@ -129,6 +167,7 @@ void OpenFilesAndProcessJar(const char *file_out, const char *file_in) { fprintf(stderr, "%s\n", in->GetError()); abort(); } + WriteManifest(out.get(), target_label, injecting_rule_kind); // Add dummy file, since javac doesn't like truly empty jars. if (out->GetNumberFiles() == 0) { @@ -148,25 +187,39 @@ void OpenFilesAndProcessJar(const char *file_out, const char *file_in) { static_cast<int>(100.0 * out_length / in_length)); } } - } // namespace devtools_ijar // // main method // static void usage() { - fprintf(stderr, "Usage: ijar [-v] x.jar [x_interface.jar>]\n"); + fprintf(stderr, + "Usage: ijar " + "[-v] [--target label label] [--injecting_rule_kind kind] " + "x.jar [x_interface.jar>]\n"); fprintf(stderr, "Creates an interface jar from the specified jar file.\n"); exit(1); } int main(int argc, char **argv) { + const char *target_label = NULL; + const char *injecting_rule_kind = NULL; const char *filename_in = NULL; const char *filename_out = NULL; for (int ii = 1; ii < argc; ++ii) { if (strcmp(argv[ii], "-v") == 0) { devtools_ijar::verbose = true; + } else if (strcmp(argv[ii], "--target_label") == 0) { + if (++ii >= argc) { + usage(); + } + target_label = argv[ii]; + } else if (strcmp(argv[ii], "--injecting_rule_kind") == 0) { + if (++ii >= argc) { + usage(); + } + injecting_rule_kind = argv[ii]; } else if (filename_in == NULL) { filename_in = argv[ii]; } else if (filename_out == NULL) { @@ -199,6 +252,7 @@ int main(int argc, char **argv) { fprintf(stderr, "INFO: writing to '%s'.\n", filename_out); } - devtools_ijar::OpenFilesAndProcessJar(filename_out, filename_in); + devtools_ijar::OpenFilesAndProcessJar(filename_out, filename_in, target_label, + injecting_rule_kind); return 0; } diff --git a/third_party/ijar/test/IjarTests.java b/third_party/ijar/test/IjarTests.java index 4e0fb5d839..d07b37e3d2 100644 --- a/third_party/ijar/test/IjarTests.java +++ b/third_party/ijar/test/IjarTests.java @@ -30,8 +30,10 @@ import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.jar.Manifest; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import javax.annotation.processing.AbstractProcessor; @@ -274,4 +276,15 @@ public class IjarTests { assertThat(new String(lib.get("module-info.class"), UTF_8)).isEqualTo("hello"); assertThat(new String(lib.get("foo/module-info.class"), UTF_8)).isEqualTo("goodbye"); } + + @Test + public void testTargetLabel() throws Exception { + try (JarFile jf = + new JarFile("third_party/ijar/test/interface_ijar_testlib_with_target_label.jar")) { + Manifest manifest = jf.getManifest(); + Attributes attributes = manifest.getMainAttributes(); + assertThat(attributes.getValue("Target-Label")).isEqualTo("//foo:foo"); + assertThat(attributes.getValue("Injecting-Rule-Kind")).isEqualTo("foo_library"); + } + } } |