Fix portable build on build server by removing depenency on ANDROID_HOST_OUT

Change-Id: I713a156468d14e07c784013c3c37a18c3c075a71
diff --git a/src/common_test.h b/src/common_test.h
index 0167424..62e7561 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -446,6 +446,15 @@
     return StringPrintf("%s/framework/%s.jar", GetAndroidRoot(), jar_prefix.c_str());
   }
 
+  std::string GetTestAndroidRoot() {
+    if (IsHost()) {
+      const char* host_dir = getenv("ANDROID_HOST_OUT");
+      CHECK(host_dir != NULL);
+      return host_dir;
+    }
+    return GetAndroidRoot();
+  }
+
   const DexFile* OpenTestDexFile(const char* name) {
     CHECK(name != NULL);
     std::string filename;
diff --git a/src/compiler/dex/write_elf.cc b/src/compiler/dex/write_elf.cc
index 7e3d512..acec531 100644
--- a/src/compiler/dex/write_elf.cc
+++ b/src/compiler/dex/write_elf.cc
@@ -23,13 +23,13 @@
 }  // namespace art
 
 extern "C" bool WriteElf(art::CompilerDriver& driver,
-                         const std::string* host_prefix,
+                         const std::string& android_root,
                          bool is_host,
                          const std::vector<const art::DexFile*>& dex_files,
                          std::vector<uint8_t>& oat_contents,
                          art::File* file)
     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-  return art::ElfWriter::Create(file, oat_contents, dex_files, host_prefix, is_host, driver);
+  return art::ElfWriter::Create(file, oat_contents, dex_files, android_root, is_host, driver);
 }
 extern "C" bool FixupElf(art::File* file, uintptr_t oat_data_begin) {
   return art::ElfWriter::Fixup(file, oat_data_begin);
diff --git a/src/compiler/driver/compiler_driver.cc b/src/compiler/driver/compiler_driver.cc
index 8856a00..8556cc8 100644
--- a/src/compiler/driver/compiler_driver.cc
+++ b/src/compiler/driver/compiler_driver.cc
@@ -1793,13 +1793,13 @@
   return freezing_constructor_classes_.count(ClassReference(dex_file, class_def_index)) != 0;
 }
 
-bool CompilerDriver::WriteElf(const std::string* host_prefix,
+bool CompilerDriver::WriteElf(const std::string& android_root,
                               bool is_host,
                               const std::vector<const DexFile*>& dex_files,
                               std::vector<uint8_t>& oat_contents,
                               File* file) {
   typedef bool (*WriteElfFn)(CompilerDriver&,
-                             const std::string* host_prefix,
+                             const std::string& android_root,
                              bool is_host,
                              const std::vector<const DexFile*>& dex_files,
                              std::vector<uint8_t>&,
@@ -1807,7 +1807,7 @@
   WriteElfFn WriteElf =
     FindFunction<WriteElfFn>(MakeCompilerSoName(compiler_backend_), compiler_library_, "WriteElf");
   Locks::mutator_lock_->AssertSharedHeld(Thread::Current());
-  return WriteElf(*this, host_prefix, is_host, dex_files, oat_contents, file);
+  return WriteElf(*this, android_root, is_host, dex_files, oat_contents, file);
 }
 
 bool CompilerDriver::FixupElf(File* file, uintptr_t oat_data_begin) const {
diff --git a/src/compiler/driver/compiler_driver.h b/src/compiler/driver/compiler_driver.h
index 7f67c21..54a2f55 100644
--- a/src/compiler/driver/compiler_driver.h
+++ b/src/compiler/driver/compiler_driver.h
@@ -187,7 +187,7 @@
   void SetBitcodeFileName(std::string const& filename);
 
   // TODO: remove these Elf wrappers when libart links against LLVM (when separate compiler library is gone)
-  bool WriteElf(const std::string* host_prefix,
+  bool WriteElf(const std::string& android_root,
                 bool is_host,
                 const std::vector<const DexFile*>& dex_files,
                 std::vector<uint8_t>& oat_contents,
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index 6892bb3..cce9276 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -115,6 +115,10 @@
   UsageError("      Example: --host-prefix=out/target/product/crespo");
   UsageError("      Default: $ANDROID_PRODUCT_OUT");
   UsageError("");
+  UsageError("  --android-root=<path>: used to locate libraries for portable linking.");
+  UsageError("      Example: --android-root=out/host/linux-x86");
+  UsageError("      Default: $ANDROID_ROOT");
+  UsageError("");
   UsageError("  --instruction-set=(arm|mips|x86): compile for a particular instruction");
   UsageError("      set.");
   UsageError("      Example: --instruction-set=x86");
@@ -223,15 +227,16 @@
   }
 
   const CompilerDriver* CreateOatFile(const std::string& boot_image_option,
-                                const std::string* host_prefix,
-                                bool is_host,
-                                const std::vector<const DexFile*>& dex_files,
-                                File* oat_file,
-                                const std::string& bitcode_filename,
-                                bool image,
-                                const std::set<std::string>* image_classes,
-                                bool dump_stats,
-                                bool dump_timings)
+                                      const std::string* host_prefix,
+                                      const std::string& android_root,
+                                      bool is_host,
+                                      const std::vector<const DexFile*>& dex_files,
+                                      File* oat_file,
+                                      const std::string& bitcode_filename,
+                                      bool image,
+                                      const std::set<std::string>* image_classes,
+                                      bool dump_stats,
+                                      bool dump_timings)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
     // SirtRef and ClassLoader creation needs to come after Runtime::Create
     jobject class_loader = NULL;
@@ -295,7 +300,7 @@
       return NULL;
     }
 
-    if (!driver->WriteElf(host_prefix, is_host, dex_files, oat_contents, oat_file)) {
+    if (!driver->WriteElf(android_root, is_host, dex_files, oat_contents, oat_file)) {
       LOG(ERROR) << "Failed to write ELF file " << oat_file->GetPath();
       return NULL;
     }
@@ -650,6 +655,7 @@
   std::string boot_image_filename;
   uintptr_t image_base = 0;
   UniquePtr<std::string> host_prefix;
+  std::string android_root;
   std::vector<const char*> runtime_args;
   int thread_count = sysconf(_SC_NPROCESSORS_CONF);
   bool support_debugging = false;
@@ -728,6 +734,8 @@
       boot_image_filename = option.substr(strlen("--boot-image=")).data();
     } else if (option.starts_with("--host-prefix=")) {
       host_prefix.reset(new std::string(option.substr(strlen("--host-prefix=")).data()));
+    } else if (option.starts_with("--android-root=")) {
+      android_root = option.substr(strlen("--android-root=")).data();
     } else if (option.starts_with("--instruction-set=")) {
       StringPiece instruction_set_str = option.substr(strlen("--instruction-set=")).data();
       if (instruction_set_str == "arm") {
@@ -788,6 +796,14 @@
     }
   }
 
+  if (android_root.empty()) {
+    const char* android_root_env_var = getenv("ANDROID_ROOT");
+    if (android_root_env_var == NULL) {
+      Usage("--android_root unspecified and ANDROID_ROOT not set");
+    }
+    android_root += android_root_env_var;
+  }
+
   bool image = (!image_filename.empty());
   if (!image && boot_image_filename.empty()) {
     if (host_prefix.get() == NULL) {
@@ -946,6 +962,7 @@
 
   UniquePtr<const CompilerDriver> compiler(dex2oat->CreateOatFile(boot_image_option,
                                                                   host_prefix.get(),
+                                                                  android_root,
                                                                   is_host,
                                                                   dex_files,
                                                                   oat_file.get(),
diff --git a/src/elf_writer.cc b/src/elf_writer.cc
index 88b3543..fc6561f 100644
--- a/src/elf_writer.cc
+++ b/src/elf_writer.cc
@@ -44,11 +44,11 @@
 bool ElfWriter::Create(File* elf_file,
                        std::vector<uint8_t>& oat_contents,
                        const std::vector<const DexFile*>& dex_files,
-                       const std::string* host_prefix,
+                       const std::string& android_root,
                        bool is_host,
                        const CompilerDriver& driver) {
   ElfWriter elf_writer(driver, elf_file);
-  return elf_writer.Write(oat_contents, dex_files, host_prefix, is_host);
+  return elf_writer.Write(oat_contents, dex_files, android_root, is_host);
 }
 
 ElfWriter::ElfWriter(const CompilerDriver& driver, File* elf_file)
@@ -58,13 +58,13 @@
 
 bool ElfWriter::Write(std::vector<uint8_t>& oat_contents,
                       const std::vector<const DexFile*>& dex_files,
-                      const std::string* host_prefix,
+                      const std::string& android_root,
                       bool is_host) {
   Init();
   AddOatInput(oat_contents);
 #if defined(ART_USE_PORTABLE_COMPILER)
   AddMethodInputs(dex_files);
-  AddRuntimeInputs(host_prefix, is_host);
+  AddRuntimeInputs(android_root, is_host);
 #endif
   if (!Link()) {
     return false;
@@ -267,21 +267,7 @@
   CHECK(code_input != NULL);
 }
 
-void ElfWriter::AddRuntimeInputs(const std::string* host_prefix, bool is_host) {
-  std::string android_root;
-  if (is_host) {
-    const char* android_host_out = getenv("ANDROID_HOST_OUT");
-    CHECK(android_host_out != NULL) << "ANDROID_HOST_OUT environment variable not set";
-    android_root += android_host_out;
-  } else {
-    if (host_prefix != NULL) {
-      android_root += *host_prefix;
-      android_root += "/system";
-    } else {
-      android_root += GetAndroidRoot();
-    }
-  }
-
+void ElfWriter::AddRuntimeInputs(const std::string& android_root, bool is_host) {
   std::string libart_so(android_root);
   libart_so += kIsDebugBuild ? "/lib/libartd.so" : "/lib/libart.so";
   // TODO: ownership of libart_so_input?
diff --git a/src/elf_writer.h b/src/elf_writer.h
index 6f22db1..1dd0131 100644
--- a/src/elf_writer.h
+++ b/src/elf_writer.h
@@ -50,7 +50,7 @@
   static bool Create(File* file,
                      std::vector<uint8_t>& oat_contents,
                      const std::vector<const DexFile*>& dex_files,
-                     const std::string* host_prefix,
+                     const std::string& android_root,
                      bool is_host,
                      const CompilerDriver& driver)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -75,7 +75,7 @@
 
   bool Write(std::vector<uint8_t>& oat_contents,
              const std::vector<const DexFile*>& dex_files,
-             const std::string* host_prefix,
+             const std::string& android_root,
              bool is_host)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
@@ -83,7 +83,7 @@
   void AddOatInput(std::vector<uint8_t>& oat_contents);
   void AddMethodInputs(const std::vector<const DexFile*>& dex_files);
   void AddCompiledCodeInput(const CompiledCode& compiled_code);
-  void AddRuntimeInputs(const std::string* host_prefix, bool is_host);
+  void AddRuntimeInputs(const std::string& android_root, bool is_host);
   bool Link();
 #if defined(ART_USE_PORTABLE_COMPILER)
   void FixupOatMethodOffsets(const std::vector<const DexFile*>& dex_files)
diff --git a/src/image_test.cc b/src/image_test.cc
index dc16a6c..e4deda3 100644
--- a/src/image_test.cc
+++ b/src/image_test.cc
@@ -57,7 +57,7 @@
         mirror::Class* klass = class_linker_->FindSystemClass(descriptor);
         EXPECT_TRUE(klass != NULL) << descriptor;
       }
-      bool success_elf = compiler_driver_->WriteElf(NULL,
+      bool success_elf = compiler_driver_->WriteElf(GetTestAndroidRoot(),
                                                     !kIsTargetBuild,
                                                     dex_files,
                                                     oat_contents,
diff --git a/src/oat_test.cc b/src/oat_test.cc
index ace52f4..c4bd60e 100644
--- a/src/oat_test.cc
+++ b/src/oat_test.cc
@@ -90,7 +90,7 @@
                                        "lue.art",
                                        *compiler_driver_.get());
   ASSERT_TRUE(success_oat);
-  bool success_elf = compiler_driver_->WriteElf(NULL,
+  bool success_elf = compiler_driver_->WriteElf(GetTestAndroidRoot(),
                                                 !kIsTargetBuild,
                                                 class_linker->GetBootClassPath(),
                                                 oat_contents,