Merge "Separate apex extraction from the ApexSet" am: b14f2f067c am: 4cb71138e7

Original change: https://android-review.googlesource.com/c/platform/build/soong/+/1665743

Change-Id: I1b1b9133981cbb09122648f35e5b12670ac40030
This commit is contained in:
Paul Duffin
2021-04-08 14:40:57 +00:00
committed by Automerger Merge Worker
2 changed files with 131 additions and 66 deletions

View File

@@ -6368,8 +6368,7 @@ func TestAppSetBundle(t *testing.T) {
} }
func TestAppSetBundlePrebuilt(t *testing.T) { func TestAppSetBundlePrebuilt(t *testing.T) {
ctx := testApex(t, "", android.FixtureModifyMockFS(func(fs android.MockFS) { bp := `
bp := `
apex_set { apex_set {
name: "myapex", name: "myapex",
filename: "foo_v2.apex", filename: "foo_v2.apex",
@@ -6377,24 +6376,23 @@ func TestAppSetBundlePrebuilt(t *testing.T) {
none: { set: "myapex.apks", }, none: { set: "myapex.apks", },
hwaddress: { set: "myapex.hwasan.apks", }, hwaddress: { set: "myapex.hwasan.apks", },
}, },
}` }
fs["Android.bp"] = []byte(bp) `
}), ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress)
prepareForTestWithSantitizeHwaddress,
)
m := ctx.ModuleForTests("myapex", "android_common") // Check that the extractor produces the correct output file from the correct input file.
extractedApex := m.Output("out/soong/.intermediates/myapex/android_common/foo_v2.apex") extractorOutput := "out/soong/.intermediates/myapex.apex.extractor/android_common/extracted/myapex.hwasan.apks"
actual := extractedApex.Inputs m := ctx.ModuleForTests("myapex.apex.extractor", "android_common")
if len(actual) != 1 { extractedApex := m.Output(extractorOutput)
t.Errorf("expected a single input")
}
expected := "myapex.hwasan.apks" android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings())
if actual[0].String() != expected {
t.Errorf("expected %s, got %s", expected, actual[0].String()) // Ditto for the apex.
} m = ctx.ModuleForTests("myapex", "android_common")
copiedApex := m.Output("out/soong/.intermediates/myapex/android_common/foo_v2.apex")
android.AssertStringEquals(t, "myapex input", extractorOutput, copiedApex.Input.String())
} }
func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) { func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) {
@@ -7030,10 +7028,10 @@ func TestApexSet(t *testing.T) {
}), }),
) )
m := ctx.ModuleForTests("myapex", "android_common") m := ctx.ModuleForTests("myapex.apex.extractor", "android_common")
// Check extract_apks tool parameters. // Check extract_apks tool parameters.
extractedApex := m.Output("out/soong/.intermediates/myapex/android_common/foo_v2.apex") extractedApex := m.Output("extracted/myapex.apks")
actual := extractedApex.Args["abis"] actual := extractedApex.Args["abis"]
expected := "ARMEABI_V7A,ARM64_V8A" expected := "ARMEABI_V7A,ARM64_V8A"
if actual != expected { if actual != expected {
@@ -7045,6 +7043,7 @@ func TestApexSet(t *testing.T) {
t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual) t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual)
} }
m = ctx.ModuleForTests("myapex", "android_common")
a := m.Module().(*ApexSet) a := m.Module().(*ApexSet)
expectedOverrides := []string{"foo"} expectedOverrides := []string{"foo"}
actualOverrides := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_OVERRIDES_MODULES"] actualOverrides := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_OVERRIDES_MODULES"]

View File

@@ -515,6 +515,49 @@ func (p *Prebuilt) AndroidMkEntries() []android.AndroidMkEntries {
}} }}
} }
// prebuiltApexExtractorModule is a private module type that is only created by the prebuilt_apex
// module. It extracts the correct apex to use and makes it available for use by apex_set.
type prebuiltApexExtractorModule struct {
android.ModuleBase
properties ApexExtractorProperties
extractedApex android.WritablePath
}
func privateApexExtractorModuleFactory() android.Module {
module := &prebuiltApexExtractorModule{}
module.AddProperties(
&module.properties,
)
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
return module
}
func (p *prebuiltApexExtractorModule) Srcs() android.Paths {
return android.Paths{p.extractedApex}
}
func (p *prebuiltApexExtractorModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
srcsSupplier := func(ctx android.BaseModuleContext, prebuilt android.Module) []string {
return p.properties.prebuiltSrcs(ctx)
}
apexSet := android.SingleSourcePathFromSupplier(ctx, srcsSupplier, "set")
p.extractedApex = android.PathForModuleOut(ctx, "extracted", apexSet.Base())
ctx.Build(pctx,
android.BuildParams{
Rule: extractMatchingApex,
Description: "Extract an apex from an apex set",
Inputs: android.Paths{apexSet},
Output: p.extractedApex,
Args: map[string]string{
"abis": strings.Join(java.SupportedAbis(ctx), ","),
"allow-prereleased": strconv.FormatBool(proptools.Bool(p.properties.Prerelease)),
"sdk-version": ctx.Config().PlatformSdkVersion().String(),
},
})
}
type ApexSet struct { type ApexSet struct {
android.ModuleBase android.ModuleBase
prebuiltCommon prebuiltCommon
@@ -533,7 +576,7 @@ type ApexSet struct {
postInstallCommands []string postInstallCommands []string
} }
type ApexSetProperties struct { type ApexExtractorProperties struct {
// the .apks file path that contains prebuilt apex files to be extracted. // the .apks file path that contains prebuilt apex files to be extracted.
Set *string Set *string
@@ -549,6 +592,37 @@ type ApexSetProperties struct {
} }
} }
// apexes in this set use prerelease SDK version
Prerelease *bool
}
func (e *ApexExtractorProperties) prebuiltSrcs(ctx android.BaseModuleContext) []string {
var srcs []string
if e.Set != nil {
srcs = append(srcs, *e.Set)
}
var sanitizers []string
if ctx.Host() {
sanitizers = ctx.Config().SanitizeHost()
} else {
sanitizers = ctx.Config().SanitizeDevice()
}
if android.InList("address", sanitizers) && e.Sanitized.Address.Set != nil {
srcs = append(srcs, *e.Sanitized.Address.Set)
} else if android.InList("hwaddress", sanitizers) && e.Sanitized.Hwaddress.Set != nil {
srcs = append(srcs, *e.Sanitized.Hwaddress.Set)
} else if e.Sanitized.None.Set != nil {
srcs = append(srcs, *e.Sanitized.None.Set)
}
return srcs
}
type ApexSetProperties struct {
ApexExtractorProperties
// whether the extracted apex file installable. // whether the extracted apex file installable.
Installable *bool Installable *bool
@@ -562,33 +636,6 @@ type ApexSetProperties struct {
// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
// from PRODUCT_PACKAGES. // from PRODUCT_PACKAGES.
Overrides []string Overrides []string
// apexes in this set use prerelease SDK version
Prerelease *bool
}
func (a *ApexSet) prebuiltSrcs(ctx android.BaseModuleContext) []string {
var srcs []string
if a.properties.Set != nil {
srcs = append(srcs, *a.properties.Set)
}
var sanitizers []string
if ctx.Host() {
sanitizers = ctx.Config().SanitizeHost()
} else {
sanitizers = ctx.Config().SanitizeDevice()
}
if android.InList("address", sanitizers) && a.properties.Sanitized.Address.Set != nil {
srcs = append(srcs, *a.properties.Sanitized.Address.Set)
} else if android.InList("hwaddress", sanitizers) && a.properties.Sanitized.Hwaddress.Set != nil {
srcs = append(srcs, *a.properties.Sanitized.Hwaddress.Set)
} else if a.properties.Sanitized.None.Set != nil {
srcs = append(srcs, *a.properties.Sanitized.None.Set)
}
return srcs
} }
func (a *ApexSet) hasSanitizedSource(sanitizer string) bool { func (a *ApexSet) hasSanitizedSource(sanitizer string) bool {
@@ -621,15 +668,41 @@ func (a *ApexSet) Overrides() []string {
// prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex. // prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex.
func apexSetFactory() android.Module { func apexSetFactory() android.Module {
module := &ApexSet{} module := &ApexSet{}
module.AddProperties(&module.properties) module.AddProperties(&module.properties, &module.selectedApexProperties)
srcsSupplier := func(ctx android.BaseModuleContext, _ android.Module) []string { android.InitSingleSourcePrebuiltModule(module, &module.selectedApexProperties, "Selected_apex")
return module.prebuiltSrcs(ctx) android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
baseModuleName := module.BaseModuleName()
apexExtractorModuleName := apexExtractorModuleName(baseModuleName)
createApexExtractorModule(ctx, apexExtractorModuleName, &module.properties.ApexExtractorProperties)
apexFileSource := ":" + apexExtractorModuleName
// After passing the arch specific src properties to the creating the apex selector module
module.selectedApexProperties.Selected_apex = proptools.StringPtr(apexFileSource)
})
return module
}
func createApexExtractorModule(ctx android.LoadHookContext, name string, apexExtractorProperties *ApexExtractorProperties) {
props := struct {
Name *string
}{
Name: proptools.StringPtr(name),
} }
android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "set") ctx.CreateModule(privateApexExtractorModuleFactory,
android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon) &props,
return module apexExtractorProperties,
)
}
func apexExtractorModuleName(baseModuleName string) string {
return baseModuleName + ".apex.extractor"
} }
func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -638,20 +711,13 @@ func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
ctx.ModuleErrorf("filename should end in %s for apex_set", imageApexSuffix) ctx.ModuleErrorf("filename should end in %s for apex_set", imageApexSuffix)
} }
apexSet := a.prebuiltCommon.prebuilt.SingleSourcePath(ctx) inputApex := android.OptionalPathForModuleSrc(ctx, a.selectedApexProperties.Selected_apex).Path()
a.outputApex = android.PathForModuleOut(ctx, a.installFilename) a.outputApex = android.PathForModuleOut(ctx, a.installFilename)
ctx.Build(pctx, ctx.Build(pctx, android.BuildParams{
android.BuildParams{ Rule: android.Cp,
Rule: extractMatchingApex, Input: inputApex,
Description: "Extract an apex from an apex set", Output: a.outputApex,
Inputs: android.Paths{apexSet}, })
Output: a.outputApex,
Args: map[string]string{
"abis": strings.Join(java.SupportedAbis(ctx), ","),
"allow-prereleased": strconv.FormatBool(proptools.Bool(a.properties.Prerelease)),
"sdk-version": ctx.Config().PlatformSdkVersion().String(),
},
})
if a.prebuiltCommon.checkForceDisable(ctx) { if a.prebuiltCommon.checkForceDisable(ctx) {
a.HideFromMake() a.HideFromMake()