Generate boot images for host from prebuilts

Previously, when building from prebuilts boot no rules were created to
produce the boot image files for the host, i.e. the OS on which the
build was running. That caused problems with checkbuilds. No rules were
produced as there was no host variant of a prebuilt apex to provide
them.

This change restructures the code to allow the prebuilt bootclasspath
fragment to build the host variants of the files from the dex files
provided by the prebuilt APEX. The generated files will not be the same
as they would be if built from source as there is no boot image profile
to use but it should be sufficient to satisfy the checkbuild target and
allow for host side testing.

Bug: 192575099
Test: m SOONG_CONFIG_art_module_source_build=false droid dist checkbuild
Merged-In: I6af00f19bb71aa18dd462f5eac6aa38e3e721023
Change-Id: I6af00f19bb71aa18dd462f5eac6aa38e3e721023
(cherry picked from commit a56be7d7815ad164cdd854f8fc6b1cbc3bbf1918)
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index f6c62b1..358c72b 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -679,7 +679,16 @@
 
 	// Build a profile for the image config and then use that to build the boot image.
 	profile := bootImageProfileRule(ctx, imageConfig)
-	return buildBootImage(ctx, imageConfig, profile)
+
+	// Build boot image files for the host variants.
+	buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
+
+	// Build boot image files for the android variants.
+	androidBootImageFilesByArch := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
+
+	// Return the boot image files for the android variants for inclusion in an APEX and to be zipped
+	// up for the dist.
+	return androidBootImageFilesByArch
 }
 
 type bootclasspathFragmentMemberType struct {
@@ -935,6 +944,12 @@
 		}
 	}
 
+	// Build the boot image files for the host variants. These are built from the dex files provided
+	// by the contents of this module as prebuilt versions of the host boot image files are not
+	// available, i.e. there is no host specific prebuilt apex containing them. This has to be built
+	// without a profile as the prebuilt modules do not provide a profile.
+	buildBootImageVariantsForBuildOs(ctx, imageConfig, nil)
+
 	return files
 }
 
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 0f8ff9e..19c65ca 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -502,14 +502,36 @@
 	}
 }
 
-// buildBootImage takes a bootImageConfig, and creates rules to build it.
+// buildBootImageVariantsForAndroidOs generates rules to build the boot image variants for the
+// android.Android OsType and returns a map from the architectures to the paths of the generated
+// boot image files.
+//
+// The paths are returned because they are needed elsewhere in Soong, e.g. for populating an APEX.
+func buildBootImageVariantsForAndroidOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) bootImageFilesByArch {
+	return buildBootImageForOsType(ctx, image, profile, android.Android)
+}
+
+// buildBootImageVariantsForBuildOs generates rules to build the boot image variants for the
+// android.BuildOs OsType, i.e. the type of OS on which the build is being running.
+//
+// The files need to be generated into their predefined location because they are used from there
+// both within Soong and outside, e.g. for ART based host side testing and also for use by some
+// cloud based tools. However, they are not needed by callers of this function and so the paths do
+// not need to be returned from this func, unlike the buildBootImageVariantsForAndroidOs func.
+func buildBootImageVariantsForBuildOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) {
+	buildBootImageForOsType(ctx, image, profile, android.BuildOs)
+}
+
+// buildBootImageForOsType takes a bootImageConfig, a profile file and an android.OsType
+// boot image files are required for and it creates rules to build the boot image
+// files for all the required architectures for them.
 //
 // It returns a map from android.ArchType to the predefined paths of the boot image files.
-func buildBootImage(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) bootImageFilesByArch {
+func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath, requiredOsType android.OsType) bootImageFilesByArch {
 	filesByArch := bootImageFilesByArch{}
 	for _, variant := range image.variants {
-		buildBootImageVariant(ctx, variant, profile)
-		if variant.target.Os == android.Android {
+		if variant.target.Os == requiredOsType {
+			buildBootImageVariant(ctx, variant, profile)
 			filesByArch[variant.target.Arch.ArchType] = variant.imagesDeps.Paths()
 		}
 	}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index cb92922..10739b0 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -421,10 +421,15 @@
 
 	// Build a profile for the image config and then use that to build the boot image.
 	profile := bootImageProfileRule(ctx, imageConfig)
-	bootImageFilesByArch := buildBootImage(ctx, imageConfig, profile)
 
-	// Zip the boot image files up.
-	buildBootImageZipInPredefinedLocation(ctx, imageConfig, bootImageFilesByArch)
+	// Build boot image files for the android variants.
+	androidBootImageFilesByArch := buildBootImageVariantsForAndroidOs(ctx, imageConfig, profile)
+
+	// Zip the android variant boot image files up.
+	buildBootImageZipInPredefinedLocation(ctx, imageConfig, androidBootImageFilesByArch)
+
+	// Build boot image files for the host variants. There are use directly by ART host side tests.
+	buildBootImageVariantsForBuildOs(ctx, imageConfig, profile)
 
 	dumpOatRules(ctx, imageConfig)
 }