aboutsummaryrefslogtreecommitdiffhomepage
path: root/third_party/ijar/ijar.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/ijar/ijar.cc')
-rw-r--r--third_party/ijar/ijar.cc62
1 files changed, 58 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;
}