Merge "Add boot_images to apex"
This commit is contained in:
45
apex/apex.go
45
apex/apex.go
@@ -89,6 +89,9 @@ type apexBundleProperties struct {
|
|||||||
|
|
||||||
Multilib apexMultilibProperties
|
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.
|
// List of java libraries that are embedded inside this APEX bundle.
|
||||||
Java_libs []string
|
Java_libs []string
|
||||||
|
|
||||||
@@ -544,6 +547,7 @@ var (
|
|||||||
certificateTag = dependencyTag{name: "certificate"}
|
certificateTag = dependencyTag{name: "certificate"}
|
||||||
executableTag = dependencyTag{name: "executable", payload: true}
|
executableTag = dependencyTag{name: "executable", payload: true}
|
||||||
fsTag = dependencyTag{name: "filesystem", payload: true}
|
fsTag = dependencyTag{name: "filesystem", payload: true}
|
||||||
|
bootImageTag = dependencyTag{name: "bootImage", payload: true}
|
||||||
javaLibTag = dependencyTag{name: "javaLib", payload: true}
|
javaLibTag = dependencyTag{name: "javaLib", payload: true}
|
||||||
jniLibTag = dependencyTag{name: "jniLib", payload: true}
|
jniLibTag = dependencyTag{name: "jniLib", payload: true}
|
||||||
keyTag = dependencyTag{name: "key"}
|
keyTag = dependencyTag{name: "key"}
|
||||||
@@ -721,6 +725,7 @@ func (a *apexBundle) DepsMutator(ctx android.BottomUpMutatorContext) {
|
|||||||
|
|
||||||
// Common-arch dependencies come next
|
// Common-arch dependencies come next
|
||||||
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
|
commonVariation := ctx.Config().AndroidCommonTarget.Variations()
|
||||||
|
ctx.AddFarVariationDependencies(commonVariation, bootImageTag, a.properties.Boot_images...)
|
||||||
ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
|
ctx.AddFarVariationDependencies(commonVariation, javaLibTag, a.properties.Java_libs...)
|
||||||
ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.properties.Bpfs...)
|
ctx.AddFarVariationDependencies(commonVariation, bpfTag, a.properties.Bpfs...)
|
||||||
ctx.AddFarVariationDependencies(commonVariation, fsTag, a.properties.Filesystems...)
|
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") {
|
if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") {
|
||||||
ctx.AddFarVariationDependencies(commonVariation, javaLibTag, "jacocoagent")
|
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
|
// Dependencies for signing
|
||||||
@@ -1648,6 +1649,23 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
} else {
|
} 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)
|
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:
|
case javaLibTag:
|
||||||
switch child.(type) {
|
switch child.(type) {
|
||||||
case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
|
case *java.Library, *java.SdkLibrary, *java.DexImport, *java.SdkLibraryImport, *java.Import:
|
||||||
@@ -1862,25 +1880,6 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
|||||||
return
|
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
|
// Remove duplicates in filesInfo
|
||||||
removeDup := func(filesInfo []apexFile) []apexFile {
|
removeDup := func(filesInfo []apexFile) []apexFile {
|
||||||
encountered := make(map[string]apexFile)
|
encountered := make(map[string]apexFile)
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
package apex
|
package apex
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"reflect"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
@@ -83,13 +85,39 @@ func TestBootImages(t *testing.T) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Make sure that the framework-boot-image is using the correct configuration.
|
// 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.
|
// 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()
|
t.Helper()
|
||||||
|
|
||||||
bootImage := ctx.ModuleForTests(moduleName, "android_common").Module().(*java.BootImageModule)
|
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 {
|
if actual := modules.String(); actual != expectedConfiguredModules {
|
||||||
t.Errorf("invalid modules for %s: expected %q, actual %q", moduleName, expectedConfiguredModules, actual)
|
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) {
|
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)
|
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.
|
||||||
|
@@ -15,9 +15,11 @@
|
|||||||
package java
|
package java
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"android/soong/android"
|
"android/soong/android"
|
||||||
|
"android/soong/dexpreopt"
|
||||||
"github.com/google/blueprint"
|
"github.com/google/blueprint"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -38,6 +40,7 @@ type bootImageProperties struct {
|
|||||||
|
|
||||||
type BootImageModule struct {
|
type BootImageModule struct {
|
||||||
android.ModuleBase
|
android.ModuleBase
|
||||||
|
android.ApexModuleBase
|
||||||
|
|
||||||
properties bootImageProperties
|
properties bootImageProperties
|
||||||
}
|
}
|
||||||
@@ -46,6 +49,7 @@ func bootImageFactory() android.Module {
|
|||||||
m := &BootImageModule{}
|
m := &BootImageModule{}
|
||||||
m.AddProperties(&m.properties)
|
m.AddProperties(&m.properties)
|
||||||
android.InitAndroidArchModule(m, android.HostAndDeviceDefault, android.MultilibCommon)
|
android.InitAndroidArchModule(m, android.HostAndDeviceDefault, android.MultilibCommon)
|
||||||
|
android.InitApexModule(m)
|
||||||
return m
|
return m
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +57,9 @@ var BootImageInfoProvider = blueprint.NewProvider(BootImageInfo{})
|
|||||||
|
|
||||||
type BootImageInfo struct {
|
type BootImageInfo struct {
|
||||||
// The image config, internal to this module (and the dex_bootjars singleton).
|
// 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
|
imageConfig *bootImageConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,12 +67,56 @@ func (i BootImageInfo) Modules() android.ConfiguredJarList {
|
|||||||
return i.imageConfig.modules
|
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) {
|
func (b *BootImageModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
|
||||||
// Nothing to do if skipping the dexpreopt of boot image jars.
|
// Nothing to do if skipping the dexpreopt of boot image jars.
|
||||||
if SkipDexpreoptBootJars(ctx) {
|
if SkipDexpreoptBootJars(ctx) {
|
||||||
return
|
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.
|
// Get a map of the image configs that are supported.
|
||||||
imageConfigs := genBootImageConfigs(ctx)
|
imageConfigs := genBootImageConfigs(ctx)
|
||||||
|
|
||||||
|
@@ -392,22 +392,6 @@ type dexpreoptBootJars struct {
|
|||||||
dexpreoptConfigForMake android.WritablePath
|
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.
|
// Provide paths to boot images for use by modules that depend upon them.
|
||||||
//
|
//
|
||||||
// The build rules are created in GenerateSingletonBuildActions().
|
// The build rules are created in GenerateSingletonBuildActions().
|
||||||
|
Reference in New Issue
Block a user