aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/ijar
diff options
context:
space:
mode:
authorGravatar tomlu <tomlu@google.com>2018-02-08 09:31:48 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2018-02-08 09:33:22 -0800
commit13962bf49cc756b49d9f114baf454f428a18acac (patch)
tree7a6728c98378e4afe1b886e7e1bd2ed3175d379c /third_party/ijar
parentc89e1f3d662f78ec995209a8c3fd83dc26630f79 (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.cc62
-rw-r--r--third_party/ijar/test/IjarTests.java13
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");
+ }
+ }
}