Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4a838dfb authored by Paul Duffin's avatar Paul Duffin Committed by Gerrit Code Review
Browse files

Merge "Add boot_images to apex"

parents a4fce3b4 a1d6025a
Loading
Loading
Loading
Loading
+22 −23
Original line number Diff line number Diff line
@@ -89,6 +89,9 @@ type apexBundleProperties struct {

	Multilib apexMultilibProperties

	// List of boot images that are embedded inside this APEX bundle.
	Boot_images []string

	// List of java libraries that are embedded inside this APEX bundle.
	Java_libs []string

@@ -544,6 +547,7 @@ var (
	certificateTag = dependencyTag{name: "certificate"}
	executableTag  = dependencyTag{name: "executable", payload: true}
	fsTag          = dependencyTag{name: "filesystem", payload: true}
	bootImageTag   = dependencyTag{name: "bootImage", payload: true}
	javaLibTag     = dependencyTag{name: "javaLib", payload: true}
	jniLibTag      = dependencyTag{name: "jniLib", payload: true}
	keyTag         = dependencyTag{name: "key"}
@@ -721,6 +725,7 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {

	// Common-arch dependencies come next
	commonVariation := ctx.Config().AndroidCommonTarget.Variations()
	ctx.AddFarVariationDependencies(commonVariation, bootImageTag, a.properties.Boot_images...)
	ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
	ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.properties.Bpfs...)
	ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
@@ -730,10 +735,6 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
		if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
			ctx.AddFarVariationDependencies(commonVariation, javaLibTag, "jacocoagent")
		}
		// The ART boot image depends on dex2oat to compile it.
		if !java.SkipDexpreoptBootJars(ctx) {
			dexpreopt.RegisterToolDeps(ctx)
		}
	}

	// Dependencies for signing
@@ -1648,6 +1649,23 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
				} else {
					ctx.PropertyErrorf("binaries", "%q is neither cc_binary, rust_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
				}
			case bootImageTag:
				{
					if _, ok := child.(*java.BootImageModule); !ok {
						ctx.PropertyErrorf("boot_images", "%q is not a boot_image module", depName)
						return false
					}
					bootImageInfo := ctx.OtherModuleProvider(child, java.BootImageInfoProvider).(java.BootImageInfo)
					for arch, files := range bootImageInfo.AndroidBootImageFilesByArchType() {
						dirInApex := filepath.Join("javalib", arch.String())
						for _, f := range files {
							androidMkModuleName := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
							// TODO(b/177892522) - consider passing in the boot image module here instead of nil
							af := newApexFile(ctx, f, androidMkModuleName, dirInApex, etc, nil)
							filesInfo = append(filesInfo, af)
						}
					}
				}
			case javaLibTag:
				switch child.(type) {
				case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
@@ -1862,25 +1880,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
		return
	}

	if a.artApex {
		// Specific to the ART apex: dexpreopt artifacts for libcore Java libraries. Build rules are
		// generated by the dexpreopt singleton, and here we access build artifacts via the global
		// boot image config.
		for arch, files := range java.DexpreoptedArtApexJars(ctx) {
			dirInApex := filepath.Join("javalib", arch.String())
			for _, f := range files {
				localModule := "javalib_" + arch.String() + "_" + filepath.Base(f.String())
				af := newApexFile(ctx, f, localModule, dirInApex, etc, nil)
				filesInfo = append(filesInfo, af)
			}
		}
		// Call GetGlobalSoongConfig to initialize it, which may be necessary if dexpreopt is
		// disabled for libraries/apps, but boot images are still needed.
		if !java.SkipDexpreoptBootJars(ctx) {
			dexpreopt.GetGlobalSoongConfig(ctx)
		}
	}

	// Remove duplicates in filesInfo
	removeDup := func(filesInfo []apexFile) []apexFile {
		encountered := make(map[string]apexFile)
+103 −3
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
package apex

import (
	"reflect"
	"strings"
	"testing"

	"android/soong/android"
@@ -83,13 +85,39 @@ func TestBootImages(t *testing.T) {
	)

	// Make sure that the framework-boot-image is using the correct configuration.
	checkBootImage(t, ctx, "framework-boot-image", "platform:foo,platform:bar")
	checkBootImage(t, ctx, "framework-boot-image", "platform:foo,platform:bar", `
test_device/dex_bootjars/android/system/framework/arm/boot-foo.art
test_device/dex_bootjars/android/system/framework/arm/boot-foo.oat
test_device/dex_bootjars/android/system/framework/arm/boot-foo.vdex
test_device/dex_bootjars/android/system/framework/arm/boot-bar.art
test_device/dex_bootjars/android/system/framework/arm/boot-bar.oat
test_device/dex_bootjars/android/system/framework/arm/boot-bar.vdex
test_device/dex_bootjars/android/system/framework/arm64/boot-foo.art
test_device/dex_bootjars/android/system/framework/arm64/boot-foo.oat
test_device/dex_bootjars/android/system/framework/arm64/boot-foo.vdex
test_device/dex_bootjars/android/system/framework/arm64/boot-bar.art
test_device/dex_bootjars/android/system/framework/arm64/boot-bar.oat
test_device/dex_bootjars/android/system/framework/arm64/boot-bar.vdex
`)

	// Make sure that the art-boot-image is using the correct configuration.
	checkBootImage(t, ctx, "art-boot-image", "com.android.art:baz,com.android.art:quuz")
	checkBootImage(t, ctx, "art-boot-image", "com.android.art:baz,com.android.art:quuz", `
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.art
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.oat
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot.vdex
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-quuz.art
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-quuz.oat
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm/boot-quuz.vdex
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.art
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.oat
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot.vdex
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-quuz.art
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-quuz.oat
test_device/dex_artjars/android/apex/art_boot_images/javalib/arm64/boot-quuz.vdex
`)
}

func checkBootImage(t *testing.T, ctx *android.TestContext, moduleName string, expectedConfiguredModules string) {
func checkBootImage(t *testing.T, ctx *android.TestContext, moduleName string, expectedConfiguredModules string, expectedBootImageFiles string) {
	t.Helper()

	bootImage := ctx.ModuleForTests(moduleName, "android_common").Module().(*java.BootImageModule)
@@ -99,6 +127,20 @@ func checkBootImage(t *testing.T, ctx *android.TestContext, moduleName string, e
	if actual := modules.String(); actual != expectedConfiguredModules {
		t.Errorf("invalid modules for %s: expected %q, actual %q", moduleName, expectedConfiguredModules, actual)
	}

	// Get a list of all the paths in the boot image sorted by arch type.
	allPaths := []string{}
	bootImageFilesByArchType := bootImageInfo.AndroidBootImageFilesByArchType()
	for _, archType := range android.ArchTypeList() {
		if paths, ok := bootImageFilesByArchType[archType]; ok {
			for _, path := range paths {
				allPaths = append(allPaths, android.NormalizePathForTesting(path))
			}
		}
	}
	if expected, actual := strings.TrimSpace(expectedBootImageFiles), strings.TrimSpace(strings.Join(allPaths, "\n")); !reflect.DeepEqual(expected, actual) {
		t.Errorf("invalid paths for %s: expected \n%s, actual \n%s", moduleName, expected, actual)
	}
}

func modifyDexpreoptConfig(configModifier func(dexpreoptConfig *dexpreopt.GlobalConfig)) func(fs map[string][]byte, config android.Config) {
@@ -126,3 +168,61 @@ func withFrameworkBootImageJars(bootJars ...string) func(fs map[string][]byte, c
		dexpreoptConfig.BootJars = android.CreateTestConfiguredJarList(bootJars)
	})
}

func TestBootImageInApex(t *testing.T) {
	ctx, _ := testApex(t, `
		apex {
			name: "myapex",
			key: "myapex.key",
			boot_images: [
				"mybootimage",
			],
		}

		apex_key {
			name: "myapex.key",
			public_key: "testkey.avbpubkey",
			private_key: "testkey.pem",
		}

		java_library {
			name: "foo",
			srcs: ["b.java"],
			installable: true,
		}

		java_library {
			name: "bar",
			srcs: ["b.java"],
			installable: true,
		}

		boot_image {
			name: "mybootimage",
			image_name: "boot",
			apex_available: [
				"myapex",
			],
		}
`,
		// Configure some libraries in the framework boot image.
		withFrameworkBootImageJars("platform:foo", "platform:bar"),
	)

	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
		"javalib/arm/boot-bar.art",
		"javalib/arm/boot-bar.oat",
		"javalib/arm/boot-bar.vdex",
		"javalib/arm/boot-foo.art",
		"javalib/arm/boot-foo.oat",
		"javalib/arm/boot-foo.vdex",
		"javalib/arm64/boot-bar.art",
		"javalib/arm64/boot-bar.oat",
		"javalib/arm64/boot-bar.vdex",
		"javalib/arm64/boot-foo.art",
		"javalib/arm64/boot-foo.oat",
		"javalib/arm64/boot-foo.vdex",
	})
}

// TODO(b/177892522) - add test for host apex.
+51 −0
Original line number Diff line number Diff line
@@ -15,9 +15,11 @@
package java

import (
	"fmt"
	"strings"

	"android/soong/android"
	"android/soong/dexpreopt"
	"github.com/google/blueprint"
)

@@ -38,6 +40,7 @@ type bootImageProperties struct {

type BootImageModule struct {
	android.ModuleBase
	android.ApexModuleBase

	properties bootImageProperties
}
@@ -46,6 +49,7 @@ func bootImageFactory() android.Module {
	m := &BootImageModule{}
	m.AddProperties(&m.properties)
	android.InitAndroidArchModule(m, android.HostAndDeviceDefault, android.MultilibCommon)
	android.InitApexModule(m)
	return m
}

@@ -53,6 +57,9 @@ var BootImageInfoProvider = blueprint.NewProvider(BootImageInfo{})

type BootImageInfo struct {
	// The image config, internal to this module (and the dex_bootjars singleton).
	//
	// Will be nil if the BootImageInfo has not been provided for a specific module. That can occur
	// when SkipDexpreoptBootJars(ctx) returns true.
	imageConfig *bootImageConfig
}

@@ -60,12 +67,56 @@ func (i BootImageInfo) Modules() android.ConfiguredJarList {
	return i.imageConfig.modules
}

// Get a map from ArchType to the associated boot image's contents for Android.
//
// Extension boot images only return their own files, not the files of the boot images they extend.
func (i BootImageInfo) AndroidBootImageFilesByArchType() map[android.ArchType]android.OutputPaths {
	files := map[android.ArchType]android.OutputPaths{}
	if i.imageConfig != nil {
		for _, variant := range i.imageConfig.variants {
			// We also generate boot images for host (for testing), but we don't need those in the apex.
			// TODO(b/177892522) - consider changing this to check Os.OsClass = android.Device
			if variant.target.Os == android.Android {
				files[variant.target.Arch.ArchType] = variant.imagesDeps
			}
		}
	}
	return files
}

func (b *BootImageModule) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
	tag := ctx.OtherModuleDependencyTag(dep)
	if tag == dexpreopt.Dex2oatDepTag {
		// The dex2oat tool is only needed for building and is not required in the apex.
		return false
	}
	panic(fmt.Errorf("boot_image module %q should not have a dependency on %q via tag %s", b, dep, android.PrettyPrintTag(tag)))
}

func (b *BootImageModule) ShouldSupportSdkVersion(ctx android.BaseModuleContext, sdkVersion android.ApiLevel) error {
	return nil
}

func (b *BootImageModule) DepsMutator(ctx android.BottomUpMutatorContext) {
	if SkipDexpreoptBootJars(ctx) {
		return
	}

	// Add a dependency onto the dex2oat tool which is needed for creating the boot image. The
	// path is retrieved from the dependency by GetGlobalSoongConfig(ctx).
	dexpreopt.RegisterToolDeps(ctx)
}

func (b *BootImageModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
	// Nothing to do if skipping the dexpreopt of boot image jars.
	if SkipDexpreoptBootJars(ctx) {
		return
	}

	// Force the GlobalSoongConfig to be created and cached for use by the dex_bootjars
	// GenerateSingletonBuildActions method as it cannot create it for itself.
	dexpreopt.GetGlobalSoongConfig(ctx)

	// Get a map of the image configs that are supported.
	imageConfigs := genBootImageConfigs(ctx)

+0 −16
Original line number Diff line number Diff line
@@ -392,22 +392,6 @@ type dexpreoptBootJars struct {
	dexpreoptConfigForMake android.WritablePath
}

// Accessor function for the apex package. Returns nil if dexpreopt is disabled.
func DexpreoptedArtApexJars(ctx android.BuilderContext) map[android.ArchType]android.OutputPaths {
	if SkipDexpreoptBootJars(ctx) {
		return nil
	}
	// Include dexpreopt files for the primary boot image.
	files := map[android.ArchType]android.OutputPaths{}
	for _, variant := range artBootImageConfig(ctx).variants {
		// We also generate boot images for host (for testing), but we don't need those in the apex.
		if variant.target.Os == android.Android {
			files[variant.target.Arch.ArchType] = variant.imagesDeps
		}
	}
	return files
}

// Provide paths to boot images for use by modules that depend upon them.
//
// The build rules are created in GenerateSingletonBuildActions().