From f3d1e8c24cba69b93d9fdd2f01d770927988eeb1 Mon Sep 17 00:00:00 2001 From: Shikha Panwar Date: Wed, 21 Dec 2022 12:54:45 +0000 Subject: Expose avb_hash_algorithm as a property. When avb_hash_algorithm is set, for filesystem type build targets, add_hashtree_footer will be called with the appropriate --hash_algorithm flag. Bug: 262892300 Test: Build succeeds Merged-In: If2f9c9aa1e98314b3d3e2f8bf25c1bab193f908e Merged-In: Ief4b0f0fd89ebf64b45b29962a3811698bc922d6 Change-Id: I3bf5aecbfd717036a5b167696b107ee6cb1830b4 --- filesystem/filesystem.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/filesystem/filesystem.go b/filesystem/filesystem.go index ccf9e9d3b..665faaaed 100644 --- a/filesystem/filesystem.go +++ b/filesystem/filesystem.go @@ -66,9 +66,13 @@ type filesystemProperties struct { // TODO(jiyong): allow apex_key to be specified here Avb_private_key *string `android:"path"` - // Hash and signing algorithm for avbtool. Default is SHA256_RSA4096. + // Signing algorithm for avbtool. Default is SHA256_RSA4096. Avb_algorithm *string + // Hash algorithm used for avbtool (for descriptors). This is passed as hash_algorithm to + // avbtool. Default used by avbtool is sha1. + Avb_hash_algorithm *string + // Name of the partition stored in vbmeta desc. Defaults to the name of this module. Partition_name *string @@ -318,7 +322,11 @@ func (f *filesystem) buildPropFile(ctx android.ModuleContext) (propFile android. addStr("avb_algorithm", algorithm) key := android.PathForModuleSrc(ctx, proptools.String(f.properties.Avb_private_key)) addPath("avb_key_path", key) - addStr("avb_add_hashtree_footer_args", "--do_not_generate_fec") + avb_add_hashtree_footer_args := "--do_not_generate_fec" + if hashAlgorithm := proptools.String(f.properties.Avb_hash_algorithm); hashAlgorithm != "" { + avb_add_hashtree_footer_args += " --hash_algorithm " + hashAlgorithm + } + addStr("avb_add_hashtree_footer_args", avb_add_hashtree_footer_args) partitionName := proptools.StringDefault(f.properties.Partition_name, f.Name()) addStr("partition_name", partitionName) } -- cgit v1.2.3 From dc4f18317d0e296961a5569424f9038296697275 Mon Sep 17 00:00:00 2001 From: Bob Hanji Date: Thu, 5 Jan 2023 18:03:03 +0000 Subject: Revert^3 "Revert "update MultiAbiTargeting matching logic"" 1cc8ed5dee39e5a4c1def3e0304c28d284fb1368 Bug: 263438687 Change-Id: I7d8585c97ca1e9a960d9725135f99579b0ae5762 Merged-In: Ic3b067e98a65146cfa399e7c9b231f397e51c23e --- cmd/extract_apks/main.go | 90 +++++++++-- cmd/extract_apks/main_test.go | 364 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 438 insertions(+), 16 deletions(-) diff --git a/cmd/extract_apks/main.go b/cmd/extract_apks/main.go index 1cf64de8b..e39f8d765 100644 --- a/cmd/extract_apks/main.go +++ b/cmd/extract_apks/main.go @@ -29,6 +29,7 @@ import ( "google.golang.org/protobuf/proto" + "android/soong/cmd/extract_apks/bundle_proto" android_bundle_proto "android/soong/cmd/extract_apks/bundle_proto" "android/soong/third_party/zip" ) @@ -197,6 +198,49 @@ type multiAbiTargetingMatcher struct { *android_bundle_proto.MultiAbiTargeting } +type multiAbiValue []*bundle_proto.Abi + +func (m multiAbiValue) compare(other multiAbiValue) int { + min := func(a, b int) int { + if a < b { + return a + } + return b + } + + sortAbis := func(abiSlice multiAbiValue) func(i, j int) bool { + return func(i, j int) bool { + // sort priorities greatest to least + return multiAbiPriorities[abiSlice[i].Alias] > multiAbiPriorities[abiSlice[j].Alias] + } + } + + m = append(multiAbiValue{}, m...) + sort.Slice(m, sortAbis(m)) + other = append(multiAbiValue{}, other...) + sort.Slice(other, sortAbis(other)) + + for i := 0; i < min(len(m), len(other)); i++ { + if multiAbiPriorities[m[i].Alias] > multiAbiPriorities[other[i].Alias] { + return 1 + } + if multiAbiPriorities[m[i].Alias] < multiAbiPriorities[other[i].Alias] { + return -1 + } + } + + if len(m) == len(other) { + return 0 + } + if len(m) > len(other) { + return 1 + } + return -1 +} + +// this logic should match the logic in bundletool at +// https://github.com/google/bundletool/blob/ae0fc0162fd80d92ef8f4ef4527c066f0106942f/src/main/java/com/android/tools/build/bundletool/device/MultiAbiMatcher.java#L43 +// (note link is the commit at time of writing; but logic should always match the latest) func (t multiAbiTargetingMatcher) matches(config TargetConfig) bool { if t.MultiAbiTargeting == nil { return true @@ -204,31 +248,45 @@ func (t multiAbiTargetingMatcher) matches(config TargetConfig) bool { if _, ok := config.abis[android_bundle_proto.Abi_UNSPECIFIED_CPU_ARCHITECTURE]; ok { return true } - // Find the one with the highest priority. - highestPriority := 0 - for _, v := range t.GetValue() { - for _, a := range v.GetAbi() { - if _, ok := config.abis[a.Alias]; ok { - if highestPriority < multiAbiPriorities[a.Alias] { - highestPriority = multiAbiPriorities[a.Alias] - } + + multiAbiIsValid := func(m multiAbiValue) bool { + for _, abi := range m { + if _, ok := config.abis[abi.Alias]; !ok { + return false } } + return true + } + + // ensure that the current value is valid for our config + valueSetContainsViableAbi := false + multiAbiSet := t.GetValue() + for _, multiAbi := range multiAbiSet { + if multiAbiIsValid(multiAbi.GetAbi()) { + valueSetContainsViableAbi = true + } } - if highestPriority == 0 { + + if !valueSetContainsViableAbi { return false } + // See if there are any matching alternatives with a higher priority. - for _, v := range t.GetAlternatives() { - for _, a := range v.GetAbi() { - if _, ok := config.abis[a.Alias]; ok { - if highestPriority < multiAbiPriorities[a.Alias] { - // There's a better one. Skip this one. - return false - } + for _, altMultiAbi := range t.GetAlternatives() { + if !multiAbiIsValid(altMultiAbi.GetAbi()) { + continue + } + + for _, multiAbi := range multiAbiSet { + valueAbis := multiAbiValue(multiAbi.GetAbi()) + altAbis := multiAbiValue(altMultiAbi.GetAbi()) + if valueAbis.compare(altAbis) < 0 { + // An alternative has a higher priority, don't use this one + return false } } } + return true } diff --git a/cmd/extract_apks/main_test.go b/cmd/extract_apks/main_test.go index f5e40466a..c1d712df4 100644 --- a/cmd/extract_apks/main_test.go +++ b/cmd/extract_apks/main_test.go @@ -420,6 +420,370 @@ bundletool { } } +func TestSelectApks_ApexSet_Variants(t *testing.T) { + testCases := []testDesc{ + { + protoText: ` +variant { + targeting { + sdk_version_targeting {value {min {value: 29}}} + multi_abi_targeting { + value {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + apk_set { + module_metadata { + name: "base" + delivery_type: INSTALL_TIME + } + apk_description { + targeting { + multi_abi_targeting { + value {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + path: "standalones/standalone-armeabi_v7a.apex" + } + } + variant_number: 0 +} +variant { + targeting { + sdk_version_targeting {value {min {value: 29}}} + multi_abi_targeting { + value {abi {alias: ARM64_V8A}} + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + apk_set { + module_metadata { + name: "base" + delivery_type: INSTALL_TIME + } + apk_description { + targeting { + multi_abi_targeting { + value {abi {alias: ARM64_V8A}} + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + path: "standalones/standalone-arm64_v8a.apex" + } + } + variant_number: 1 +} +variant { + targeting { + sdk_version_targeting {value {min {value: 29}}} + multi_abi_targeting { + value { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARMEABI_V7A}} + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + apk_set { + module_metadata { + name: "base" + delivery_type: INSTALL_TIME + } + apk_description { + targeting { + multi_abi_targeting { + value { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARMEABI_V7A}} + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + path: "standalones/standalone-armeabi_v7a.arm64_v8a.apex" + } + } + variant_number: 2 +} +variant { + targeting { + sdk_version_targeting {value {min {value: 29}}} + multi_abi_targeting { + value {abi {alias: X86}} + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + apk_set { + module_metadata { + name: "base" + delivery_type: INSTALL_TIME + } + apk_description { + targeting { + multi_abi_targeting { + value {abi {alias: X86}} + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives { + abi {alias: X86} + abi {alias: X86_64} + } + } + } + path: "standalones/standalone-x86.apex" + } + } + variant_number: 3 +} +variant { + targeting { + sdk_version_targeting {value {min {value: 29}}} + multi_abi_targeting { + value { + abi {alias: X86} + abi {alias: X86_64} + } + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + } + } + apk_set { + module_metadata { + name: "base" + delivery_type: INSTALL_TIME + } + apk_description { + targeting { + multi_abi_targeting { + value { + abi {alias: X86} + abi {alias: X86_64} + } + alternatives {abi {alias: ARMEABI_V7A}} + alternatives { + abi {alias: ARMEABI_V7A} + abi {alias: ARM64_V8A} + } + alternatives {abi {alias: ARM64_V8A}} + alternatives {abi {alias: X86}} + } + } + path: "standalones/standalone-x86.x86_64.apex" + } + } + variant_number: 4 +} +`, + configs: []testConfigDesc{ + { + name: "multi-variant multi-target ARM", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_ARM64_V8A: 0, + bp.Abi_ARMEABI_V7A: 1, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-armeabi_v7a.arm64_v8a.apex", + }, + }, + }, + { + name: "multi-variant single-target arm", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_ARMEABI_V7A: 0, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-armeabi_v7a.apex", + }, + }, + }, + { + name: "multi-variant single-target arm64", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_ARM64_V8A: 0, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-arm64_v8a.apex", + }, + }, + }, + { + name: "multi-variant multi-target x86", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_X86: 0, + bp.Abi_X86_64: 1, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-x86.x86_64.apex", + }, + }, + }, + { + name: "multi-variant single-target x86", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_X86: 0, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-x86.apex", + }, + }, + }, + { + name: "multi-variant single-target x86_64", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_X86_64: 0, + }, + }, + expected: SelectionResult{}, + }, + { + name: "multi-variant multi-target cross-target", + targetConfig: TargetConfig{ + sdkVersion: 33, + screenDpi: map[bp.ScreenDensity_DensityAlias]bool{ + bp.ScreenDensity_DENSITY_UNSPECIFIED: true, + }, + abis: map[bp.Abi_AbiAlias]int{ + bp.Abi_ARM64_V8A: 0, + bp.Abi_X86_64: 1, + }, + }, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-arm64_v8a.apex", + }, + }, + }, + }, + }, + } + for _, testCase := range testCases { + var toc bp.BuildApksResult + if err := prototext.Unmarshal([]byte(testCase.protoText), &toc); err != nil { + t.Fatal(err) + } + for _, config := range testCase.configs { + t.Run(config.name, func(t *testing.T) { + actual := selectApks(&toc, config.targetConfig) + if !reflect.DeepEqual(config.expected, actual) { + t.Errorf("expected %v, got %v", config.expected, actual) + } + }) + } + } +} + type testZip2ZipWriter struct { entries map[string]string } -- cgit v1.2.3 From d706f71090fa24eec4fb7209125d738524e22174 Mon Sep 17 00:00:00 2001 From: Sam Delmerico Date: Tue, 22 Nov 2022 17:47:59 -0500 Subject: extract_apks matches APKs with >= 1 matching ABI Prior to this change, the bundletool and extract_apks tools require that all ABIs that an APEX or APK provides must be compatible with the TargetConfig. Instead, this change allows an APK to be selected if it has at least one compatible ABI with the TargetConfig. Bug: 260115309 Bug: 269311816 Test: go test . Change-Id: If67ce8128099611257a834862295a2bf5fa427d3 (cherry picked from commit b48d57bdcdcae3c3eb0b823bdf952d74e5502412) Merged-In: If67ce8128099611257a834862295a2bf5fa427d3 --- cmd/extract_apks/main.go | 100 ++++++++++++++++++++++++------------------ cmd/extract_apks/main_test.go | 6 ++- 2 files changed, 62 insertions(+), 44 deletions(-) diff --git a/cmd/extract_apks/main.go b/cmd/extract_apks/main.go index e39f8d765..c5ec9f72e 100644 --- a/cmd/extract_apks/main.go +++ b/cmd/extract_apks/main.go @@ -132,21 +132,21 @@ type apkDescriptionMatcher struct { *android_bundle_proto.ApkDescription } -func (m apkDescriptionMatcher) matches(config TargetConfig) bool { - return m.ApkDescription == nil || (apkTargetingMatcher{m.Targeting}).matches(config) +func (m apkDescriptionMatcher) matches(config TargetConfig, allAbisMustMatch bool) bool { + return m.ApkDescription == nil || (apkTargetingMatcher{m.Targeting}).matches(config, allAbisMustMatch) } type apkTargetingMatcher struct { *android_bundle_proto.ApkTargeting } -func (m apkTargetingMatcher) matches(config TargetConfig) bool { +func (m apkTargetingMatcher) matches(config TargetConfig, allAbisMustMatch bool) bool { return m.ApkTargeting == nil || (abiTargetingMatcher{m.AbiTargeting}.matches(config) && languageTargetingMatcher{m.LanguageTargeting}.matches(config) && screenDensityTargetingMatcher{m.ScreenDensityTargeting}.matches(config) && sdkVersionTargetingMatcher{m.SdkVersionTargeting}.matches(config) && - multiAbiTargetingMatcher{m.MultiAbiTargeting}.matches(config)) + multiAbiTargetingMatcher{m.MultiAbiTargeting}.matches(config, allAbisMustMatch)) } type languageTargetingMatcher struct { @@ -215,33 +215,27 @@ func (m multiAbiValue) compare(other multiAbiValue) int { } } - m = append(multiAbiValue{}, m...) - sort.Slice(m, sortAbis(m)) - other = append(multiAbiValue{}, other...) - sort.Slice(other, sortAbis(other)) + sortedM := append(multiAbiValue{}, m...) + sort.Slice(sortedM, sortAbis(sortedM)) + sortedOther := append(multiAbiValue{}, other...) + sort.Slice(sortedOther, sortAbis(sortedOther)) - for i := 0; i < min(len(m), len(other)); i++ { - if multiAbiPriorities[m[i].Alias] > multiAbiPriorities[other[i].Alias] { + for i := 0; i < min(len(sortedM), len(sortedOther)); i++ { + if multiAbiPriorities[sortedM[i].Alias] > multiAbiPriorities[sortedOther[i].Alias] { return 1 } - if multiAbiPriorities[m[i].Alias] < multiAbiPriorities[other[i].Alias] { + if multiAbiPriorities[sortedM[i].Alias] < multiAbiPriorities[sortedOther[i].Alias] { return -1 } } - if len(m) == len(other) { - return 0 - } - if len(m) > len(other) { - return 1 - } - return -1 + return len(sortedM) - len(sortedOther) } // this logic should match the logic in bundletool at // https://github.com/google/bundletool/blob/ae0fc0162fd80d92ef8f4ef4527c066f0106942f/src/main/java/com/android/tools/build/bundletool/device/MultiAbiMatcher.java#L43 // (note link is the commit at time of writing; but logic should always match the latest) -func (t multiAbiTargetingMatcher) matches(config TargetConfig) bool { +func (t multiAbiTargetingMatcher) matches(config TargetConfig, allAbisMustMatch bool) bool { if t.MultiAbiTargeting == nil { return true } @@ -250,12 +244,19 @@ func (t multiAbiTargetingMatcher) matches(config TargetConfig) bool { } multiAbiIsValid := func(m multiAbiValue) bool { + numValid := 0 for _, abi := range m { - if _, ok := config.abis[abi.Alias]; !ok { - return false + if _, ok := config.abis[abi.Alias]; ok { + numValid += 1 } } - return true + if numValid == 0 { + return false + } else if numValid > 0 && !allAbisMustMatch { + return true + } else { + return numValid == len(m) + } } // ensure that the current value is valid for our config @@ -264,6 +265,7 @@ func (t multiAbiTargetingMatcher) matches(config TargetConfig) bool { for _, multiAbi := range multiAbiSet { if multiAbiIsValid(multiAbi.GetAbi()) { valueSetContainsViableAbi = true + break } } @@ -362,13 +364,13 @@ type variantTargetingMatcher struct { *android_bundle_proto.VariantTargeting } -func (m variantTargetingMatcher) matches(config TargetConfig) bool { +func (m variantTargetingMatcher) matches(config TargetConfig, allAbisMustMatch bool) bool { if m.VariantTargeting == nil { return true } return sdkVersionTargetingMatcher{m.SdkVersionTargeting}.matches(config) && abiTargetingMatcher{m.AbiTargeting}.matches(config) && - multiAbiTargetingMatcher{m.MultiAbiTargeting}.matches(config) && + multiAbiTargetingMatcher{m.MultiAbiTargeting}.matches(config, allAbisMustMatch) && screenDensityTargetingMatcher{m.ScreenDensityTargeting}.matches(config) && textureCompressionFormatTargetingMatcher{m.TextureCompressionFormatTargeting}.matches(config) } @@ -380,30 +382,42 @@ type SelectionResult struct { // Return all entries matching target configuration func selectApks(toc Toc, targetConfig TargetConfig) SelectionResult { - var result SelectionResult - for _, variant := range (*toc).GetVariant() { - if !(variantTargetingMatcher{variant.GetTargeting()}.matches(targetConfig)) { - continue - } - for _, as := range variant.GetApkSet() { - if !(moduleMetadataMatcher{as.ModuleMetadata}.matches(targetConfig)) { + checkMatching := func(allAbisMustMatch bool) SelectionResult { + var result SelectionResult + for _, variant := range (*toc).GetVariant() { + if !(variantTargetingMatcher{variant.GetTargeting()}.matches(targetConfig, allAbisMustMatch)) { continue } - for _, apkdesc := range as.GetApkDescription() { - if (apkDescriptionMatcher{apkdesc}).matches(targetConfig) { - result.entries = append(result.entries, apkdesc.GetPath()) - // TODO(asmundak): As it turns out, moduleName which we get from - // the ModuleMetadata matches the module names of the generated - // entry paths just by coincidence, only for the split APKs. We - // need to discuss this with bundletool folks. - result.moduleName = as.GetModuleMetadata().GetName() + for _, as := range variant.GetApkSet() { + if !(moduleMetadataMatcher{as.ModuleMetadata}.matches(targetConfig)) { + continue + } + for _, apkdesc := range as.GetApkDescription() { + if (apkDescriptionMatcher{apkdesc}).matches(targetConfig, allAbisMustMatch) { + result.entries = append(result.entries, apkdesc.GetPath()) + // TODO(asmundak): As it turns out, moduleName which we get from + // the ModuleMetadata matches the module names of the generated + // entry paths just by coincidence, only for the split APKs. We + // need to discuss this with bundletool folks. + result.moduleName = as.GetModuleMetadata().GetName() + } + } + // we allow only a single module, so bail out here if we found one + if result.moduleName != "" { + return result } - } - // we allow only a single module, so bail out here if we found one - if result.moduleName != "" { - return result } } + return result + } + result := checkMatching(true) + if result.moduleName == "" { + // if there are no matches where all of the ABIs are available in the + // TargetConfig, then search again with a looser requirement of at + // least one matching ABI + // NOTE(b/260130686): this logic diverges from the logic in bundletool + // https://github.com/google/bundletool/blob/ae0fc0162fd80d92ef8f4ef4527c066f0106942f/src/main/java/com/android/tools/build/bundletool/device/MultiAbiMatcher.java#L43 + result = checkMatching(false) } return result } diff --git a/cmd/extract_apks/main_test.go b/cmd/extract_apks/main_test.go index c1d712df4..9f52877c9 100644 --- a/cmd/extract_apks/main_test.go +++ b/cmd/extract_apks/main_test.go @@ -744,7 +744,11 @@ variant { bp.Abi_X86_64: 0, }, }, - expected: SelectionResult{}, + expected: SelectionResult{ + "base", + []string{ + "standalones/standalone-x86.x86_64.apex", + }}, }, { name: "multi-variant multi-target cross-target", -- cgit v1.2.3 From 144be1f8aa798fc7f00004ab76db93b955880e32 Mon Sep 17 00:00:00 2001 From: Anton Hansson Date: Fri, 25 Nov 2022 14:06:46 +0000 Subject: Ignore native bridge archs for apex selection This leads to an arm64 apex being used on a device that is mixed x86_64 with nativebridge=arm64. A device like that doesn't appear to work with arm64 binaries. For example, the boringssl-self-check binary crashes on boot. Bug: 260115309 Bug: 268224524 Test: unit test Test: boot emulator with this combination Change-Id: Ic4a91974290a05b1799f755fcf52ef226d68f4c2 (cherry picked from commit 805e0a53ef53299878643dffbb7641c21892bcfe) Merged-In: Ic4a91974290a05b1799f755fcf52ef226d68f4c2 --- apex/apex_test.go | 24 ++++++++++++++++++++++++ apex/prebuilt.go | 5 ++++- java/app_set.go | 7 +++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/apex/apex_test.go b/apex/apex_test.go index b3036b1fa..0351cb8a3 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -8254,6 +8254,30 @@ func TestApexSet(t *testing.T) { } } +func TestApexSet_NativeBridge(t *testing.T) { + ctx := testApex(t, ` + apex_set { + name: "myapex", + set: "myapex.apks", + filename: "foo_v2.apex", + overrides: ["foo"], + } + `, + android.FixtureModifyConfig(func(config android.Config) { + config.Targets[android.Android] = []android.Target{ + {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "", Abi: []string{"x86_64"}}}, + {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeEnabled}, + } + }), + ) + + m := ctx.ModuleForTests("myapex.apex.extractor", "android_common") + + // Check extract_apks tool parameters. No native bridge arch expected + extractedApex := m.Output("extracted/myapex.apks") + android.AssertStringEquals(t, "abis", "X86_64", extractedApex.Args["abis"]) +} + func TestNoStaticLinkingToStubsLib(t *testing.T) { testApexError(t, `.*required by "mylib" is a native library providing stub.*`, ` apex { diff --git a/apex/prebuilt.go b/apex/prebuilt.go index 187e0df09..03ee11ef5 100644 --- a/apex/prebuilt.go +++ b/apex/prebuilt.go @@ -24,6 +24,7 @@ import ( "android/soong/android" "android/soong/java" "android/soong/provenance" + "github.com/google/blueprint" "github.com/google/blueprint/proptools" ) @@ -817,6 +818,8 @@ func (p *prebuiltApexExtractorModule) GenerateAndroidBuildActions(ctx android.Mo } apexSet := android.SingleSourcePathFromSupplier(ctx, srcsSupplier, "set") p.extractedApex = android.PathForModuleOut(ctx, "extracted", apexSet.Base()) + // Filter out NativeBridge archs (b/260115309) + abis := java.SupportedAbis(ctx, true) ctx.Build(pctx, android.BuildParams{ Rule: extractMatchingApex, @@ -824,7 +827,7 @@ func (p *prebuiltApexExtractorModule) GenerateAndroidBuildActions(ctx android.Mo Inputs: android.Paths{apexSet}, Output: p.extractedApex, Args: map[string]string{ - "abis": strings.Join(java.SupportedAbis(ctx), ","), + "abis": strings.Join(abis, ","), "allow-prereleased": strconv.FormatBool(proptools.Bool(p.properties.Prerelease)), "sdk-version": ctx.Config().PlatformSdkVersion().String(), }, diff --git a/java/app_set.go b/java/app_set.go index 694b1670e..defb4cbf7 100644 --- a/java/app_set.go +++ b/java/app_set.go @@ -96,7 +96,7 @@ var TargetCpuAbi = map[string]string{ "x86_64": "X86_64", } -func SupportedAbis(ctx android.ModuleContext) []string { +func SupportedAbis(ctx android.ModuleContext, excludeNativeBridgeAbis bool) []string { abiName := func(targetIdx int, deviceArch string) string { if abi, found := TargetCpuAbi[deviceArch]; found { return abi @@ -107,6 +107,9 @@ func SupportedAbis(ctx android.ModuleContext) []string { var result []string for i, target := range ctx.Config().Targets[android.Android] { + if target.NativeBridge == android.NativeBridgeEnabled && excludeNativeBridgeAbis { + continue + } result = append(result, abiName(i, target.Arch.ArchType.String())) } return result @@ -133,7 +136,7 @@ func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) ImplicitOutputs: android.WritablePaths{as.packedOutput, as.apkcertsFile}, Inputs: android.Paths{as.prebuilt.SingleSourcePath(ctx)}, Args: map[string]string{ - "abis": strings.Join(SupportedAbis(ctx), ","), + "abis": strings.Join(SupportedAbis(ctx, false), ","), "allow-prereleased": strconv.FormatBool(proptools.Bool(as.properties.Prerelease)), "screen-densities": screenDensities, "sdk-version": ctx.Config().PlatformSdkVersion().String(), -- cgit v1.2.3 From 8ab8056a4f9de6cec1fdedc7d49502439ea7aef6 Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Tue, 27 Sep 2022 12:41:52 +0100 Subject: java_sdk_library_import: Copy all prebuilt properties to child modules Previously, only the prefer property was copied from the java_sdk_library_import module to its child modules which meant that if the use_source_config_var property was used to control the prefer property that the child modules would never be used. That can cause build breakages when building against prebuilts as some parts of the build will use prebuilt files from java_sdk_library_import and some will use source files from the corresponding java_sdk_library. This change copies the use_source_config_var property too. It also adds tests to verify that dependencies on child modules of a java_sdk_library use the prebuilt child modules of the corresponding java_sdk_library_import. That revealed a bug with the handling of stub sources where the prefer property was set after creating the module which has also been fixed. Bug: 249192297 Test: m nothing # Cherry pick into branch broken by previous behavior and make # sure that it fixes it. Change-Id: I5719c257f8457bcb2238bc7965215512a20f1095 (cherry picked from commit on android-review.googlesource.com host: bf4de041de611de4b3ec24c5f261c4293522961a) Merged-In: I5719c257f8457bcb2238bc7965215512a20f1095 --- android/prebuilt.go | 14 +++++++++- java/sdk_library.go | 17 +++++++----- java/sdk_library_test.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 91 insertions(+), 10 deletions(-) diff --git a/android/prebuilt.go b/android/prebuilt.go index 584348767..e7f221b6d 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -56,7 +56,9 @@ func (t prebuiltDependencyTag) ExcludeFromApexContents() {} var _ ExcludeFromVisibilityEnforcementTag = PrebuiltDepTag var _ ExcludeFromApexContentsTag = PrebuiltDepTag -type PrebuiltProperties struct { +// UserSuppliedPrebuiltProperties contains the prebuilt properties that can be specified in an +// Android.bp file. +type UserSuppliedPrebuiltProperties struct { // When prefer is set to true the prebuilt will be used instead of any source module with // a matching name. Prefer *bool `android:"arch_variant"` @@ -70,6 +72,16 @@ type PrebuiltProperties struct { // If specified then the prefer property is ignored in favor of the value of the Soong config // variable. Use_source_config_var *ConfigVarProperties +} + +// CopyUserSuppliedPropertiesFromPrebuilt copies the user supplied prebuilt properties from the +// prebuilt properties. +func (u *UserSuppliedPrebuiltProperties) CopyUserSuppliedPropertiesFromPrebuilt(p *Prebuilt) { + *u = p.properties.UserSuppliedPrebuiltProperties +} + +type PrebuiltProperties struct { + UserSuppliedPrebuiltProperties SourceExists bool `blueprint:"mutated"` UsePrebuilt bool `blueprint:"mutated"` diff --git a/java/sdk_library.go b/java/sdk_library.go index 47ffc6afc..cb4805823 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -2119,8 +2119,9 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl Sdk_version *string Libs []string Jars []string - Prefer *bool Compile_dex *bool + + android.UserSuppliedPrebuiltProperties }{} props.Name = proptools.StringPtr(module.stubsLibraryModuleName(apiScope)) props.Sdk_version = scopeProperties.Sdk_version @@ -2130,7 +2131,7 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl props.Jars = scopeProperties.Jars // The imports are preferred if the java_sdk_library_import is preferred. - props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer()) + props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt) // The imports need to be compiled to dex if the java_sdk_library_import requests it. compileDex := module.properties.Compile_dex @@ -2144,16 +2145,18 @@ func (module *SdkLibraryImport) createJavaImportForStubs(mctx android.Defaultabl func (module *SdkLibraryImport) createPrebuiltStubsSources(mctx android.DefaultableHookContext, apiScope *apiScope, scopeProperties *sdkLibraryScopeProperties) { props := struct { - Name *string - Srcs []string - Prefer *bool + Name *string + Srcs []string + + android.UserSuppliedPrebuiltProperties }{} props.Name = proptools.StringPtr(module.stubsSourceModuleName(apiScope)) props.Srcs = scopeProperties.Stub_srcs - mctx.CreateModule(PrebuiltStubsSourcesFactory, &props) // The stubs source is preferred if the java_sdk_library_import is preferred. - props.Prefer = proptools.BoolPtr(module.prebuilt.Prefer()) + props.CopyUserSuppliedPropertiesFromPrebuilt(&module.prebuilt) + + mctx.CreateModule(PrebuiltStubsSourcesFactory, &props) } // Add the dependencies on the child module in the component deps mutator so that it diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go index 3500c84d2..ec971a8fe 100644 --- a/java/sdk_library_test.go +++ b/java/sdk_library_test.go @@ -867,11 +867,12 @@ func TestJavaSdkLibraryImport_WithSource(t *testing.T) { }) } -func TestJavaSdkLibraryImport_Preferred(t *testing.T) { +func testJavaSdkLibraryImport_Preferred(t *testing.T, prefer string, preparer android.FixturePreparer) { result := android.GroupFixturePreparers( prepareForJavaTest, PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("sdklib"), + preparer, ).RunTestWithBp(t, ` java_sdk_library { name: "sdklib", @@ -885,11 +886,37 @@ func TestJavaSdkLibraryImport_Preferred(t *testing.T) { java_sdk_library_import { name: "sdklib", - prefer: true, + `+prefer+` public: { jars: ["a.jar"], + stub_srcs: ["a.java"], + current_api: "current.txt", + removed_api: "removed.txt", + annotations: "annotations.zip", }, } + + java_library { + name: "combined", + static_libs: [ + "sdklib.stubs", + ], + java_resources: [ + ":sdklib.stubs.source", + ":sdklib{.public.api.txt}", + ":sdklib{.public.removed-api.txt}", + ":sdklib{.public.annotations.zip}", + ], + sdk_version: "none", + system_modules: "none", + } + + java_library { + name: "public", + srcs: ["a.java"], + libs: ["sdklib"], + sdk_version: "current", + } `) CheckModuleDependencies(t, result.TestContext, "sdklib", "android_common", []string{ @@ -903,9 +930,48 @@ func TestJavaSdkLibraryImport_Preferred(t *testing.T) { CheckModuleDependencies(t, result.TestContext, "prebuilt_sdklib", "android_common", []string{ `dex2oatd`, `prebuilt_sdklib.stubs`, + `prebuilt_sdklib.stubs.source`, `sdklib.impl`, `sdklib.xml`, }) + + // Make sure that dependencies on child modules use the prebuilt when preferred. + CheckModuleDependencies(t, result.TestContext, "combined", "android_common", []string{ + // Each use of :sdklib{...} adds a dependency onto prebuilt_sdklib. + `prebuilt_sdklib`, + `prebuilt_sdklib`, + `prebuilt_sdklib`, + `prebuilt_sdklib.stubs`, + `prebuilt_sdklib.stubs.source`, + }) + + // Make sure that dependencies on sdklib that resolve to one of the child libraries use the + // prebuilt library. + public := result.ModuleForTests("public", "android_common") + rule := public.Output("javac/public.jar") + inputs := rule.Implicits.Strings() + expected := "out/soong/.intermediates/prebuilt_sdklib.stubs/android_common/combined/sdklib.stubs.jar" + if !android.InList(expected, inputs) { + t.Errorf("expected %q to contain %q", inputs, expected) + } +} + +func TestJavaSdkLibraryImport_Preferred(t *testing.T) { + t.Run("prefer", func(t *testing.T) { + testJavaSdkLibraryImport_Preferred(t, "prefer: true,", android.NullFixturePreparer) + }) + + t.Run("use_source_config_var", func(t *testing.T) { + testJavaSdkLibraryImport_Preferred(t, + "use_source_config_var: {config_namespace: \"acme\", var_name: \"use_source\"},", + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.VendorVars = map[string]map[string]string{ + "acme": { + "use_source": "false", + }, + } + })) + }) } func TestJavaSdkLibraryEnforce(t *testing.T) { -- cgit v1.2.3 From 82747779baa334116d0337fb13edd1c0fdca5324 Mon Sep 17 00:00:00 2001 From: Spandan Das Date: Tue, 8 Nov 2022 18:42:16 +0000 Subject: Create a new product variable to gate blueprint files Bug: 270654958 Users can use this feature by 1. Setting PRODUCT_INCLUDE_TAGS += in their product mk files 2. Set ``` blueprint_packge_includes { match_al: [""], } other_module_type {name: foo} other_module_type {name: bar} ``` bar and foo will be included if and only if is set Test: Unit tests in blueprint Test: TH Change-Id: I32eed4e3b5ac47fb565c62d13d8881fa984c86f4 Merged-In: I32eed4e3b5ac47fb565c62d13d8881fa984c86f4 (cherry picked from commit b45fbfbabe69d368d50e149ab37da3476a431a96) --- android/config.go | 4 ++++ android/register.go | 1 + android/variable.go | 2 ++ cmd/soong_build/main.go | 1 + ui/build/config.go | 10 ++++++++++ ui/build/dumpvars.go | 2 ++ ui/build/soong.go | 1 + 7 files changed, 21 insertions(+) diff --git a/android/config.go b/android/config.go index 3c99659f9..cbf186e46 100644 --- a/android/config.go +++ b/android/config.go @@ -1093,6 +1093,10 @@ func (c *config) ExportedNamespaces() []string { return append([]string(nil), c.productVariables.NamespacesToExport...) } +func (c *config) IncludeTags() []string { + return c.productVariables.IncludeTags +} + func (c *config) HostStaticBinaries() bool { return Bool(c.productVariables.HostStaticBinaries) } diff --git a/android/register.go b/android/register.go index c50583322..a29cfeaf1 100644 --- a/android/register.go +++ b/android/register.go @@ -160,6 +160,7 @@ type Context struct { func NewContext(config Config) *Context { ctx := &Context{blueprint.NewContext(), config} ctx.SetSrcDir(absSrcDir) + ctx.AddIncludeTags(config.IncludeTags()...) return ctx } diff --git a/android/variable.go b/android/variable.go index 442068423..8d96e31cb 100644 --- a/android/variable.go +++ b/android/variable.go @@ -445,6 +445,8 @@ type productVariables struct { GenerateAidlNdkPlatformBackend bool `json:",omitempty"` ForceMultilibFirstOnDevice bool `json:",omitempty"` + + IncludeTags []string `json:",omitempty"` } func boolPtr(v bool) *bool { diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index 4b3161b33..f1884a795 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -117,6 +117,7 @@ func newContext(configuration android.Config) *android.Context { ctx.Register() ctx.SetNameInterface(newNameResolver(configuration)) ctx.SetAllowMissingDependencies(configuration.AllowMissingDependencies()) + ctx.AddIncludeTags(configuration.IncludeTags()...) return ctx } diff --git a/ui/build/config.go b/ui/build/config.go index e271bfca2..a6763214f 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -98,6 +98,8 @@ type configImpl struct { emptyNinjaFile bool metricsUploader string + + includeTags []string } const srcDirFileCheck = "build/soong/root.bp" @@ -1038,6 +1040,14 @@ func (c *configImpl) Parallel() int { return c.parallel } +func (c *configImpl) GetIncludeTags() []string { + return c.includeTags +} + +func (c *configImpl) SetIncludeTags(i []string) { + c.includeTags = i +} + func (c *configImpl) HighmemParallel() int { if i, ok := c.environ.GetInt("NINJA_HIGHMEM_NUM_JOBS"); ok { return i diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go index 285f1569b..cc796ce3f 100644 --- a/ui/build/dumpvars.go +++ b/ui/build/dumpvars.go @@ -139,6 +139,7 @@ func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_ var BannerVars = []string{ "PLATFORM_VERSION_CODENAME", "PLATFORM_VERSION", + "PRODUCT_INCLUDE_TAGS", "TARGET_PRODUCT", "TARGET_BUILD_VARIANT", "TARGET_BUILD_TYPE", @@ -295,4 +296,5 @@ func runMakeProductConfig(ctx Context, config Config) { config.SetBuildBrokenDupRules(makeVars["BUILD_BROKEN_DUP_RULES"] == "true") config.SetBuildBrokenUsesNetwork(makeVars["BUILD_BROKEN_USES_NETWORK"] == "true") config.SetBuildBrokenNinjaUsesEnvVars(strings.Fields(makeVars["BUILD_BROKEN_NINJA_USES_ENV_VARS"])) + config.SetIncludeTags(strings.Fields(makeVars["PRODUCT_INCLUDE_TAGS"])) } diff --git a/ui/build/soong.go b/ui/build/soong.go index c7f22f946..a0ab1cc10 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -332,6 +332,7 @@ func bootstrapBlueprint(ctx Context, config Config) { blueprintArgs.EmptyNinjaFile = false blueprintCtx := blueprint.NewContext() + blueprintCtx.AddIncludeTags(config.GetIncludeTags()...) blueprintCtx.SetIgnoreUnknownModuleTypes(true) blueprintConfig := BlueprintConfig{ soongOutDir: config.SoongOutDir(), -- cgit v1.2.3