Do not generate an app image without a boot image.

We used to not do compilation at all. Now we will compile, but not
generate an app image.

Test: test.py
Test: dex2oat_tests
Bug: 214376933
Change-Id: Ia8adffec9d1919b128f5ed0fe2e763ee863dc4b3
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 7a27ab6..c8bef9e 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -958,7 +958,6 @@
     key_value_store_->Put(OatHeader::kCompilerFilter,
                           CompilerFilter::NameOfFilter(compiler_options_->GetCompilerFilter()));
     key_value_store_->Put(OatHeader::kConcurrentCopying, kUseReadBarrier);
-    key_value_store_->Put(OatHeader::kRequiresImage, compiler_options_->IsGeneratingImage());
     if (invocation_file_.get() != -1) {
       std::ostringstream oss;
       for (int i = 0; i < argc; ++i) {
@@ -1525,10 +1524,10 @@
     }
     if (runtime_->GetHeap()->GetBootImageSpaces().empty() &&
         (IsBootImageExtension() || IsAppImage())) {
-      LOG(ERROR) << "Cannot create "
-                 << (IsBootImageExtension() ? "boot image extension" : "app image")
-                 << " without a primary boot image.";
-      return dex2oat::ReturnCode::kOther;
+      LOG(WARNING) << "Cannot create "
+                   << (IsBootImageExtension() ? "boot image extension" : "app image")
+                   << " without a primary boot image.";
+      compiler_options_->image_type_ = CompilerOptions::ImageType::kNone;
     }
     ArrayRef<const DexFile* const> bcp_dex_files(runtime_->GetClassLinker()->GetBootClassPath());
     if (IsBootImage() || IsBootImageExtension()) {
@@ -1667,6 +1666,10 @@
       key_value_store_->Put(OatHeader::kApexVersionsKey, versions);
     }
 
+    // Now that we have adjusted whether we generate an image, encode it in the
+    // key/value store.
+    key_value_store_->Put(OatHeader::kRequiresImage, compiler_options_->IsGeneratingImage());
+
     // Now that we have finalized key_value_store_, start writing the .rodata section.
     // Among other things, this creates type lookup tables that speed up the compilation.
     {
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index c38c720..9ee532a 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -884,7 +884,21 @@
                      /*use_fd=*/ false,
                      /*num_profile_classes=*/ 1,
                      /*extra_args=*/ {"--boot-image=/nonx/boot.art"},
-                     /*expect_success=*/ false);
+                     /*expect_success=*/ true);
+
+  // Verify the odex file does not require an image.
+  std::string error_msg;
+  std::unique_ptr<OatFile> odex_file(OatFile::Open(/*zip_fd=*/ -1,
+                                                   odex_location.c_str(),
+                                                   odex_location.c_str(),
+                                                   /*executable=*/ false,
+                                                   /*low_4gb=*/ false,
+                                                   dex_location,
+                                                   &error_msg));
+  ASSERT_TRUE(odex_file != nullptr) << "Could not open odex file: " << error_msg;
+
+  CheckFilter(CompilerFilter::kSpeedProfile, odex_file->GetCompilerFilter());
+  ASSERT_FALSE(odex_file->GetOatHeader().RequiresImage());
 }
 
 TEST_F(Dex2oatLayoutTest, TestLayoutMultipleProfiles) {
diff --git a/runtime/oat_file_manager.cc b/runtime/oat_file_manager.cc
index aaa6600..c3a268d 100644
--- a/runtime/oat_file_manager.cc
+++ b/runtime/oat_file_manager.cc
@@ -308,7 +308,7 @@
         if (oat_file->RequiresImage()) {
           LOG(WARNING) << "Loading "
                        << oat_file->GetLocation()
-                       << "non-executable as it requires an image which we failed to load";
+                       << " non-executable as it requires an image which we failed to load";
           // file as non-executable.
           OatFileAssistant nonexecutable_oat_file_assistant(dex_location,
                                                             kRuntimeISA,