Merge "Implement test-only for python_ rules" into main
diff --git a/android/apex.go b/android/apex.go
index 8759905..c0acada 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "slices"
"sort"
"strconv"
"strings"
@@ -108,7 +109,7 @@
// are configured to have the same alias variation named apex29. Whether platform APIs is allowed
// or not also matters; if two APEXes don't have the same allowance, they get different names and
// thus wouldn't be merged.
-func (i ApexInfo) mergedName(ctx PathContext) string {
+func (i ApexInfo) mergedName() string {
name := "apex" + strconv.Itoa(i.MinSdkVersion.FinalOrFutureInt())
return name
}
@@ -543,17 +544,10 @@
return true
}
-type byApexName []ApexInfo
-
-func (a byApexName) Len() int { return len(a) }
-func (a byApexName) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-func (a byApexName) Less(i, j int) bool { return a[i].ApexVariationName < a[j].ApexVariationName }
-
// mergeApexVariations deduplicates apex variations that would build identically into a common
// variation. It returns the reduced list of variations and a list of aliases from the original
// variation names to the new variation names.
-func mergeApexVariations(ctx PathContext, apexInfos []ApexInfo) (merged []ApexInfo, aliases [][2]string) {
- sort.Sort(byApexName(apexInfos))
+func mergeApexVariations(apexInfos []ApexInfo) (merged []ApexInfo, aliases [][2]string) {
seen := make(map[string]int)
for _, apexInfo := range apexInfos {
// If this is for a prebuilt apex then use the actual name of the apex variation to prevent this
@@ -567,7 +561,7 @@
// this one into it, otherwise create a new merged ApexInfo from this one and save it away so
// other ApexInfo instances can be merged into it.
variantName := apexInfo.ApexVariationName
- mergedName := apexInfo.mergedName(ctx)
+ mergedName := apexInfo.mergedName()
if index, exists := seen[mergedName]; exists {
// Variants having the same mergedName are deduped
merged[index].InApexVariants = append(merged[index].InApexVariants, variantName)
@@ -606,18 +600,20 @@
// TODO(jiyong): is this the right place?
base.checkApexAvailableProperty(mctx)
- var apexInfos []ApexInfo
- var aliases [][2]string
- if !mctx.Module().(ApexModule).UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps {
- apexInfos, aliases = mergeApexVariations(mctx, base.apexInfos)
- } else {
- apexInfos = base.apexInfos
- }
+ apexInfos := base.apexInfos
// base.apexInfos is only needed to propagate the list of apexes from apexInfoMutator to
// apexMutator. It is no longer accurate after mergeApexVariations, and won't be copied to
// all but the first created variant. Clear it so it doesn't accidentally get used later.
base.apexInfos = nil
- sort.Sort(byApexName(apexInfos))
+
+ slices.SortFunc(apexInfos, func(a, b ApexInfo) int {
+ return strings.Compare(a.ApexVariationName, b.ApexVariationName)
+ })
+
+ var aliases [][2]string
+ if !mctx.Module().(ApexModule).UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps {
+ apexInfos, aliases = mergeApexVariations(apexInfos)
+ }
var inApex ApexMembership
for _, a := range apexInfos {
diff --git a/android/apex_test.go b/android/apex_test.go
index ddc730d..347bf7d 100644
--- a/android/apex_test.go
+++ b/android/apex_test.go
@@ -33,10 +33,22 @@
{
name: "single",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
{"foo", "apex10000"},
@@ -45,98 +57,231 @@
{
name: "merge",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", FutureApiLevel, false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, false, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, false, nil}},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo", "bar"},
+ InApexModules: []string{"foo", "bar"},
+ }},
wantAliases: [][2]string{
- {"bar", "apex10000"},
{"foo", "apex10000"},
+ {"bar", "apex10000"},
},
},
{
name: "don't merge version",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", uncheckedFinalApiLevel(30), false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: uncheckedFinalApiLevel(30),
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex30", uncheckedFinalApiLevel(30), false, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
- {"apex10000", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "apex30",
+ MinSdkVersion: uncheckedFinalApiLevel(30),
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
- {"bar", "apex30"},
{"foo", "apex10000"},
+ {"bar", "apex30"},
},
},
{
name: "merge updatable",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", FutureApiLevel, true, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, true, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"foo", "bar"},
+ InApexModules: []string{"foo", "bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
- {"bar", "apex10000"},
{"foo", "apex10000"},
+ {"bar", "apex10000"},
},
},
{
name: "don't merge when for prebuilt_apex",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", FutureApiLevel, true, false, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
// This one should not be merged in with the others because it is for
// a prebuilt_apex.
- {"baz", FutureApiLevel, true, false, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex, nil},
+ {
+ ApexVariationName: "baz",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"baz"},
+ InApexModules: []string{"baz"},
+ ForPrebuiltApex: ForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, true, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
- {"baz", FutureApiLevel, true, false, []string{"baz"}, []string{"baz"}, nil, ForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"foo", "bar"},
+ InApexModules: []string{"foo", "bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "baz",
+ MinSdkVersion: FutureApiLevel,
+ Updatable: true,
+ InApexVariants: []string{"baz"},
+ InApexModules: []string{"baz"},
+ ForPrebuiltApex: ForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
- {"bar", "apex10000"},
{"foo", "apex10000"},
+ {"bar", "apex10000"},
},
},
{
name: "merge different UsePlatformApis but don't allow using platform api",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, false, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", FutureApiLevel, false, true, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: FutureApiLevel,
+ UsePlatformApis: true,
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, false, false, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ InApexVariants: []string{"foo", "bar"},
+ InApexModules: []string{"foo", "bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
- {"bar", "apex10000"},
{"foo", "apex10000"},
+ {"bar", "apex10000"},
},
},
{
name: "merge same UsePlatformApis and allow using platform api",
in: []ApexInfo{
- {"foo", FutureApiLevel, false, true, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex, nil},
- {"bar", FutureApiLevel, false, true, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "foo",
+ MinSdkVersion: FutureApiLevel,
+ UsePlatformApis: true,
+ InApexVariants: []string{"foo"},
+ InApexModules: []string{"foo"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
+ {
+ ApexVariationName: "bar",
+ MinSdkVersion: FutureApiLevel,
+ UsePlatformApis: true,
+ InApexVariants: []string{"bar"},
+ InApexModules: []string{"bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantMerged: []ApexInfo{
- {"apex10000", FutureApiLevel, false, true, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex, nil},
+ {
+ ApexVariationName: "apex10000",
+ MinSdkVersion: FutureApiLevel,
+ UsePlatformApis: true,
+ InApexVariants: []string{"foo", "bar"},
+ InApexModules: []string{"foo", "bar"},
+ ForPrebuiltApex: NotForPrebuiltApex,
+ },
},
wantAliases: [][2]string{
- {"bar", "apex10000"},
{"foo", "apex10000"},
+ {"bar", "apex10000"},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- config := TestConfig(t.TempDir(), nil, "", nil)
- ctx := &configErrorWrapper{config: config}
- gotMerged, gotAliases := mergeApexVariations(ctx, tt.in)
+ gotMerged, gotAliases := mergeApexVariations(tt.in)
if !reflect.DeepEqual(gotMerged, tt.wantMerged) {
t.Errorf("mergeApexVariations() gotMerged = %v, want %v", gotMerged, tt.wantMerged)
}
diff --git a/android/module.go b/android/module.go
index 47bc829..5fe379c 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1042,12 +1042,12 @@
pv := ctx.Config().productVariables
fullManifest := pv.DeviceArch != nil && pv.DeviceName != nil
if fullManifest {
- m.addRequiredDeps(ctx)
+ addRequiredDeps(ctx)
}
}
// addRequiredDeps adds required, target_required, and host_required as dependencies.
-func (m *ModuleBase) addRequiredDeps(ctx BottomUpMutatorContext) {
+func addRequiredDeps(ctx BottomUpMutatorContext) {
addDep := func(target Target, depName string) {
if !ctx.OtherModuleExists(depName) {
if ctx.Config().AllowMissingDependencies() {
@@ -1060,9 +1060,9 @@
// in build/make/core/main.mk.
// TODO(jiyong): the Make-side does this only when the required module is a shared
// library or a native test.
- bothInAndroid := m.Device() && target.Os.Class == Device
- nativeArch := InList(m.Arch().ArchType.Multilib, []string{"lib32", "lib64"})
- sameBitness := m.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
+ bothInAndroid := ctx.Device() && target.Os.Class == Device
+ nativeArch := InList(ctx.Arch().ArchType.Multilib, []string{"lib32", "lib64"})
+ sameBitness := ctx.Arch().ArchType.Multilib == target.Arch.ArchType.Multilib
if bothInAndroid && nativeArch && !sameBitness {
return
}
@@ -1081,31 +1081,31 @@
hostTargets = append(hostTargets, ctx.Config().Targets[ctx.Config().BuildOS]...)
hostTargets = append(hostTargets, ctx.Config().BuildOSCommonTarget)
- if m.Device() {
- for _, depName := range m.RequiredModuleNames() {
+ if ctx.Device() {
+ for _, depName := range ctx.Module().RequiredModuleNames() {
for _, target := range deviceTargets {
addDep(target, depName)
}
}
- for _, depName := range m.HostRequiredModuleNames() {
+ for _, depName := range ctx.Module().HostRequiredModuleNames() {
for _, target := range hostTargets {
addDep(target, depName)
}
}
}
- if m.Host() {
- for _, depName := range m.RequiredModuleNames() {
+ if ctx.Host() {
+ for _, depName := range ctx.Module().RequiredModuleNames() {
for _, target := range hostTargets {
// When a host module requires another host module, don't make a
// dependency if they have different OSes (i.e. hostcross).
- if m.Target().HostCross != target.HostCross {
+ if ctx.Target().HostCross != target.HostCross {
continue
}
addDep(target, depName)
}
}
- for _, depName := range m.TargetRequiredModuleNames() {
+ for _, depName := range ctx.Module().TargetRequiredModuleNames() {
for _, target := range deviceTargets {
addDep(target, depName)
}
@@ -2169,20 +2169,27 @@
}
}
return proptools.ConfigurableValueUndefined()
- case "variant":
- if len(condition.Args) != 1 {
- ctx.OtherModulePropertyErrorf(m, property, "variant requires 1 argument, found %d", len(condition.Args))
+ case "arch":
+ if len(condition.Args) != 0 {
+ ctx.OtherModulePropertyErrorf(m, property, "arch requires no arguments, found %d", len(condition.Args))
return proptools.ConfigurableValueUndefined()
}
- if condition.Args[0] == "arch" {
- if !m.base().ArchReady() {
- ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran")
- return proptools.ConfigurableValueUndefined()
- }
- return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name)
+ if !m.base().ArchReady() {
+ ctx.OtherModulePropertyErrorf(m, property, "A select on arch was attempted before the arch mutator ran")
+ return proptools.ConfigurableValueUndefined()
}
- ctx.OtherModulePropertyErrorf(m, property, "Unknown variant %s", condition.Args[0])
- return proptools.ConfigurableValueUndefined()
+ return proptools.ConfigurableValueString(m.base().Arch().ArchType.Name)
+ case "os":
+ if len(condition.Args) != 0 {
+ ctx.OtherModulePropertyErrorf(m, property, "os requires no arguments, found %d", len(condition.Args))
+ return proptools.ConfigurableValueUndefined()
+ }
+ // the arch mutator runs after the os mutator, we can just use this to enforce that os is ready.
+ if !m.base().ArchReady() {
+ ctx.OtherModulePropertyErrorf(m, property, "A select on os was attempted before the arch mutator ran (arch runs after os, we use it to lazily detect that os is ready)")
+ return proptools.ConfigurableValueUndefined()
+ }
+ return proptools.ConfigurableValueString(m.base().Os().Name)
case "boolean_var_for_testing":
// We currently don't have any other boolean variables (we should add support for typing
// the soong config variables), so add this fake one for testing the boolean select
diff --git a/android/mutator.go b/android/mutator.go
index 0ff4f48..75ba650 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -391,6 +391,7 @@
type IncomingTransitionContext interface {
ArchModuleContext
+ ModuleProviderContext
// Module returns the target of the dependency edge for which the transition
// is being computed
@@ -404,6 +405,7 @@
type OutgoingTransitionContext interface {
ArchModuleContext
+ ModuleProviderContext
// Module returns the target of the dependency edge for which the transition
// is being computed
@@ -505,6 +507,7 @@
type androidTransitionMutator struct {
finalPhase bool
mutator TransitionMutator
+ name string
}
func (a *androidTransitionMutator) Split(ctx blueprint.BaseModuleContext) []string {
@@ -537,6 +540,10 @@
return DeviceConfig{c.bp.Config().(Config).deviceConfig}
}
+func (c *outgoingTransitionContextImpl) provider(provider blueprint.AnyProviderKey) (any, bool) {
+ return c.bp.Provider(provider)
+}
+
func (a *androidTransitionMutator) OutgoingTransition(bpctx blueprint.OutgoingTransitionContext, sourceVariation string) string {
if m, ok := bpctx.Module().(Module); ok {
ctx := outgoingTransitionContextPool.Get().(*outgoingTransitionContextImpl)
@@ -568,6 +575,10 @@
return DeviceConfig{c.bp.Config().(Config).deviceConfig}
}
+func (c *incomingTransitionContextImpl) provider(provider blueprint.AnyProviderKey) (any, bool) {
+ return c.bp.Provider(provider)
+}
+
func (a *androidTransitionMutator) IncomingTransition(bpctx blueprint.IncomingTransitionContext, incomingVariation string) string {
if m, ok := bpctx.Module().(Module); ok {
ctx := incomingTransitionContextPool.Get().(*incomingTransitionContextImpl)
@@ -586,6 +597,9 @@
if am, ok := ctx.Module().(Module); ok {
mctx := bottomUpMutatorContextFactory(ctx, am, a.finalPhase)
defer bottomUpMutatorContextPool.Put(mctx)
+ base := am.base()
+ base.commonProperties.DebugMutators = append(base.commonProperties.DebugMutators, a.name)
+ base.commonProperties.DebugVariations = append(base.commonProperties.DebugVariations, variation)
a.mutator.Mutate(mctx, variation)
}
}
@@ -594,6 +608,7 @@
atm := &androidTransitionMutator{
finalPhase: x.finalPhase,
mutator: m,
+ name: name,
}
mutator := &mutator{
name: name,
diff --git a/android/selects_test.go b/android/selects_test.go
index 1eb137b..f912ce6 100644
--- a/android/selects_test.go
+++ b/android/selects_test.go
@@ -269,11 +269,11 @@
},
},
{
- name: "Select on variant",
+ name: "Select on arch",
bp: `
my_module_type {
name: "foo",
- my_string: select(variant("arch"), {
+ my_string: select(arch(), {
"x86": "my_x86",
"x86_64": "my_x86_64",
"arm": "my_arm",
@@ -287,6 +287,22 @@
},
},
{
+ name: "Select on os",
+ bp: `
+ my_module_type {
+ name: "foo",
+ my_string: select(os(), {
+ "android": "my_android",
+ "linux": "my_linux",
+ default: "my_default",
+ }),
+ }
+ `,
+ provider: selectsTestProvider{
+ my_string: proptools.StringPtr("my_android"),
+ },
+ },
+ {
name: "Unset value",
bp: `
my_module_type {
diff --git a/android/util.go b/android/util.go
index 363b31c..698a856 100644
--- a/android/util.go
+++ b/android/util.go
@@ -524,22 +524,27 @@
return root, suffix, ext
}
-// ShardPaths takes a Paths, and returns a slice of Paths where each one has at most shardSize paths.
-func ShardPaths(paths Paths, shardSize int) []Paths {
- if len(paths) == 0 {
+func shard[T ~[]E, E any](toShard T, shardSize int) []T {
+ if len(toShard) == 0 {
return nil
}
- ret := make([]Paths, 0, (len(paths)+shardSize-1)/shardSize)
- for len(paths) > shardSize {
- ret = append(ret, paths[0:shardSize])
- paths = paths[shardSize:]
+
+ ret := make([]T, 0, (len(toShard)+shardSize-1)/shardSize)
+ for len(toShard) > shardSize {
+ ret = append(ret, toShard[0:shardSize])
+ toShard = toShard[shardSize:]
}
- if len(paths) > 0 {
- ret = append(ret, paths)
+ if len(toShard) > 0 {
+ ret = append(ret, toShard)
}
return ret
}
+// ShardPaths takes a Paths, and returns a slice of Paths where each one has at most shardSize paths.
+func ShardPaths(paths Paths, shardSize int) []Paths {
+ return shard(paths, shardSize)
+}
+
// ShardString takes a string and returns a slice of strings where the length of each one is
// at most shardSize.
func ShardString(s string, shardSize int) []string {
@@ -560,18 +565,7 @@
// ShardStrings takes a slice of strings, and returns a slice of slices of strings where each one has at most shardSize
// elements.
func ShardStrings(s []string, shardSize int) [][]string {
- if len(s) == 0 {
- return nil
- }
- ret := make([][]string, 0, (len(s)+shardSize-1)/shardSize)
- for len(s) > shardSize {
- ret = append(ret, s[0:shardSize])
- s = s[shardSize:]
- }
- if len(s) > 0 {
- ret = append(ret, s)
- }
- return ret
+ return shard(s, shardSize)
}
// CheckDuplicate checks if there are duplicates in given string list.
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index 672e852..b5b49b1 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -19,6 +19,7 @@
import (
"bytes"
"fmt"
+ "os"
"reflect"
"strings"
"testing"
@@ -2215,3 +2216,9 @@
})
}
}
+
+func TestMain(m *testing.M) {
+ // Skip checking Android.mk path with cleaning "ANDROID_BUILD_TOP"
+ os.Setenv("ANDROID_BUILD_TOP", "")
+ os.Exit(m.Run())
+}
diff --git a/cc/config/global.go b/cc/config/global.go
index 16b5e09..ffd6d7e 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -295,6 +295,9 @@
// New warnings to be fixed after clang-r475365
"-Wno-error=single-bit-bitfield-constant-conversion", // http://b/243965903
"-Wno-error=enum-constexpr-conversion", // http://b/243964282
+ // New warnings to be fixed after clang-r522817
+ "-Wno-error=invalid-offsetof",
+ "-Wno-error=thread-safety-reference-return",
// Irrelevant on Android because _we_ don't use exceptions, but causes
// lots of build noise because libcxx/libcxxabi do. This can probably
@@ -302,6 +305,9 @@
// until then because it causes warnings in the _callers_, not the
// project itself.
"-Wno-deprecated-dynamic-exception-spec",
+
+ // Allow using VLA CXX extension.
+ "-Wno-vla-cxx-extension",
}
noOverride64GlobalCflags = []string{}
@@ -386,7 +392,7 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r510928"
+ ClangDefaultVersion = "clang-r522817"
ClangDefaultShortVersion = "18"
// Directories with warnings from Android.bp files.
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 04bc61d..93351f1 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -52,7 +52,7 @@
// GenerateDexpreoptRule generates a set of commands that will preopt a module based on a GlobalConfig and a
// ModuleConfig. The produced files and their install locations will be available through rule.Installs().
func GenerateDexpreoptRule(ctx android.BuilderContext, globalSoong *GlobalSoongConfig,
- global *GlobalConfig, module *ModuleConfig, productPackages android.Path) (
+ global *GlobalConfig, module *ModuleConfig, productPackages android.Path, copyApexSystemServerJarDex bool) (
rule *android.RuleBuilder, err error) {
defer func() {
@@ -94,7 +94,7 @@
for archIdx, _ := range module.Archs {
dexpreoptCommand(ctx, globalSoong, global, module, rule, archIdx, profile, appImage,
- generateDM, productPackages)
+ generateDM, productPackages, copyApexSystemServerJarDex)
}
}
}
@@ -231,7 +231,7 @@
func dexpreoptCommand(ctx android.BuilderContext, globalSoong *GlobalSoongConfig,
global *GlobalConfig, module *ModuleConfig, rule *android.RuleBuilder, archIdx int,
- profile android.WritablePath, appImage bool, generateDM bool, productPackages android.Path) {
+ profile android.WritablePath, appImage bool, generateDM bool, productPackages android.Path, copyApexSystemServerJarDex bool) {
arch := module.Archs[archIdx]
@@ -277,7 +277,7 @@
clcTarget = append(clcTarget, GetSystemServerDexLocation(ctx, global, lib))
}
- if DexpreoptRunningInSoong {
+ if DexpreoptRunningInSoong && copyApexSystemServerJarDex {
// Copy the system server jar to a predefined location where dex2oat will find it.
dexPathHost := SystemServerDexJarHostPath(ctx, module.Name)
rule.Command().Text("mkdir -p").Flag(filepath.Dir(dexPathHost.String()))
diff --git a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
index 8033b48..7512005 100644
--- a/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
+++ b/dexpreopt/dexpreopt_gen/dexpreopt_gen.go
@@ -205,8 +205,9 @@
panic(err)
}
}
+ cpApexSscpServerJar := false // dexpreopt_gen operates on make modules, and since sscp libraries are in soong, this should be a noop
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(
- ctx, globalSoong, global, module, android.PathForTesting(productPackagesPath))
+ ctx, globalSoong, global, module, android.PathForTesting(productPackagesPath), cpApexSscpServerJar)
if err != nil {
panic(err)
}
diff --git a/dexpreopt/dexpreopt_test.go b/dexpreopt/dexpreopt_test.go
index 7071f3e..eff2416 100644
--- a/dexpreopt/dexpreopt_test.go
+++ b/dexpreopt/dexpreopt_test.go
@@ -101,7 +101,7 @@
module := testSystemModuleConfig(ctx, "test")
productPackages := android.PathForTesting("product_packages.txt")
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -161,7 +161,7 @@
for _, test := range tests {
global.PatternsOnSystemOther = test.patterns
for _, mt := range test.moduleTests {
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, mt.module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, mt.module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -181,6 +181,11 @@
}
func TestDexPreoptApexSystemServerJars(t *testing.T) {
+ // modify the global variable for test
+ var oldDexpreoptRunningInSoong = DexpreoptRunningInSoong
+ DexpreoptRunningInSoong = true
+
+ // test begin
config := android.TestConfig("out", nil, "", nil)
ctx := android.BuilderContextForTesting(config)
globalSoong := globalSoongConfigForTests(ctx)
@@ -191,7 +196,7 @@
global.ApexSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"com.android.apex1:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -202,6 +207,18 @@
}
android.AssertStringEquals(t, "installs", wantInstalls.String(), rule.Installs().String())
+
+ android.AssertStringListContains(t, "apex sscp jar copy", rule.Outputs().Strings(), "out/soong/system_server_dexjars/service-A.jar")
+
+ // rule with apex sscp cp as false
+ rule, err = GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, false)
+ if err != nil {
+ t.Fatal(err)
+ }
+ android.AssertStringListDoesNotContain(t, "apex sscp jar copy", rule.Outputs().Strings(), "out/soong/system_server_dexjars/service-A.jar")
+
+ // cleanup the global variable for test
+ DexpreoptRunningInSoong = oldDexpreoptRunningInSoong
}
func TestDexPreoptStandaloneSystemServerJars(t *testing.T) {
@@ -215,7 +232,7 @@
global.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"platform:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -239,7 +256,7 @@
global.StandaloneSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"system_ext:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -263,7 +280,7 @@
global.ApexStandaloneSystemServerJars = android.CreateTestConfiguredJarList(
[]string{"com.android.apex1:service-A"})
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
@@ -286,7 +303,7 @@
module.ProfileClassListing = android.OptionalPathForPath(android.PathForTesting("profile"))
- rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages)
+ rule, err := GenerateDexpreoptRule(ctx, globalSoong, global, module, productPackages, true)
if err != nil {
t.Fatal(err)
}
diff --git a/filesystem/filesystem_test.go b/filesystem/filesystem_test.go
index f4ecad4..3a5071d 100644
--- a/filesystem/filesystem_test.go
+++ b/filesystem/filesystem_test.go
@@ -84,12 +84,21 @@
cc_library {
name: "libbar",
required: ["libbaz"],
+ target: {
+ platform: {
+ required: ["lib_platform_only"],
+ },
+ },
}
cc_library {
name: "libbaz",
}
+ cc_library {
+ name: "lib_platform_only",
+ }
+
phony {
name: "phony",
required: [
@@ -120,6 +129,7 @@
"lib64/libbar.so",
"lib64/libbaz.so",
"lib64/libquz.so",
+ "lib64/lib_platform_only.so",
"etc/bpf/bpf.o",
}
for _, e := range expected {
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 38ed856..25e95db 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -243,10 +243,6 @@
return true
}
- if disableSourceApexVariant(ctx) {
- return true
- }
-
if _, isApex := android.ModuleProvider(ctx, android.ApexBundleInfoProvider); isApex {
// dexpreopt rules for system server jars can be generated in the ModuleCtx of prebuilt apexes
return false
@@ -501,8 +497,12 @@
Output(appProductPackages)
productPackagesRule.Restat().Build("product_packages."+dexJarStem, "dexpreopt product_packages")
+ // Prebuilts are active, do not copy the dexpreopt'd source javalib to out/soong/system_server_dexjars
+ // The javalib from the deapexed prebuilt will be copied to this location.
+ // TODO (b/331665856): Implement a principled solution for this.
+ copyApexSystemServerJarDex := !disableSourceApexVariant(ctx)
dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(
- ctx, globalSoong, global, dexpreoptConfig, appProductPackages)
+ ctx, globalSoong, global, dexpreoptConfig, appProductPackages, copyApexSystemServerJarDex)
if err != nil {
ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error())
return
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index e4beb5e..ae587ea 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -1478,13 +1478,3 @@
}
return bootDexJar.Path()
}
-
-// extractEncodedDexJarsFromModules extracts the encoded dex jars from the supplied modules.
-func extractEncodedDexJarsFromModules(ctx android.ModuleContext, contents []android.Module) bootDexJarByModule {
- encodedDexJarsByModuleName := bootDexJarByModule{}
- for _, module := range contents {
- path := retrieveEncodedBootDexJarFromModule(ctx, module)
- encodedDexJarsByModuleName.addPath(module, path)
- }
- return encodedDexJarsByModuleName
-}
diff --git a/java/java.go b/java/java.go
index fb35a9a..2834c5f 100644
--- a/java/java.go
+++ b/java/java.go
@@ -886,6 +886,12 @@
}
func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if disableSourceApexVariant(ctx) {
+ // Prebuilts are active, do not create the installation rules for the source javalib.
+ // Even though the source javalib is not used, we need to hide it to prevent duplicate installation rules.
+ // TODO (b/331665856): Implement a principled solution for this.
+ j.HideFromMake()
+ }
j.provideHiddenAPIPropertyInfo(ctx)
j.sdkVersion = j.SdkVersion(ctx)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index e7e53a2..56b1d39 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1562,6 +1562,12 @@
}
func (module *SdkLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ if disableSourceApexVariant(ctx) {
+ // Prebuilts are active, do not create the installation rules for the source javalib.
+ // Even though the source javalib is not used, we need to hide it to prevent duplicate installation rules.
+ // TODO (b/331665856): Implement a principled solution for this.
+ module.HideFromMake()
+ }
if proptools.String(module.deviceProperties.Min_sdk_version) != "" {
module.CheckMinSdkVersion(ctx)
}
diff --git a/partner/androidmk/androidmk_test.go b/partner/androidmk/androidmk_test.go
index 6bae836..3ace750 100644
--- a/partner/androidmk/androidmk_test.go
+++ b/partner/androidmk/androidmk_test.go
@@ -54,6 +54,9 @@
}
func TestEndToEnd(t *testing.T) {
+ // Skip checking Android.mk path with cleaning "ANDROID_BUILD_TOP"
+ t.Setenv("ANDROID_BUILD_TOP", "")
+
for i, test := range testCases {
expected, err := bpfix.Reformat(test.expected)
if err != nil {