Loading apex/apex_test.go +18 −19 Original line number Diff line number Diff line Loading @@ -6368,7 +6368,6 @@ func TestAppSetBundle(t *testing.T) { } func TestAppSetBundlePrebuilt(t *testing.T) { ctx := testApex(t, "", android.FixtureModifyMockFS(func(fs android.MockFS) { bp := ` apex_set { name: "myapex", Loading @@ -6377,24 +6376,23 @@ func TestAppSetBundlePrebuilt(t *testing.T) { none: { set: "myapex.apks", }, hwaddress: { set: "myapex.hwasan.apks", }, }, }` fs["Android.bp"] = []byte(bp) }), prepareForTestWithSantitizeHwaddress, ) } ` ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress) m := ctx.ModuleForTests("myapex", "android_common") extractedApex := m.Output("out/soong/.intermediates/myapex/android_common/foo_v2.apex") // Check that the extractor produces the correct output file from the correct input file. extractorOutput := "out/soong/.intermediates/myapex.apex.extractor/android_common/extracted/myapex.hwasan.apks" actual := extractedApex.Inputs if len(actual) != 1 { t.Errorf("expected a single input") } m := ctx.ModuleForTests("myapex.apex.extractor", "android_common") extractedApex := m.Output(extractorOutput) expected := "myapex.hwasan.apks" if actual[0].String() != expected { t.Errorf("expected %s, got %s", expected, actual[0].String()) } android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings()) // 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)) { Loading Loading @@ -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. extractedApex := m.Output("out/soong/.intermediates/myapex/android_common/foo_v2.apex") extractedApex := m.Output("extracted/myapex.apks") actual := extractedApex.Args["abis"] expected := "ARMEABI_V7A,ARM64_V8A" if actual != expected { Loading @@ -7045,6 +7043,7 @@ func TestApexSet(t *testing.T) { t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual) } m = ctx.ModuleForTests("myapex", "android_common") a := m.Module().(*ApexSet) expectedOverrides := []string{"foo"} actualOverrides := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_OVERRIDES_MODULES"] Loading apex/prebuilt.go +109 −43 Original line number Diff line number Diff line Loading @@ -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 { android.ModuleBase prebuiltCommon Loading @@ -533,7 +576,7 @@ type ApexSet struct { postInstallCommands []string } type ApexSetProperties struct { type ApexExtractorProperties struct { // the .apks file path that contains prebuilt apex files to be extracted. Set *string Loading @@ -549,28 +592,14 @@ type ApexSetProperties struct { } } // whether the extracted apex file installable. Installable *bool // optional name for the installed apex. If unspecified, name of the // module is used as the file name Filename *string // names of modules to be overridden. Listed modules can only be other binaries // (in Make or Soong). // This does not completely prevent installation of the overridden binaries, but if both // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed // from PRODUCT_PACKAGES. Overrides []string // apexes in this set use prerelease SDK version Prerelease *bool } func (a *ApexSet) prebuiltSrcs(ctx android.BaseModuleContext) []string { func (e *ApexExtractorProperties) prebuiltSrcs(ctx android.BaseModuleContext) []string { var srcs []string if a.properties.Set != nil { srcs = append(srcs, *a.properties.Set) if e.Set != nil { srcs = append(srcs, *e.Set) } var sanitizers []string Loading @@ -580,17 +609,35 @@ func (a *ApexSet) prebuiltSrcs(ctx android.BaseModuleContext) []string { 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) 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. Installable *bool // optional name for the installed apex. If unspecified, name of the // module is used as the file name Filename *string // names of modules to be overridden. Listed modules can only be other binaries // (in Make or Soong). // This does not completely prevent installation of the overridden binaries, but if both // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed // from PRODUCT_PACKAGES. Overrides []string } func (a *ApexSet) hasSanitizedSource(sanitizer string) bool { if sanitizer == "address" { return a.properties.Sanitized.Address.Set != nil Loading Loading @@ -621,36 +668,55 @@ func (a *ApexSet) Overrides() []string { // prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex. func apexSetFactory() android.Module { module := &ApexSet{} module.AddProperties(&module.properties) module.AddProperties(&module.properties, &module.selectedApexProperties) srcsSupplier := func(ctx android.BaseModuleContext, _ android.Module) []string { return module.prebuiltSrcs(ctx) } android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "set") android.InitSingleSourcePrebuiltModule(module, &module.selectedApexProperties, "Selected_apex") 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), } ctx.CreateModule(privateApexExtractorModuleFactory, &props, apexExtractorProperties, ) } func apexExtractorModuleName(baseModuleName string) string { return baseModuleName + ".apex.extractor" } func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.installFilename = a.InstallFilename() if !strings.HasSuffix(a.installFilename, 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) ctx.Build(pctx, android.BuildParams{ Rule: extractMatchingApex, Description: "Extract an apex from an apex set", Inputs: android.Paths{apexSet}, ctx.Build(pctx, android.BuildParams{ Rule: android.Cp, Input: inputApex, 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) { Loading Loading
apex/apex_test.go +18 −19 Original line number Diff line number Diff line Loading @@ -6368,7 +6368,6 @@ func TestAppSetBundle(t *testing.T) { } func TestAppSetBundlePrebuilt(t *testing.T) { ctx := testApex(t, "", android.FixtureModifyMockFS(func(fs android.MockFS) { bp := ` apex_set { name: "myapex", Loading @@ -6377,24 +6376,23 @@ func TestAppSetBundlePrebuilt(t *testing.T) { none: { set: "myapex.apks", }, hwaddress: { set: "myapex.hwasan.apks", }, }, }` fs["Android.bp"] = []byte(bp) }), prepareForTestWithSantitizeHwaddress, ) } ` ctx := testApex(t, bp, prepareForTestWithSantitizeHwaddress) m := ctx.ModuleForTests("myapex", "android_common") extractedApex := m.Output("out/soong/.intermediates/myapex/android_common/foo_v2.apex") // Check that the extractor produces the correct output file from the correct input file. extractorOutput := "out/soong/.intermediates/myapex.apex.extractor/android_common/extracted/myapex.hwasan.apks" actual := extractedApex.Inputs if len(actual) != 1 { t.Errorf("expected a single input") } m := ctx.ModuleForTests("myapex.apex.extractor", "android_common") extractedApex := m.Output(extractorOutput) expected := "myapex.hwasan.apks" if actual[0].String() != expected { t.Errorf("expected %s, got %s", expected, actual[0].String()) } android.AssertArrayString(t, "extractor input", []string{"myapex.hwasan.apks"}, extractedApex.Inputs.Strings()) // 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)) { Loading Loading @@ -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. extractedApex := m.Output("out/soong/.intermediates/myapex/android_common/foo_v2.apex") extractedApex := m.Output("extracted/myapex.apks") actual := extractedApex.Args["abis"] expected := "ARMEABI_V7A,ARM64_V8A" if actual != expected { Loading @@ -7045,6 +7043,7 @@ func TestApexSet(t *testing.T) { t.Errorf("Unexpected abis parameter - expected %q vs actual %q", expected, actual) } m = ctx.ModuleForTests("myapex", "android_common") a := m.Module().(*ApexSet) expectedOverrides := []string{"foo"} actualOverrides := android.AndroidMkEntriesForTest(t, ctx, a)[0].EntryMap["LOCAL_OVERRIDES_MODULES"] Loading
apex/prebuilt.go +109 −43 Original line number Diff line number Diff line Loading @@ -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 { android.ModuleBase prebuiltCommon Loading @@ -533,7 +576,7 @@ type ApexSet struct { postInstallCommands []string } type ApexSetProperties struct { type ApexExtractorProperties struct { // the .apks file path that contains prebuilt apex files to be extracted. Set *string Loading @@ -549,28 +592,14 @@ type ApexSetProperties struct { } } // whether the extracted apex file installable. Installable *bool // optional name for the installed apex. If unspecified, name of the // module is used as the file name Filename *string // names of modules to be overridden. Listed modules can only be other binaries // (in Make or Soong). // This does not completely prevent installation of the overridden binaries, but if both // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed // from PRODUCT_PACKAGES. Overrides []string // apexes in this set use prerelease SDK version Prerelease *bool } func (a *ApexSet) prebuiltSrcs(ctx android.BaseModuleContext) []string { func (e *ApexExtractorProperties) prebuiltSrcs(ctx android.BaseModuleContext) []string { var srcs []string if a.properties.Set != nil { srcs = append(srcs, *a.properties.Set) if e.Set != nil { srcs = append(srcs, *e.Set) } var sanitizers []string Loading @@ -580,17 +609,35 @@ func (a *ApexSet) prebuiltSrcs(ctx android.BaseModuleContext) []string { 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) 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. Installable *bool // optional name for the installed apex. If unspecified, name of the // module is used as the file name Filename *string // names of modules to be overridden. Listed modules can only be other binaries // (in Make or Soong). // This does not completely prevent installation of the overridden binaries, but if both // binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed // from PRODUCT_PACKAGES. Overrides []string } func (a *ApexSet) hasSanitizedSource(sanitizer string) bool { if sanitizer == "address" { return a.properties.Sanitized.Address.Set != nil Loading Loading @@ -621,36 +668,55 @@ func (a *ApexSet) Overrides() []string { // prebuilt_apex imports an `.apex` file into the build graph as if it was built with apex. func apexSetFactory() android.Module { module := &ApexSet{} module.AddProperties(&module.properties) module.AddProperties(&module.properties, &module.selectedApexProperties) srcsSupplier := func(ctx android.BaseModuleContext, _ android.Module) []string { return module.prebuiltSrcs(ctx) } android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "set") android.InitSingleSourcePrebuiltModule(module, &module.selectedApexProperties, "Selected_apex") 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), } ctx.CreateModule(privateApexExtractorModuleFactory, &props, apexExtractorProperties, ) } func apexExtractorModuleName(baseModuleName string) string { return baseModuleName + ".apex.extractor" } func (a *ApexSet) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.installFilename = a.InstallFilename() if !strings.HasSuffix(a.installFilename, 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) ctx.Build(pctx, android.BuildParams{ Rule: extractMatchingApex, Description: "Extract an apex from an apex set", Inputs: android.Paths{apexSet}, ctx.Build(pctx, android.BuildParams{ Rule: android.Cp, Input: inputApex, 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) { Loading