Pass the classpath to dex2oat.
This makes it possible to run applications that have multiple
dex files on the classpath.
Change-Id: I15264a001a46ddb253e87f2739e6b9644348f1be
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index 6cf6df6..231ca9c 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -94,6 +94,34 @@
bool do_unlink_;
};
+// Returns true if dex_files has a dex with the named location.
+bool DexFilesContains(const std::vector<const DexFile*>& dex_files, const std::string& location) {
+ for (size_t i = 0; i < dex_files.size(); ++i) {
+ if (dex_files[i]->GetLocation() == location) {
+ return true;
+ }
+ }
+ return false;
+}
+
+// Appends to dex_files any elements of class_path that it doesn't already
+// contain. This will open those dex files as necessary.
+void OpenClassPathFiles(const std::string& class_path, std::vector<const DexFile*>& dex_files) {
+ std::vector<std::string> parsed;
+ Split(class_path, ':', parsed);
+ for (size_t i = 0; i < parsed.size(); ++i) {
+ if (DexFilesContains(dex_files, parsed[i])) {
+ continue;
+ }
+ const DexFile* dex_file = DexFile::Open(parsed[i], Runtime::Current()->GetHostPrefix());
+ if (dex_file == NULL) {
+ LOG(WARNING) << "Failed to open dex file " << parsed[i];
+ } else {
+ dex_files.push_back(dex_file);
+ }
+ }
+}
+
int dex2oat(int argc, char** argv) {
// Skip over argv[0].
argv++;
@@ -272,13 +300,17 @@
// ClassLoader creation needs to come after Runtime::Create
SirtRef<ClassLoader> class_loader(NULL);
+ std::vector<const DexFile*> dex_files;
if (!boot_image_option.empty()) {
- std::vector<const DexFile*> dex_files;
DexFile::OpenDexFiles(dex_filenames, dex_files, host_prefix);
- for (size_t i = 0; i < dex_files.size(); i++) {
- class_linker->RegisterDexFile(*dex_files[i]);
+ std::vector<const DexFile*> class_path_files(dex_files);
+ OpenClassPathFiles(runtime->GetClassPath(), class_path_files);
+ for (size_t i = 0; i < class_path_files.size(); i++) {
+ class_linker->RegisterDexFile(*class_path_files[i]);
}
- class_loader.reset(PathClassLoader::AllocCompileTime(dex_files));
+ class_loader.reset(PathClassLoader::AllocCompileTime(class_path_files));
+ } else {
+ dex_files = runtime->GetClassLinker()->GetBootClassPath();
}
// if we loaded an existing image, we will reuse values from the image roots.
@@ -302,7 +334,7 @@
}
Compiler compiler(kThumb2, image_filename != NULL);
if (method_names.empty()) {
- compiler.CompileAll(class_loader.get());
+ compiler.CompileAll(class_loader.get(), dex_files);
} else {
for (size_t i = 0; i < method_names.size(); i++) {
// names are actually class_descriptor + name + signature.