diff --git a/android/apex.go b/android/apex.go index 1589a1718..c01b71692 100644 --- a/android/apex.go +++ b/android/apex.go @@ -28,20 +28,29 @@ var ( SdkVersion_Android10 = uncheckedFinalApiLevel(29) ) +// ApexInfo describes the metadata common to all modules in an apexBundle. type ApexInfo struct { - // Name of the apex variation that this module is mutated into + // Name of the apex variation that this module is mutated into, or "" for + // a platform variant. Note that a module can be included in multiple APEXes, + // in which case, the module is mutated into one or more variants, each of + // which is for one or more APEXes. ApexVariationName string // Serialized ApiLevel. Use via MinSdkVersion() method. Cannot be stored in // its struct form because this is cloned into properties structs, and // ApiLevel has private members. MinSdkVersionStr string - Updatable bool - RequiredSdks SdkRefs - InApexes []string + // True if the module comes from an updatable APEX. + Updatable bool + RequiredSdks SdkRefs + + InApexes []string + ApexContents []*ApexContents } +var ApexInfoProvider = blueprint.NewMutatorProvider(ApexInfo{}, "apex") + func (i ApexInfo) mergedName(ctx PathContext) string { name := "apex" + strconv.Itoa(i.MinSdkVersion(ctx).FinalOrFutureInt()) for _, sdk := range i.RequiredSdks { @@ -54,6 +63,18 @@ func (this *ApexInfo) MinSdkVersion(ctx PathContext) ApiLevel { return ApiLevelOrPanic(ctx, this.MinSdkVersionStr) } +func (i ApexInfo) IsForPlatform() bool { + return i.ApexVariationName == "" +} + +// ApexTestForInfo stores the contents of APEXes for which this module is a test and thus has +// access to APEX internals. +type ApexTestForInfo struct { + ApexContents []*ApexContents +} + +var ApexTestForInfoProvider = blueprint.NewMutatorProvider(ApexTestForInfo{}, "apex_test_for") + // Extracted from ApexModule to make it easier to define custom subsets of the // ApexModule interface and improve code navigation within the IDE. type DepIsInSameApex interface { @@ -87,23 +108,18 @@ type ApexModule interface { // Call this before apex.apexMutator is run. BuildForApex(apex ApexInfo) - // Returns the name of APEX variation that this module will be built for. - // Empty string is returned when 'IsForPlatform() == true'. Note that a - // module can beincluded in multiple APEXes, in which case, the module - // is mutated into one or more variants, each of which is for one or - // more APEXes. This method returns the name of the APEX variation of - // the module. + // Returns true if this module is present in any APEXes + // directly or indirectly. // Call this after apex.apexMutator is run. - ApexVariationName() string + InAnyApex() bool - // Returns the name of the APEX modules that this variant of this module - // is present in. + // Returns true if this module is directly in any APEXes. // Call this after apex.apexMutator is run. - InApexes() []string + DirectlyInAnyApex() bool - // Tests whether this module will be built for the platform or not. - // This is a shortcut for ApexVariationName() == "" - IsForPlatform() bool + // Returns true if any variant of this module is directly in any APEXes. + // Call this after apex.apexMutator is run. + AnyVariantDirectlyInAnyApex() bool // Tests if this module could have APEX variants. APEX variants are // created only for the modules that returns true here. This is useful @@ -116,10 +132,6 @@ type ApexModule interface { // libs. IsInstallableToApex() bool - // Mutate this module into one or more variants each of which is built - // for an APEX marked via BuildForApex(). - CreateApexVariations(mctx BottomUpMutatorContext) []Module - // Tests if this module is available for the specified APEX or ":platform" AvailableFor(what string) bool @@ -138,9 +150,6 @@ type ApexModule interface { // it returns 9 as string ChooseSdkVersion(ctx BaseModuleContext, versionList []string, maxSdkVersion ApiLevel) (string, error) - // Tests if the module comes from an updatable APEX. - Updatable() bool - // List of APEXes that this module tests. The module has access to // the private part of the listed APEXes even when it is not included in the // APEXes. @@ -153,11 +162,6 @@ type ApexModule interface { // Returns true if this module needs a unique variation per apex, for example if // use_apex_name_macro is set. UniqueApexVariations() bool - - // UpdateUniqueApexVariationsForDeps sets UniqueApexVariationsForDeps if any dependencies - // that are in the same APEX have unique APEX variations so that the module can link against - // the right variant. - UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext) } type ApexProperties struct { @@ -171,7 +175,21 @@ type ApexProperties struct { // Default is ["//apex_available:platform"]. Apex_available []string - Info ApexInfo `blueprint:"mutated"` + // AnyVariantDirectlyInAnyApex is true in the primary variant of a module if _any_ variant + // of the module is directly in any apex. This includes host, arch, asan, etc. variants. + // It is unused in any variant that is not the primary variant. + // Ideally this wouldn't be used, as it incorrectly mixes arch variants if only one arch + // is in an apex, but a few places depend on it, for example when an ASAN variant is + // created before the apexMutator. + AnyVariantDirectlyInAnyApex bool `blueprint:"mutated"` + + // DirectlyInAnyApex is true if any APEX variant (including the "" variant used for the + // platform) of this module is directly in any APEX. + DirectlyInAnyApex bool `blueprint:"mutated"` + + // DirectlyInAnyApex is true if any APEX variant (including the "" variant used for the + // platform) of this module is directly or indirectly in any APEX. + InAnyApex bool `blueprint:"mutated"` NotAvailableForPlatform bool `blueprint:"mutated"` @@ -187,6 +205,15 @@ type ExcludeFromApexContentsTag interface { ExcludeFromApexContents() } +// Marker interface that identifies dependencies that should inherit the DirectlyInAnyApex +// state from the parent to the child. For example, stubs libraries are marked as +// DirectlyInAnyApex if their implementation is in an apex. +type CopyDirectlyInAnyApexTag interface { + blueprint.DependencyTag + + CopyDirectlyInAnyApex() +} + // Provides default implementation for the ApexModule interface. APEX-aware // modules are expected to include this struct and call InitApexModule(). type ApexModuleBase struct { @@ -215,43 +242,6 @@ func (m *ApexModuleBase) UniqueApexVariations() bool { return false } -func (m *ApexModuleBase) UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext) { - // anyInSameApex returns true if the two ApexInfo lists contain any values in an InApexes list - // in common. It is used instead of DepIsInSameApex because it needs to determine if the dep - // is in the same APEX due to being directly included, not only if it is included _because_ it - // is a dependency. - anyInSameApex := func(a, b []ApexInfo) bool { - collectApexes := func(infos []ApexInfo) []string { - var ret []string - for _, info := range infos { - ret = append(ret, info.InApexes...) - } - return ret - } - - aApexes := collectApexes(a) - bApexes := collectApexes(b) - sort.Strings(bApexes) - for _, aApex := range aApexes { - index := sort.SearchStrings(bApexes, aApex) - if index < len(bApexes) && bApexes[index] == aApex { - return true - } - } - return false - } - - mctx.VisitDirectDeps(func(dep Module) { - if depApexModule, ok := dep.(ApexModule); ok { - if anyInSameApex(depApexModule.apexModuleBase().apexVariations, m.apexVariations) && - (depApexModule.UniqueApexVariations() || - depApexModule.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps) { - m.ApexProperties.UniqueApexVariationsForDeps = true - } - } - }) -} - func (m *ApexModuleBase) BuildForApex(apex ApexInfo) { m.apexVariationsLock.Lock() defer m.apexVariationsLock.Unlock() @@ -263,16 +253,16 @@ func (m *ApexModuleBase) BuildForApex(apex ApexInfo) { m.apexVariations = append(m.apexVariations, apex) } -func (m *ApexModuleBase) ApexVariationName() string { - return m.ApexProperties.Info.ApexVariationName +func (m *ApexModuleBase) DirectlyInAnyApex() bool { + return m.ApexProperties.DirectlyInAnyApex } -func (m *ApexModuleBase) InApexes() []string { - return m.ApexProperties.Info.InApexes +func (m *ApexModuleBase) AnyVariantDirectlyInAnyApex() bool { + return m.ApexProperties.AnyVariantDirectlyInAnyApex } -func (m *ApexModuleBase) IsForPlatform() bool { - return m.ApexProperties.Info.ApexVariationName == "" +func (m *ApexModuleBase) InAnyApex() bool { + return m.ApexProperties.InAnyApex } func (m *ApexModuleBase) CanHaveApexVariants() bool { @@ -345,10 +335,6 @@ func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) { } } -func (m *ApexModuleBase) Updatable() bool { - return m.ApexProperties.Info.Updatable -} - type byApexName []ApexInfo func (a byApexName) Len() int { return len(a) } @@ -366,11 +352,13 @@ func mergeApexVariations(ctx PathContext, apexVariations []ApexInfo) (merged []A mergedName := apexInfo.mergedName(ctx) if index, exists := seen[mergedName]; exists { merged[index].InApexes = append(merged[index].InApexes, apexName) + merged[index].ApexContents = append(merged[index].ApexContents, apexInfo.ApexContents...) merged[index].Updatable = merged[index].Updatable || apexInfo.Updatable } else { seen[mergedName] = len(merged) apexInfo.ApexVariationName = apexInfo.mergedName(ctx) apexInfo.InApexes = CopyOf(apexInfo.InApexes) + apexInfo.ApexContents = append([]*ApexContents(nil), apexInfo.ApexContents...) merged = append(merged, apexInfo) } aliases = append(aliases, [2]string{apexName, mergedName}) @@ -378,17 +366,23 @@ func mergeApexVariations(ctx PathContext, apexVariations []ApexInfo) (merged []A return merged, aliases } -func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []Module { - if len(m.apexVariations) > 0 { - m.checkApexAvailableProperty(mctx) +func CreateApexVariations(mctx BottomUpMutatorContext, module ApexModule) []Module { + base := module.apexModuleBase() + if len(base.apexVariations) > 0 { + base.checkApexAvailableProperty(mctx) var apexVariations []ApexInfo var aliases [][2]string - if !mctx.Module().(ApexModule).UniqueApexVariations() && !m.ApexProperties.UniqueApexVariationsForDeps { - apexVariations, aliases = mergeApexVariations(mctx, m.apexVariations) + if !mctx.Module().(ApexModule).UniqueApexVariations() && !base.ApexProperties.UniqueApexVariationsForDeps { + apexVariations, aliases = mergeApexVariations(mctx, base.apexVariations) } else { - apexVariations = m.apexVariations + apexVariations = base.apexVariations } + // base.apexVariations is only needed to propagate the list of apexes from + // apexDepsMutator 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.apexVariations = nil sort.Sort(byApexName(apexVariations)) variations := []string{} @@ -400,6 +394,16 @@ func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []Mod defaultVariation := "" mctx.SetDefaultDependencyVariation(&defaultVariation) + var inApex ApexMembership + for _, a := range apexVariations { + for _, apexContents := range a.ApexContents { + inApex = inApex.merge(apexContents.contents[mctx.ModuleName()]) + } + } + + base.ApexProperties.InAnyApex = true + base.ApexProperties.DirectlyInAnyApex = inApex == directlyInApex + modules := mctx.CreateVariations(variations...) for i, mod := range modules { platformVariation := i == 0 @@ -410,7 +414,7 @@ func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []Mod mod.MakeUninstallable() } if !platformVariation { - mod.(ApexModule).apexModuleBase().ApexProperties.Info = apexVariations[i-1] + mctx.SetVariationProvider(mod, ApexInfoProvider, apexVariations[i-1]) } } @@ -423,116 +427,139 @@ func (m *ApexModuleBase) CreateApexVariations(mctx BottomUpMutatorContext) []Mod return nil } -var apexData OncePer -var apexNamesMapMutex sync.Mutex -var apexNamesKey = NewOnceKey("apexNames") +// UpdateUniqueApexVariationsForDeps sets UniqueApexVariationsForDeps if any dependencies +// that are in the same APEX have unique APEX variations so that the module can link against +// the right variant. +func UpdateUniqueApexVariationsForDeps(mctx BottomUpMutatorContext, am ApexModule) { + // anyInSameApex returns true if the two ApexInfo lists contain any values in an InApexes list + // in common. It is used instead of DepIsInSameApex because it needs to determine if the dep + // is in the same APEX due to being directly included, not only if it is included _because_ it + // is a dependency. + anyInSameApex := func(a, b []ApexInfo) bool { + collectApexes := func(infos []ApexInfo) []string { + var ret []string + for _, info := range infos { + ret = append(ret, info.InApexes...) + } + return ret + } -// This structure maintains the global mapping in between modules and APEXes. -// Examples: -// -// apexNamesMap()["foo"]["bar"] == true: module foo is directly depended on by APEX bar -// apexNamesMap()["foo"]["bar"] == false: module foo is indirectly depended on by APEX bar -// apexNamesMap()["foo"]["bar"] doesn't exist: foo is not built for APEX bar -func apexNamesMap() map[string]map[string]bool { - return apexData.Once(apexNamesKey, func() interface{} { - return make(map[string]map[string]bool) - }).(map[string]map[string]bool) + aApexes := collectApexes(a) + bApexes := collectApexes(b) + sort.Strings(bApexes) + for _, aApex := range aApexes { + index := sort.SearchStrings(bApexes, aApex) + if index < len(bApexes) && bApexes[index] == aApex { + return true + } + } + return false + } + + mctx.VisitDirectDeps(func(dep Module) { + if depApexModule, ok := dep.(ApexModule); ok { + if anyInSameApex(depApexModule.apexModuleBase().apexVariations, am.apexModuleBase().apexVariations) && + (depApexModule.UniqueApexVariations() || + depApexModule.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps) { + am.apexModuleBase().ApexProperties.UniqueApexVariationsForDeps = true + } + } + }) } -// Update the map to mark that a module named moduleName is directly or indirectly -// depended on by the specified APEXes. Directly depending means that a module -// is explicitly listed in the build definition of the APEX via properties like -// native_shared_libs, java_libs, etc. -func UpdateApexDependency(apex ApexInfo, moduleName string, directDep bool) { - apexNamesMapMutex.Lock() - defer apexNamesMapMutex.Unlock() - apexesForModule, ok := apexNamesMap()[moduleName] - if !ok { - apexesForModule = make(map[string]bool) - apexNamesMap()[moduleName] = apexesForModule +// UpdateDirectlyInAnyApex uses the final module to store if any variant of this +// module is directly in any APEX, and then copies the final value to all the modules. +// It also copies the DirectlyInAnyApex value to any direct dependencies with a +// CopyDirectlyInAnyApexTag dependency tag. +func UpdateDirectlyInAnyApex(mctx BottomUpMutatorContext, am ApexModule) { + base := am.apexModuleBase() + // Copy DirectlyInAnyApex and InAnyApex from any direct dependencies with a + // CopyDirectlyInAnyApexTag dependency tag. + mctx.VisitDirectDeps(func(dep Module) { + if _, ok := mctx.OtherModuleDependencyTag(dep).(CopyDirectlyInAnyApexTag); ok { + depBase := dep.(ApexModule).apexModuleBase() + base.ApexProperties.DirectlyInAnyApex = depBase.ApexProperties.DirectlyInAnyApex + base.ApexProperties.InAnyApex = depBase.ApexProperties.InAnyApex + } + }) + + if base.ApexProperties.DirectlyInAnyApex { + // Variants of a module are always visited sequentially in order, so it is safe to + // write to another variant of this module. + // For a BottomUpMutator the PrimaryModule() is visited first and FinalModule() is + // visited last. + mctx.FinalModule().(ApexModule).apexModuleBase().ApexProperties.AnyVariantDirectlyInAnyApex = true } - apexesForModule[apex.ApexVariationName] = apexesForModule[apex.ApexVariationName] || directDep - for _, apexName := range apex.InApexes { - apexesForModule[apexName] = apexesForModule[apex.ApexVariationName] || directDep + + // If this is the FinalModule (last visited module) copy AnyVariantDirectlyInAnyApex to + // all the other variants + if am == mctx.FinalModule().(ApexModule) { + mctx.VisitAllModuleVariants(func(variant Module) { + variant.(ApexModule).apexModuleBase().ApexProperties.AnyVariantDirectlyInAnyApex = + base.ApexProperties.AnyVariantDirectlyInAnyApex + }) } } -// TODO(b/146393795): remove this when b/146393795 is fixed -func ClearApexDependency() { - m := apexNamesMap() - for k := range m { - delete(m, k) +type ApexMembership int + +const ( + notInApex ApexMembership = 0 + indirectlyInApex = iota + directlyInApex +) + +// Each apexBundle has an apexContents, and modules in that apex have a provider containing the +// apexContents of each apexBundle they are part of. +type ApexContents struct { + ApexName string + contents map[string]ApexMembership +} + +func NewApexContents(name string, contents map[string]ApexMembership) *ApexContents { + return &ApexContents{ + ApexName: name, + contents: contents, } } -// Tests whether a module named moduleName is directly depended on by an APEX -// named apexName. -func DirectlyInApex(apexName string, moduleName string) bool { - apexNamesMapMutex.Lock() - defer apexNamesMapMutex.Unlock() - if apexNamesForModule, ok := apexNamesMap()[moduleName]; ok { - return apexNamesForModule[apexName] +func (i ApexMembership) Add(direct bool) ApexMembership { + if direct || i == directlyInApex { + return directlyInApex } - return false + return indirectlyInApex +} + +func (i ApexMembership) merge(other ApexMembership) ApexMembership { + if other == directlyInApex || i == directlyInApex { + return directlyInApex + } + + if other == indirectlyInApex || i == indirectlyInApex { + return indirectlyInApex + } + return notInApex +} + +func (ac *ApexContents) DirectlyInApex(name string) bool { + return ac.contents[name] == directlyInApex +} + +func (ac *ApexContents) InApex(name string) bool { + return ac.contents[name] != notInApex } // Tests whether a module named moduleName is directly depended on by all APEXes -// in a list of apexNames. -func DirectlyInAllApexes(apexNames []string, moduleName string) bool { - apexNamesMapMutex.Lock() - defer apexNamesMapMutex.Unlock() - for _, apexName := range apexNames { - apexNamesForModule := apexNamesMap()[moduleName] - if !apexNamesForModule[apexName] { +// in an ApexInfo. +func DirectlyInAllApexes(apexInfo ApexInfo, moduleName string) bool { + for _, contents := range apexInfo.ApexContents { + if !contents.DirectlyInApex(moduleName) { return false } } return true } -type hostContext interface { - Host() bool -} - -// Tests whether a module named moduleName is directly depended on by any APEX. -func DirectlyInAnyApex(ctx hostContext, moduleName string) bool { - if ctx.Host() { - // Host has no APEX. - return false - } - apexNamesMapMutex.Lock() - defer apexNamesMapMutex.Unlock() - if apexNames, ok := apexNamesMap()[moduleName]; ok { - for an := range apexNames { - if apexNames[an] { - return true - } - } - } - return false -} - -// Tests whether a module named module is depended on (including both -// direct and indirect dependencies) by any APEX. -func InAnyApex(moduleName string) bool { - apexNamesMapMutex.Lock() - defer apexNamesMapMutex.Unlock() - apexNames, ok := apexNamesMap()[moduleName] - return ok && len(apexNames) > 0 -} - -func GetApexesForModule(moduleName string) []string { - ret := []string{} - apexNamesMapMutex.Lock() - defer apexNamesMapMutex.Unlock() - if apexNames, ok := apexNamesMap()[moduleName]; ok { - for an := range apexNames { - ret = append(ret, an) - } - } - return ret -} - func InitApexModule(m ApexModule) { base := m.apexModuleBase() base.canHaveApexVariants = true diff --git a/android/apex_test.go b/android/apex_test.go index dd372f792..512b50f96 100644 --- a/android/apex_test.go +++ b/android/apex_test.go @@ -29,10 +29,10 @@ func Test_mergeApexVariations(t *testing.T) { { name: "single", in: []ApexInfo{ - {"foo", "current", false, nil, []string{"foo"}}, + {"foo", "current", false, nil, []string{"foo"}, nil}, }, wantMerged: []ApexInfo{ - {"apex10000", "current", false, nil, []string{"foo"}}, + {"apex10000", "current", false, nil, []string{"foo"}, nil}, }, wantAliases: [][2]string{ {"foo", "apex10000"}, @@ -41,12 +41,11 @@ func Test_mergeApexVariations(t *testing.T) { { name: "merge", in: []ApexInfo{ - {"foo", "current", false, SdkRefs{{"baz", "1"}}, []string{"foo"}}, - {"bar", "current", false, SdkRefs{{"baz", "1"}}, []string{"bar"}}, + {"foo", "current", false, SdkRefs{{"baz", "1"}}, []string{"foo"}, nil}, + {"bar", "current", false, SdkRefs{{"baz", "1"}}, []string{"bar"}, nil}, }, wantMerged: []ApexInfo{ - {"apex10000_baz_1", "current", false, SdkRefs{{"baz", "1"}}, []string{"bar", "foo"}}, - }, + {"apex10000_baz_1", "current", false, SdkRefs{{"baz", "1"}}, []string{"bar", "foo"}, nil}}, wantAliases: [][2]string{ {"bar", "apex10000_baz_1"}, {"foo", "apex10000_baz_1"}, @@ -55,12 +54,12 @@ func Test_mergeApexVariations(t *testing.T) { { name: "don't merge version", in: []ApexInfo{ - {"foo", "current", false, nil, []string{"foo"}}, - {"bar", "30", false, nil, []string{"bar"}}, + {"foo", "current", false, nil, []string{"foo"}, nil}, + {"bar", "30", false, nil, []string{"bar"}, nil}, }, wantMerged: []ApexInfo{ - {"apex30", "30", false, nil, []string{"bar"}}, - {"apex10000", "current", false, nil, []string{"foo"}}, + {"apex30", "30", false, nil, []string{"bar"}, nil}, + {"apex10000", "current", false, nil, []string{"foo"}, nil}, }, wantAliases: [][2]string{ {"bar", "apex30"}, @@ -70,11 +69,11 @@ func Test_mergeApexVariations(t *testing.T) { { name: "merge updatable", in: []ApexInfo{ - {"foo", "current", false, nil, []string{"foo"}}, - {"bar", "current", true, nil, []string{"bar"}}, + {"foo", "current", false, nil, []string{"foo"}, nil}, + {"bar", "current", true, nil, []string{"bar"}, nil}, }, wantMerged: []ApexInfo{ - {"apex10000", "current", true, nil, []string{"bar", "foo"}}, + {"apex10000", "current", true, nil, []string{"bar", "foo"}, nil}, }, wantAliases: [][2]string{ {"bar", "apex10000"}, @@ -84,12 +83,12 @@ func Test_mergeApexVariations(t *testing.T) { { name: "don't merge sdks", in: []ApexInfo{ - {"foo", "current", false, SdkRefs{{"baz", "1"}}, []string{"foo"}}, - {"bar", "current", false, SdkRefs{{"baz", "2"}}, []string{"bar"}}, + {"foo", "current", false, SdkRefs{{"baz", "1"}}, []string{"foo"}, nil}, + {"bar", "current", false, SdkRefs{{"baz", "2"}}, []string{"bar"}, nil}, }, wantMerged: []ApexInfo{ - {"apex10000_baz_2", "current", false, SdkRefs{{"baz", "2"}}, []string{"bar"}}, - {"apex10000_baz_1", "current", false, SdkRefs{{"baz", "1"}}, []string{"foo"}}, + {"apex10000_baz_2", "current", false, SdkRefs{{"baz", "2"}}, []string{"bar"}, nil}, + {"apex10000_baz_1", "current", false, SdkRefs{{"baz", "1"}}, []string{"foo"}, nil}, }, wantAliases: [][2]string{ {"bar", "apex10000_baz_2"}, diff --git a/android/module.go b/android/module.go index c4e43c219..056b0a56c 100644 --- a/android/module.go +++ b/android/module.go @@ -1499,8 +1499,8 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) if !ctx.PrimaryArch() { suffix = append(suffix, ctx.Arch().ArchType.String()) } - if apex, ok := m.module.(ApexModule); ok && !apex.IsForPlatform() { - suffix = append(suffix, apex.ApexVariationName()) + if apexInfo := ctx.Provider(ApexInfoProvider).(ApexInfo); !apexInfo.IsForPlatform() { + suffix = append(suffix, apexInfo.ApexVariationName) } ctx.Variable(pctx, "moduleDesc", desc) diff --git a/apex/apex.go b/apex/apex.go index a5b228c2a..a9a58a66d 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -67,6 +67,7 @@ var ( androidAppTag = dependencyTag{name: "androidApp", payload: true} rroTag = dependencyTag{name: "rro", payload: true} bpfTag = dependencyTag{name: "bpf", payload: true} + testForTag = dependencyTag{name: "test for"} apexAvailBaseline = makeApexAvailableBaseline() @@ -769,7 +770,10 @@ func RegisterPreDepsMutators(ctx android.RegisterMutatorsContext) { func RegisterPostDepsMutators(ctx android.RegisterMutatorsContext) { ctx.TopDown("apex_deps", apexDepsMutator).Parallel() ctx.BottomUp("apex_unique", apexUniqueVariationsMutator).Parallel() + ctx.BottomUp("apex_test_for_deps", apexTestForDepsMutator).Parallel() + ctx.BottomUp("apex_test_for", apexTestForMutator).Parallel() ctx.BottomUp("apex", apexMutator).Parallel() + ctx.BottomUp("apex_directly_in_any", apexDirectlyInAnyMutator).Parallel() ctx.BottomUp("apex_flattened", apexFlattenedMutator).Parallel() ctx.BottomUp("apex_uses", apexUsesMutator).Parallel() ctx.BottomUp("mark_platform_availability", markPlatformAvailability).Parallel() @@ -785,13 +789,6 @@ func apexDepsMutator(mctx android.TopDownMutatorContext) { if !ok || a.vndkApex { return } - apexInfo := android.ApexInfo{ - ApexVariationName: mctx.ModuleName(), - MinSdkVersionStr: a.minSdkVersion(mctx).String(), - RequiredSdks: a.RequiredSdks(), - Updatable: a.Updatable(), - InApexes: []string{mctx.ModuleName()}, - } useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface()) excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable) @@ -800,7 +797,9 @@ func apexDepsMutator(mctx android.TopDownMutatorContext) { return } - mctx.WalkDeps(func(child, parent android.Module) bool { + contents := make(map[string]android.ApexMembership) + + continueApexDepsWalk := func(child, parent android.Module) bool { am, ok := child.(android.ApexModule) if !ok || !am.CanHaveApexVariants() { return false @@ -813,12 +812,41 @@ func apexDepsMutator(mctx android.TopDownMutatorContext) { return false } } + return true + } + + mctx.WalkDeps(func(child, parent android.Module) bool { + if !continueApexDepsWalk(child, parent) { + return false + } depName := mctx.OtherModuleName(child) // If the parent is apexBundle, this child is directly depended. _, directDep := parent.(*apexBundle) - android.UpdateApexDependency(apexInfo, depName, directDep) - am.BuildForApex(apexInfo) + contents[depName] = contents[depName].Add(directDep) + return true + }) + + apexContents := android.NewApexContents(mctx.ModuleName(), contents) + mctx.SetProvider(ApexBundleInfoProvider, ApexBundleInfo{ + Contents: apexContents, + }) + + apexInfo := android.ApexInfo{ + ApexVariationName: mctx.ModuleName(), + MinSdkVersionStr: a.minSdkVersion(mctx).String(), + RequiredSdks: a.RequiredSdks(), + Updatable: a.Updatable(), + InApexes: []string{mctx.ModuleName()}, + ApexContents: []*android.ApexContents{apexContents}, + } + + mctx.WalkDeps(func(child, parent android.Module) bool { + if !continueApexDepsWalk(child, parent) { + return false + } + + child.(android.ApexModule).BuildForApex(apexInfo) return true }) } @@ -830,7 +858,40 @@ func apexUniqueVariationsMutator(mctx android.BottomUpMutatorContext) { if am, ok := mctx.Module().(android.ApexModule); ok { // Check if any dependencies use unique apex variations. If so, use unique apex variations // for this module. - am.UpdateUniqueApexVariationsForDeps(mctx) + android.UpdateUniqueApexVariationsForDeps(mctx, am) + } +} + +func apexTestForDepsMutator(mctx android.BottomUpMutatorContext) { + if !mctx.Module().Enabled() { + return + } + // Check if this module is a test for an apex. If so, add a dependency on the apex + // in order to retrieve its contents later. + if am, ok := mctx.Module().(android.ApexModule); ok { + if testFor := am.TestFor(); len(testFor) > 0 { + mctx.AddFarVariationDependencies([]blueprint.Variation{ + {Mutator: "os", Variation: am.Target().OsVariation()}, + {"arch", "common"}, + }, testForTag, testFor...) + } + } +} + +func apexTestForMutator(mctx android.BottomUpMutatorContext) { + if !mctx.Module().Enabled() { + return + } + + if _, ok := mctx.Module().(android.ApexModule); ok { + var contents []*android.ApexContents + for _, testFor := range mctx.GetDirectDepsWithTag(testForTag) { + abInfo := mctx.OtherModuleProvider(testFor, ApexBundleInfoProvider).(ApexBundleInfo) + contents = append(contents, abInfo.Contents) + } + mctx.SetProvider(android.ApexTestForInfoProvider, android.ApexTestForInfo{ + ApexContents: contents, + }) } } @@ -891,8 +952,9 @@ func apexMutator(mctx android.BottomUpMutatorContext) { if !mctx.Module().Enabled() { return } + if am, ok := mctx.Module().(android.ApexModule); ok && am.CanHaveApexVariants() { - am.CreateApexVariations(mctx) + android.CreateApexVariations(mctx, am) } else if a, ok := mctx.Module().(*apexBundle); ok && !a.vndkApex { // apex bundle itself is mutated so that it and its modules have same // apex variant. @@ -909,6 +971,15 @@ func apexMutator(mctx android.BottomUpMutatorContext) { } +func apexDirectlyInAnyMutator(mctx android.BottomUpMutatorContext) { + if !mctx.Module().Enabled() { + return + } + if am, ok := mctx.Module().(android.ApexModule); ok { + android.UpdateDirectlyInAnyApex(mctx, am) + } +} + func apexFlattenedMutator(mctx android.BottomUpMutatorContext) { if !mctx.Module().Enabled() { return @@ -1118,6 +1189,12 @@ type apexBundleProperties struct { Payload_fs_type *string } +type ApexBundleInfo struct { + Contents *android.ApexContents +} + +var ApexBundleInfoProvider = blueprint.NewMutatorProvider(ApexBundleInfo{}, "apex_deps") + type apexTargetBundleProperties struct { Target struct { // Multilib properties only for android. @@ -1908,6 +1985,8 @@ func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.Paylo return false } + childApexInfo := ctx.OtherModuleProvider(child, android.ApexInfoProvider).(android.ApexInfo) + dt := ctx.OtherModuleDependencyTag(child) if _, ok := dt.(android.ExcludeFromApexContentsTag); ok { @@ -1924,7 +2003,7 @@ func (a *apexBundle) WalkPayloadDeps(ctx android.ModuleContext, do android.Paylo } // Check for the indirect dependencies if it is considered as part of the APEX - if android.InList(ctx.ModuleName(), am.InApexes()) { + if android.InList(ctx.ModuleName(), childApexInfo.InApexes) { return do(ctx, parent, am, false /* externalDep */) } @@ -2032,6 +2111,8 @@ func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext return } + abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo) + a.WalkPayloadDeps(ctx, func(ctx android.ModuleContext, from blueprint.Module, to android.ApexModule, externalDep bool) bool { if ccm, ok := to.(*cc.Module); ok { apexName := ctx.ModuleName() @@ -2052,7 +2133,7 @@ func (a *apexBundle) checkStaticLinkingToStubLibraries(ctx android.ModuleContext return false } - isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !android.DirectlyInApex(apexName, toName) + isStubLibraryFromOtherApex := ccm.HasStubsVariants() && !abInfo.Contents.DirectlyInApex(toName) if isStubLibraryFromOtherApex && !externalDep { ctx.ModuleErrorf("%q required by %q is a native library providing stub. "+ "It shouldn't be included in this APEX via static linking. Dependency path: %s", to.String(), fromName, ctx.GetPathString(false)) @@ -2291,7 +2372,8 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { } af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs) af.transitiveDep = true - if !a.Host() && !android.DirectlyInApex(ctx.ModuleName(), depName) && (cc.IsStubs() || cc.HasStubsVariants()) { + abInfo := ctx.Provider(ApexBundleInfoProvider).(ApexBundleInfo) + if !a.Host() && !abInfo.Contents.DirectlyInApex(depName) && (cc.IsStubs() || cc.HasStubsVariants()) { // If the dependency is a stubs lib, don't include it in this APEX, // but make sure that the lib is installed on the device. // In case no APEX is having the lib, the lib is installed to the system @@ -2299,7 +2381,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // // Always include if we are a host-apex however since those won't have any // system libraries. - if !android.DirectlyInAnyApex(ctx, depName) { + if !am.DirectlyInAnyApex() { // we need a module name for Make name := cc.BaseModuleName() + cc.Properties.SubName if proptools.Bool(a.properties.Use_vendor) { @@ -2338,6 +2420,8 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok { filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName)) } + } else if _, ok := depTag.(android.CopyDirectlyInAnyApexTag); ok { + // nothing } else if am.CanHaveApexVariants() && am.IsInstallableToApex() { ctx.ModuleErrorf("unexpected tag %s for indirect dependency %q", android.PrettyPrintTag(depTag), depName) } diff --git a/apex/apex_singleton.go b/apex/apex_singleton.go index afb739cef..803e0c559 100644 --- a/apex/apex_singleton.go +++ b/apex/apex_singleton.go @@ -72,8 +72,11 @@ func (s *apexDepsInfoSingleton) GenerateBuildActions(ctx android.SingletonContex updatableFlatLists := android.Paths{} ctx.VisitAllModules(func(module android.Module) { if binaryInfo, ok := module.(android.ApexBundleDepsInfoIntf); ok { - if path := binaryInfo.FlatListPath(); path != nil && binaryInfo.Updatable() { - updatableFlatLists = append(updatableFlatLists, path) + apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) + if path := binaryInfo.FlatListPath(); path != nil { + if binaryInfo.Updatable() || apexInfo.Updatable { + updatableFlatLists = append(updatableFlatLists, path) + } } } }) diff --git a/apex/apex_test.go b/apex/apex_test.go index 71c4aa268..cf2c9533b 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -125,8 +125,6 @@ func withUnbundledBuild(_ map[string][]byte, config android.Config) { } func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) { - android.ClearApexDependency() - bp = bp + ` filegroup { name: "myapex-file_contexts", @@ -1607,10 +1605,12 @@ func TestPlatformUsesLatestStubsFromApexes(t *testing.T) { `) expectLink := func(from, from_variant, to, to_variant string) { + t.Helper() ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] ensureContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") } expectNoLink := func(from, from_variant, to, to_variant string) { + t.Helper() ldArgs := ctx.ModuleForTests(from, "android_arm64_armv8-a_"+from_variant).Rule("ld").Args["libFlags"] ensureNotContains(t, ldArgs, "android_arm64_armv8-a_"+to_variant+"/"+to+".so") } @@ -3643,16 +3643,13 @@ func TestNonTestApex(t *testing.T) { // Ensure that the platform variant ends with _shared ensureListContains(t, ctx.ModuleVariantsForTests("mylib_common"), "android_arm64_armv8-a_shared") - if !android.InAnyApex("mylib_common") { + if !ctx.ModuleForTests("mylib_common", "android_arm64_armv8-a_shared_apex10000").Module().(*cc.Module).InAnyApex() { t.Log("Found mylib_common not in any apex!") t.Fail() } } func TestTestApex(t *testing.T) { - if android.InAnyApex("mylib_common_test") { - t.Fatal("mylib_common_test must not be used in any other tests since this checks that global state is not updated in an illegal way!") - } ctx, _ := testApex(t, ` apex_test { name: "myapex", @@ -5845,7 +5842,6 @@ func TestNoUpdatableJarsInBootImage(t *testing.T) { func testApexPermittedPackagesRules(t *testing.T, errmsg, bp string, apexBootJars []string, rules []android.Rule) { t.Helper() - android.ClearApexDependency() bp += ` apex_key { name: "myapex.key", diff --git a/cc/androidmk.go b/cc/androidmk.go index d92fabc0d..a2549b8e7 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -33,7 +33,6 @@ var ( ) type AndroidMkContext interface { - BaseModuleName() string Target() android.Target subAndroidMk(*android.AndroidMkEntries, interface{}) Arch() android.Arch @@ -44,6 +43,7 @@ type AndroidMkContext interface { static() bool InRamdisk() bool InRecovery() bool + AnyVariantDirectlyInAnyApex() bool } type subAndroidMkProvider interface { @@ -63,7 +63,7 @@ func (c *Module) subAndroidMk(entries *android.AndroidMkEntries, obj interface{} } func (c *Module) AndroidMkEntries() []android.AndroidMkEntries { - if c.Properties.HideFromMake || !c.IsForPlatform() { + if c.hideApexVariantFromMake || c.Properties.HideFromMake { return []android.AndroidMkEntries{{ Disabled: true, }} @@ -277,9 +277,8 @@ func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries } }) } - if len(library.Properties.Stubs.Versions) > 0 && - android.DirectlyInAnyApex(ctx, ctx.BaseModuleName()) && !ctx.InRamdisk() && !ctx.InRecovery() && !ctx.UseVndk() && - !ctx.static() { + if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.AnyVariantDirectlyInAnyApex() && + !ctx.InRamdisk() && !ctx.InRecovery() && !ctx.UseVndk() && !ctx.static() { if library.buildStubs() && library.isLatestStubVersion() { // reference the latest version via its name without suffix when it is provided by apex entries.SubName = "" diff --git a/cc/binary.go b/cc/binary.go index b3ce5ff1c..7f7b619d5 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -445,7 +445,9 @@ func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) { // The original path becomes a symlink to the corresponding file in the // runtime APEX. translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled - if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !translatedArch && ctx.apexVariationName() == "" && !ctx.inRamdisk() && !ctx.inRecovery() { + if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !ctx.Host() && ctx.directlyInAnyApex() && + !translatedArch && ctx.apexVariationName() == "" && !ctx.inRamdisk() && !ctx.inRecovery() { + if ctx.Device() && isBionic(ctx.baseModuleName()) { binary.installSymlinkToRuntimeApex(ctx, file) } diff --git a/cc/cc.go b/cc/cc.go index 03290ad88..81885509b 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -366,6 +366,7 @@ type ModuleContextIntf interface { bootstrap() bool mustUseVendorVariant() bool nativeCoverage() bool + directlyInAnyApex() bool } type ModuleContext interface { @@ -545,8 +546,17 @@ var ( dataLibDepTag = dependencyTag{name: "data lib"} runtimeDepTag = dependencyTag{name: "runtime lib"} testPerSrcDepTag = dependencyTag{name: "test_per_src"} + testForDepTag = dependencyTag{name: "test for apex"} + + stubImplDepTag = copyDirectlyInAnyApexDependencyTag{name: "stub_impl"} ) +type copyDirectlyInAnyApexDependencyTag dependencyTag + +func (copyDirectlyInAnyApexDependencyTag) CopyDirectlyInAnyApex() {} + +var _ android.CopyDirectlyInAnyApexTag = copyDirectlyInAnyApexDependencyTag{} + func IsSharedDepTag(depTag blueprint.DependencyTag) bool { ccLibDepTag, ok := depTag.(libraryDependencyTag) return ok && ccLibDepTag.shared() @@ -622,6 +632,8 @@ type Module struct { // For apex variants, this is set as apex.min_sdk_version apexSdkVersion android.ApiLevel + + hideApexVariantFromMake bool } func (c *Module) Toc() android.OptionalPath { @@ -1363,11 +1375,11 @@ func (ctx *moduleContextImpl) getVndkExtendsModuleName() string { } func (ctx *moduleContextImpl) isForPlatform() bool { - return ctx.mod.IsForPlatform() + return ctx.ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() } func (ctx *moduleContextImpl) apexVariationName() string { - return ctx.mod.ApexVariationName() + return ctx.ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).ApexVariationName } func (ctx *moduleContextImpl) apexSdkVersion() android.ApiLevel { @@ -1390,6 +1402,10 @@ func (ctx *moduleContextImpl) nativeCoverage() bool { return ctx.mod.nativeCoverage() } +func (ctx *moduleContextImpl) directlyInAnyApex() bool { + return ctx.mod.DirectlyInAnyApex() +} + func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { return &Module{ hod: hod, @@ -1545,6 +1561,11 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { return } + apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo) + if !apexInfo.IsForPlatform() { + c.hideApexVariantFromMake = true + } + c.makeLinkType = c.getMakeLinkType(actx) c.Properties.SubName = "" @@ -1676,8 +1697,7 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { // force anything in the make world to link against the stubs library. // (unless it is explicitly referenced via .bootstrap suffix or the // module is marked with 'bootstrap: true'). - if c.HasStubsVariants() && - android.DirectlyInAnyApex(ctx, ctx.baseModuleName()) && !c.InRamdisk() && + if c.HasStubsVariants() && c.AnyVariantDirectlyInAnyApex() && !c.InRamdisk() && !c.InRecovery() && !c.UseVndk() && !c.static() && !c.isCoverageVariant() && c.IsStubs() { c.Properties.HideFromMake = false // unhide @@ -1686,13 +1706,13 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { // glob exported headers for snapshot, if BOARD_VNDK_VERSION is current. if i, ok := c.linker.(snapshotLibraryInterface); ok && ctx.DeviceConfig().VndkVersion() == "current" { - if isSnapshotAware(ctx, c) { + if isSnapshotAware(ctx, c, apexInfo) { i.collectHeadersForSnapshot(ctx) } } } - if c.installable() { + if c.installable(apexInfo) { c.installer.install(ctx, c.outputFile.Path()) if ctx.Failed() { return @@ -2381,8 +2401,9 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // For the dependency from platform to apex, use the latest stubs c.apexSdkVersion = android.FutureApiLevel - if !c.IsForPlatform() { - c.apexSdkVersion = c.ApexProperties.Info.MinSdkVersion(ctx) + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + if !apexInfo.IsForPlatform() { + c.apexSdkVersion = apexInfo.MinSdkVersion(ctx) } if android.InList("hwaddress", ctx.Config().SanitizeDevice()) { @@ -2493,8 +2514,8 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { if ccDep.CcLibrary() && !libDepTag.static() { depIsStubs := ccDep.BuildStubs() depHasStubs := CanBeOrLinkAgainstVersionVariants(c) && ccDep.HasStubsVariants() - depInSameApexes := android.DirectlyInAllApexes(c.InApexes(), depName) - depInPlatform := !android.DirectlyInAnyApex(ctx, depName) + depInSameApexes := android.DirectlyInAllApexes(apexInfo, depName) + depInPlatform := !dep.(android.ApexModule).AnyVariantDirectlyInAnyApex() var useThisDep bool if depIsStubs && libDepTag.explicitlyVersioned { @@ -2504,7 +2525,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // Use non-stub variant if that is the only choice // (i.e. depending on a lib without stubs.version property) useThisDep = true - } else if c.IsForPlatform() { + } else if apexInfo.IsForPlatform() { // If not building for APEX, use stubs only when it is from // an APEX (and not from platform) useThisDep = (depInPlatform != depIsStubs) @@ -2513,11 +2534,12 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // always link to non-stub variant useThisDep = !depIsStubs } - for _, testFor := range c.TestFor() { - // Another exception: if this module is bundled with an APEX, then - // it is linked with the non-stub variant of a module in the APEX - // as if this is part of the APEX. - if android.DirectlyInApex(testFor, depName) { + // Another exception: if this module is bundled with an APEX, then + // it is linked with the non-stub variant of a module in the APEX + // as if this is part of the APEX. + testFor := ctx.Provider(android.ApexTestForInfoProvider).(android.ApexTestForInfo) + for _, apexContents := range testFor.ApexContents { + if apexContents.DirectlyInApex(depName) { useThisDep = !depIsStubs break } @@ -2549,7 +2571,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // by default, use current version of LLNDK versionToUse := "" versions := m.AllStubsVersions() - if c.ApexVariationName() != "" && len(versions) > 0 { + if apexInfo.ApexVariationName != "" && len(versions) > 0 { // if this is for use_vendor apex && dep has stubsVersions // apply the same rule of apex sdk enforcement to choose right version var err error @@ -2711,10 +2733,11 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { c.Properties.AndroidMkHeaderLibs, makeLibName) case libDepTag.shared(): if ccDep.CcLibrary() { - if ccDep.BuildStubs() && android.InAnyApex(depName) { + if ccDep.BuildStubs() && dep.(android.ApexModule).InAnyApex() { // Add the dependency to the APEX(es) providing the library so that // m can trigger building the APEXes as well. - for _, an := range android.GetApexesForModule(depName) { + depApexInfo := ctx.OtherModuleProvider(dep, android.ApexInfoProvider).(android.ApexInfo) + for _, an := range depApexInfo.InApexes { c.Properties.ApexesProvidingSharedLibs = append( c.Properties.ApexesProvidingSharedLibs, an) } @@ -3018,7 +3041,7 @@ func (c *Module) EverInstallable() bool { c.installer.everInstallable() } -func (c *Module) installable() bool { +func (c *Module) installable(apexInfo android.ApexInfo) bool { ret := c.EverInstallable() && // Check to see whether the module has been configured to not be installed. proptools.BoolDefault(c.Properties.Installable, true) && @@ -3027,7 +3050,7 @@ func (c *Module) installable() bool { // The platform variant doesn't need further condition. Apex variants however might not // be installable because it will likely to be included in the APEX and won't appear // in the system partition. - if c.IsForPlatform() { + if apexInfo.IsForPlatform() { return ret } diff --git a/cc/library.go b/cc/library.go index b5bec952a..35828aa71 100644 --- a/cc/library.go +++ b/cc/library.go @@ -1231,18 +1231,19 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { library.baseInstaller.subDir += "-" + vndkVersion } } - } else if len(library.Properties.Stubs.Versions) > 0 && android.DirectlyInAnyApex(ctx, ctx.ModuleName()) { + } else if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.directlyInAnyApex() { // Bionic libraries (e.g. libc.so) is installed to the bootstrap subdirectory. // The original path becomes a symlink to the corresponding file in the // runtime APEX. translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled - if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() && !translatedArch && !ctx.inRamdisk() && !ctx.inRecovery() { + if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !library.buildStubs() && + !translatedArch && !ctx.inRamdisk() && !ctx.inRecovery() { if ctx.Device() { library.installSymlinkToRuntimeApex(ctx, file) } library.baseInstaller.subDir = "bootstrap" } - } else if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && ctx.isLlndk(ctx.Config()) && !isBionic(ctx.baseModuleName()) { + } else if ctx.directlyInAnyApex() && ctx.isLlndk(ctx.Config()) && !isBionic(ctx.baseModuleName()) { // Skip installing LLNDK (non-bionic) libraries moved to APEX. ctx.Module().SkipInstall() } @@ -1531,6 +1532,8 @@ func createVersionVariations(mctx android.BottomUpMutatorContext, versions []str if variants[i] != "" { m.(LinkableInterface).SetBuildStubs() m.(LinkableInterface).SetStubsVersion(variants[i]) + // The stubs depend on the implementation + mctx.AddInterVariantDependency(stubImplDepTag, modules[i], modules[0]) } } mctx.AliasVariation("") diff --git a/cc/llndk_library.go b/cc/llndk_library.go index b3f9d6177..a42906323 100644 --- a/cc/llndk_library.go +++ b/cc/llndk_library.go @@ -74,6 +74,8 @@ type llndkStubDecorator struct { exportHeadersTimestamp android.OptionalPath versionScriptPath android.ModuleGenPath + + movedToApex bool } func (stub *llndkStubDecorator) compilerFlags(ctx ModuleContext, flags Flags, deps PathDeps) Flags { @@ -135,6 +137,11 @@ func (stub *llndkStubDecorator) processHeaders(ctx ModuleContext, srcHeaderDir s func (stub *llndkStubDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { + impl := ctx.GetDirectDepWithTag(ctx.baseModuleName(), llndkImplDep) + if implApexModule, ok := impl.(android.ApexModule); ok { + stub.movedToApex = implApexModule.DirectlyInAnyApex() + } + if !Bool(stub.Properties.Unversioned) { linkerScriptFlag := "-Wl,--version-script," + stub.versionScriptPath.String() flags.Local.LdFlags = append(flags.Local.LdFlags, linkerScriptFlag) diff --git a/cc/snapshot_utils.go b/cc/snapshot_utils.go index f27d166f4..b72af4405 100644 --- a/cc/snapshot_utils.go +++ b/cc/snapshot_utils.go @@ -58,10 +58,10 @@ func (s *snapshotMap) get(name string, arch android.ArchType) (snapshot string, return snapshot, found } -func isSnapshotAware(ctx android.ModuleContext, m *Module) bool { - if _, _, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m); ok { +func isSnapshotAware(ctx android.ModuleContext, m *Module, apexInfo android.ApexInfo) bool { + if _, _, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m, apexInfo); ok { return ctx.Config().VndkSnapshotBuildArtifacts() - } else if isVendorSnapshotModule(m, isVendorProprietaryPath(ctx.ModuleDir())) { + } else if isVendorSnapshotModule(m, isVendorProprietaryPath(ctx.ModuleDir()), apexInfo) { return true } return false diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go index 2819f4958..529ed600e 100644 --- a/cc/vendor_snapshot.go +++ b/cc/vendor_snapshot.go @@ -537,7 +537,7 @@ func isVendorProprietaryModule(ctx android.BaseModuleContext) bool { // AOSP. They are not guaranteed to be compatible with older vendor images. (e.g. might // depend on newer VNDK) So they are captured as vendor snapshot To build older vendor // image and newer system image altogether. -func isVendorSnapshotModule(m *Module, inVendorProprietaryPath bool) bool { +func isVendorSnapshotModule(m *Module, inVendorProprietaryPath bool, apexInfo android.ApexInfo) bool { if !m.Enabled() || m.Properties.HideFromMake { return false } @@ -562,7 +562,7 @@ func isVendorSnapshotModule(m *Module, inVendorProprietaryPath bool) bool { return false } // the module must be installed in /vendor - if !m.IsForPlatform() || m.isSnapshotPrebuilt() || !m.inVendor() { + if !apexInfo.IsForPlatform() || m.isSnapshotPrebuilt() || !m.inVendor() { return false } // skip kernel_headers which always depend on vendor @@ -825,6 +825,7 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont moduleDir := ctx.ModuleDir(module) inVendorProprietaryPath := isVendorProprietaryPath(moduleDir) + apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) if m.ExcludeFromVendorSnapshot() { if inVendorProprietaryPath { @@ -842,7 +843,7 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont } } - if !isVendorSnapshotModule(m, inVendorProprietaryPath) { + if !isVendorSnapshotModule(m, inVendorProprietaryPath, apexInfo) { return } diff --git a/cc/vndk.go b/cc/vndk.go index 9a2fa09d4..4169e2129 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -300,6 +300,7 @@ func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) { if !Bool(lib.Properties.Vendor_available) { vndkPrivateLibraries(mctx.Config())[name] = filename } + if mctx.OtherModuleExists(name) { mctx.AddFarVariationDependencies(m.Target().Variations(), llndkImplDep, name) } @@ -533,11 +534,13 @@ type vndkSnapshotSingleton struct { vndkSnapshotZipFile android.OptionalPath } -func isVndkSnapshotLibrary(config android.DeviceConfig, m *Module) (i snapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) { +func isVndkSnapshotLibrary(config android.DeviceConfig, m *Module, + apexInfo android.ApexInfo) (i snapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) { + if m.Target().NativeBridge == android.NativeBridgeEnabled { return nil, "", false } - if !m.inVendor() || !m.installable() || m.isSnapshotPrebuilt() { + if !m.inVendor() || !m.installable(apexInfo) || m.isSnapshotPrebuilt() { return nil, "", false } l, ok := m.linker.(snapshotLibraryInterface) @@ -659,7 +662,9 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex return } - l, vndkType, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m) + apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) + + l, vndkType, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m, apexInfo) if !ok { return } @@ -823,14 +828,21 @@ func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.Singleton func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) { // Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to avoid installing libraries on /system if // they been moved to an apex. - movedToApexLlndkLibraries := []string{} - for lib := range llndkLibraries(ctx.Config()) { - // Skip bionic libs, they are handled in different manner - if android.DirectlyInAnyApex(¬OnHostContext{}, lib) && !isBionic(lib) { - movedToApexLlndkLibraries = append(movedToApexLlndkLibraries, lib) + movedToApexLlndkLibraries := make(map[string]bool) + ctx.VisitAllModules(func(module android.Module) { + if m, ok := module.(*Module); ok { + if llndk, ok := m.linker.(*llndkStubDecorator); ok { + // Skip bionic libs, they are handled in different manner + name := m.BaseModuleName() + if llndk.movedToApex && !isBionic(m.BaseModuleName()) { + movedToApexLlndkLibraries[name] = true + } + } } - } - ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES", strings.Join(movedToApexLlndkLibraries, " ")) + }) + + ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES", + strings.Join(android.SortedStringKeys(movedToApexLlndkLibraries), " ")) // Make uses LLNDK_LIBRARIES to determine which libraries to install. // HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN. diff --git a/java/aar.go b/java/aar.go index 9cab0bdca..8d2a74ad1 100644 --- a/java/aar.go +++ b/java/aar.go @@ -477,6 +477,8 @@ func (a *AndroidLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) a.aapt.buildActions(ctx, sdkContext(a)) a.exportedSdkLibs = a.aapt.sdkLibraries + a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() + ctx.CheckbuildFile(a.proguardOptionsFile) ctx.CheckbuildFile(a.exportPackage) ctx.CheckbuildFile(a.aaptSrcJar) @@ -569,6 +571,8 @@ type AARImport struct { manifest android.WritablePath exportedStaticPackages android.Paths + + hideApexVariantFromMake bool } func (a *AARImport) sdkVersion() sdkSpec { @@ -662,6 +666,8 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { return } + a.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() + aarName := ctx.ModuleName() + ".aar" var aar android.Path aar = android.PathForModuleSrc(ctx, a.properties.Aars[0]) diff --git a/java/androidmk.go b/java/androidmk.go index 65c44a329..f72ee3760 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -23,8 +23,7 @@ import ( func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries { hostDexNeeded := Bool(library.deviceProperties.Hostdex) && !library.Host() - if !library.IsForPlatform() { - // Don't emit hostdex modules from the APEX variants + if library.hideApexVariantFromMake { hostDexNeeded = false } @@ -61,22 +60,15 @@ func (library *Library) AndroidMkEntriesHostDex() android.AndroidMkEntries { func (library *Library) AndroidMkEntries() []android.AndroidMkEntries { var entriesList []android.AndroidMkEntries - mainEntries := android.AndroidMkEntries{Disabled: true} - - // For a java library built for an APEX, we don't need Make module - hideFromMake := !library.IsForPlatform() - // If not available for platform, don't emit to make. - if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) { - hideFromMake = true - } - if hideFromMake { - // May still need to add some additional dependencies. This will be called - // once for the platform variant (even if it is not being used) and once each - // for the APEX specific variants. In order to avoid adding the dependency - // multiple times only add it for the platform variant. + if library.hideApexVariantFromMake { + // For a java library built for an APEX we don't need Make module + entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true}) + } else if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) { + // Platform variant. If not available for the platform, we don't need Make module. + // May still need to add some additional dependencies. checkedModulePaths := library.additionalCheckedModules - if library.IsForPlatform() && len(checkedModulePaths) != 0 { - mainEntries = android.AndroidMkEntries{ + if len(checkedModulePaths) != 0 { + entriesList = append(entriesList, android.AndroidMkEntries{ Class: "FAKE", // Need at least one output file in order for this to take effect. OutputFile: android.OptionalPathForPath(checkedModulePaths[0]), @@ -86,10 +78,12 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries { entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", checkedModulePaths.Strings()...) }, }, - } + }) + } else { + entriesList = append(entriesList, android.AndroidMkEntries{Disabled: true}) } } else { - mainEntries = android.AndroidMkEntries{ + entriesList = append(entriesList, android.AndroidMkEntries{ Class: "JAVA_LIBRARIES", DistFiles: library.distFiles, OutputFile: android.OptionalPathForPath(library.outputFile), @@ -134,12 +128,11 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries { entries.SetOptionalPaths("LOCAL_SOONG_LINT_REPORTS", library.linter.reports) }, }, - } + }) } - hostDexEntries := library.AndroidMkEntriesHostDex() + entriesList = append(entriesList, library.AndroidMkEntriesHostDex()) - entriesList = append(entriesList, mainEntries, hostDexEntries) return entriesList } @@ -189,7 +182,7 @@ func (j *TestHelperLibrary) AndroidMkEntries() []android.AndroidMkEntries { } func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries { - if !prebuilt.IsForPlatform() || !prebuilt.ContainingSdk().Unversioned() { + if prebuilt.hideApexVariantFromMake || !prebuilt.ContainingSdk().Unversioned() { return []android.AndroidMkEntries{android.AndroidMkEntries{ Disabled: true, }} @@ -211,7 +204,7 @@ func (prebuilt *Import) AndroidMkEntries() []android.AndroidMkEntries { } func (prebuilt *DexImport) AndroidMkEntries() []android.AndroidMkEntries { - if !prebuilt.IsForPlatform() { + if prebuilt.hideApexVariantFromMake { return []android.AndroidMkEntries{android.AndroidMkEntries{ Disabled: true, }} @@ -239,7 +232,7 @@ func (prebuilt *DexImport) AndroidMkEntries() []android.AndroidMkEntries { } func (prebuilt *AARImport) AndroidMkEntries() []android.AndroidMkEntries { - if !prebuilt.IsForPlatform() { + if prebuilt.hideApexVariantFromMake { return []android.AndroidMkEntries{{ Disabled: true, }} @@ -309,7 +302,7 @@ func (binary *Binary) AndroidMkEntries() []android.AndroidMkEntries { } func (app *AndroidApp) AndroidMkEntries() []android.AndroidMkEntries { - if !app.IsForPlatform() || app.appProperties.HideFromMake { + if app.hideApexVariantFromMake || app.appProperties.HideFromMake { return []android.AndroidMkEntries{android.AndroidMkEntries{ Disabled: true, }} @@ -458,7 +451,7 @@ func (a *AndroidTestHelperApp) AndroidMkEntries() []android.AndroidMkEntries { } func (a *AndroidLibrary) AndroidMkEntries() []android.AndroidMkEntries { - if !a.IsForPlatform() { + if a.hideApexVariantFromMake { return []android.AndroidMkEntries{{ Disabled: true, }} @@ -638,7 +631,7 @@ func (dstubs *Droidstubs) AndroidMkEntries() []android.AndroidMkEntries { } func (a *AndroidAppImport) AndroidMkEntries() []android.AndroidMkEntries { - if !a.IsForPlatform() { + if a.hideApexVariantFromMake { // The non-platform variant is placed inside APEX. No reason to // make it available to Make. return nil diff --git a/java/app.go b/java/app.go index 13d08b94a..c25835c41 100755 --- a/java/app.go +++ b/java/app.go @@ -480,8 +480,9 @@ func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool { ctx.PropertyErrorf("min_sdk_version", "invalid value %q: %s", a.minSdkVersion(), err) } + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) return (minSdkVersion >= 23 && Bool(a.appProperties.Use_embedded_native_libs)) || - !a.IsForPlatform() + !apexInfo.IsForPlatform() } // Returns whether this module should have the dex file stored uncompressed in the APK. @@ -504,8 +505,9 @@ func (a *AndroidApp) shouldUncompressDex(ctx android.ModuleContext) bool { } func (a *AndroidApp) shouldEmbedJnis(ctx android.BaseModuleContext) bool { + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) return ctx.Config().UnbundledBuild() || Bool(a.appProperties.Use_embedded_native_libs) || - !a.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs + !apexInfo.IsForPlatform() || a.appProperties.AlwaysPackageNativeLibs } func generateAaptRenamePackageFlags(packageName string, renameResourcesPackage bool) []string { @@ -756,6 +758,10 @@ func (a *AndroidApp) InstallApkName() string { func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { var apkDeps android.Paths + if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() { + a.hideApexVariantFromMake = true + } + a.aapt.useEmbeddedNativeLibs = a.useEmbeddedNativeLibs(ctx) a.aapt.useEmbeddedDex = Bool(a.appProperties.Use_embedded_dex) @@ -850,8 +856,10 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { BuildBundleModule(ctx, bundleFile, a.exportPackage, jniJarFile, dexJarFile) a.bundleFile = bundleFile + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + // Install the app package. - if (Bool(a.Module.properties.Installable) || ctx.Host()) && a.IsForPlatform() { + if (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() { ctx.InstallFile(a.installDir, a.outputFile.Base(), a.outputFile) for _, extra := range a.extraOutputFiles { ctx.InstallFile(a.installDir, extra.Base(), extra) @@ -979,7 +987,7 @@ func (a *AndroidApp) buildAppDependencyInfo(ctx android.ModuleContext) { } func (a *AndroidApp) Updatable() bool { - return Bool(a.appProperties.Updatable) || a.ApexModuleBase.Updatable() + return Bool(a.appProperties.Updatable) } func (a *AndroidApp) getCertString(ctx android.BaseModuleContext) string { @@ -1335,6 +1343,8 @@ type AndroidAppImport struct { preprocessed bool installPath android.InstallPath + + hideApexVariantFromMake bool } type AndroidAppImportProperties struct { @@ -1481,6 +1491,11 @@ func (a *AndroidAppImport) InstallApkName() string { } func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext) { + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + if !apexInfo.IsForPlatform() { + a.hideApexVariantFromMake = true + } + numCertPropsSet := 0 if String(a.properties.Certificate) != "" { numCertPropsSet++ @@ -1569,7 +1584,7 @@ func (a *AndroidAppImport) generateAndroidBuildActions(ctx android.ModuleContext // TODO: Optionally compress the output apk. - if a.IsForPlatform() { + if apexInfo.IsForPlatform() { a.installPath = ctx.InstallFile(installDir, apkFilename, a.outputFile) } diff --git a/java/dexpreopt.go b/java/dexpreopt.go index f1b717874..20dbc666b 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -94,7 +94,7 @@ func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool { } // Don't preopt APEX variant module - if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() { + if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() { return true } diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 7877031f8..9f49786ba 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -266,12 +266,13 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul } // Check that this module satisfies constraints for a particular boot image. - apex, isApexModule := module.(android.ApexModule) - fromUpdatableApex := isApexModule && apex.Updatable() + _, isApexModule := module.(android.ApexModule) + apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) + fromUpdatableApex := isApexModule && apexInfo.Updatable if image.name == artBootImageName { - if isApexModule && len(apex.InApexes()) > 0 && allHavePrefix(apex.InApexes(), "com.android.art.") { + if isApexModule && len(apexInfo.InApexes) > 0 && allHavePrefix(apexInfo.InApexes, "com.android.art.") { // ok: found the jar in the ART apex - } else if isApexModule && apex.IsForPlatform() && isHostdex(module) { + } else if isApexModule && apexInfo.IsForPlatform() && isHostdex(module) { // exception (skip and continue): special "hostdex" platform variant return -1, nil } else if name == "jacocoagent" && ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { @@ -279,7 +280,7 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul return -1, nil } else if fromUpdatableApex { // error: this jar is part of an updatable apex other than ART - ctx.Errorf("module %q from updatable apexes %q is not allowed in the ART boot image", name, apex.InApexes()) + ctx.Errorf("module %q from updatable apexes %q is not allowed in the ART boot image", name, apexInfo.InApexes) } else { // error: this jar is part of the platform or a non-updatable apex ctx.Errorf("module %q is not allowed in the ART boot image", name) @@ -289,7 +290,7 @@ func getBootImageJar(ctx android.SingletonContext, image *bootImageConfig, modul // ok: this jar is part of the platform or a non-updatable apex } else { // error: this jar is part of an updatable apex - ctx.Errorf("module %q from updatable apexes %q is not allowed in the framework boot image", name, apex.InApexes()) + ctx.Errorf("module %q from updatable apexes %q is not allowed in the framework boot image", name, apexInfo.InApexes) } } else { panic("unknown boot image: " + image.name) diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go index 61a9b97e4..b140b899b 100644 --- a/java/hiddenapi_singleton.go +++ b/java/hiddenapi_singleton.go @@ -161,10 +161,9 @@ func stubFlagsRule(ctx android.SingletonContext) { // For a java lib included in an APEX, only take the one built for // the platform variant, and skip the variants for APEXes. // Otherwise, the hiddenapi tool will complain about duplicated classes - if a, ok := module.(android.ApexModule); ok { - if android.InAnyApex(module.Name()) && !a.IsForPlatform() { - return - } + apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo) + if !apexInfo.IsForPlatform() { + return } bootDexJars = append(bootDexJars, jar) diff --git a/java/java.go b/java/java.go index cdf162827..2553a30bd 100644 --- a/java/java.go +++ b/java/java.go @@ -451,6 +451,8 @@ type Module struct { // Collect the module directory for IDE info in java/jdeps.go. modulePaths []string + + hideApexVariantFromMake bool } func (j *Module) addHostProperties() { @@ -638,8 +640,9 @@ func (j *Module) shouldInstrumentInApex(ctx android.BaseModuleContext) bool { // Force enable the instrumentation for java code that is built for APEXes ... // except for the jacocoagent itself (because instrumenting jacocoagent using jacocoagent // doesn't make sense) or framework libraries (e.g. libraries found in the InstrumentFrameworkModules list) unless EMMA_INSTRUMENT_FRAMEWORK is true. + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) isJacocoAgent := ctx.ModuleName() == "jacocoagent" - if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !isJacocoAgent && !j.IsForPlatform() { + if j.DirectlyInAnyApex() && !isJacocoAgent && !apexInfo.IsForPlatform() { if !inList(ctx.ModuleName(), config.InstrumentFrameworkModules) { return true } else if ctx.Config().IsEnvTrue("EMMA_INSTRUMENT_FRAMEWORK") { @@ -1602,7 +1605,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { j.implementationAndResourcesJar = implementationAndResourcesJar // Enable dex compilation for the APEX variants, unless it is disabled explicitly - if android.DirectlyInAnyApex(ctx, ctx.ModuleName()) && !j.IsForPlatform() { + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + if j.DirectlyInAnyApex() && !apexInfo.IsForPlatform() { if j.dexProperties.Compile_dex == nil { j.dexProperties.Compile_dex = proptools.BoolPtr(true) } @@ -1684,7 +1688,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { j.linter.compileSdkVersion = lintSDKVersionString(j.sdkVersion()) j.linter.javaLanguageLevel = flags.javaVersion.String() j.linter.kotlinLanguageLevel = "1.3" - if j.ApexVariationName() != "" && ctx.Config().UnbundledBuildApps() { + if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() { j.linter.buildModuleReportZip = true } j.linter.lint(ctx) @@ -1946,7 +1950,7 @@ func (j *Library) PermittedPackagesForUpdatableBootJars() []string { func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool { // Store uncompressed (and aligned) any dex files from jars in APEXes. - if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() { + if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() { return true } @@ -1968,6 +1972,11 @@ func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bo } func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + if !apexInfo.IsForPlatform() { + j.hideApexVariantFromMake = true + } + j.checkSdkVersions(ctx) j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary @@ -1982,7 +1991,7 @@ func (j *Library) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Collect the module directory for IDE info in java/jdeps.go. j.modulePaths = append(j.modulePaths, ctx.ModuleDir()) - exclusivelyForApex := android.InAnyApex(ctx.ModuleName()) && !j.IsForPlatform() + exclusivelyForApex := !apexInfo.IsForPlatform() if (Bool(j.properties.Installable) || ctx.Host()) && !exclusivelyForApex { var extraInstallDeps android.Paths if j.InstallMixin != nil { @@ -2574,6 +2583,8 @@ type Import struct { combinedClasspathFile android.Path exportedSdkLibs dexpreopt.LibraryPaths exportAidlIncludeDirs android.Paths + + hideApexVariantFromMake bool } func (j *Import) sdkVersion() sdkSpec { @@ -2629,6 +2640,10 @@ func (j *Import) DepsMutator(ctx android.BottomUpMutatorContext) { } func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { + if !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() { + j.hideApexVariantFromMake = true + } + jars := android.PathsForModuleSrc(ctx, j.properties.Jars) jarName := j.Stem() + ".jar" @@ -2872,6 +2887,8 @@ type DexImport struct { maybeStrippedDexJarFile android.Path dexpreopter + + hideApexVariantFromMake bool } func (j *DexImport) Prebuilt() *android.Prebuilt { @@ -2907,6 +2924,11 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.PropertyErrorf("jars", "exactly one jar must be provided") } + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + if !apexInfo.IsForPlatform() { + j.hideApexVariantFromMake = true + } + j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar") j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter) @@ -2951,7 +2973,7 @@ func (j *DexImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { j.maybeStrippedDexJarFile = dexOutputFile - if j.IsForPlatform() { + if apexInfo.IsForPlatform() { ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"), j.Stem()+".jar", dexOutputFile) } diff --git a/java/lint.go b/java/lint.go index 3a210cc0b..3df582f6e 100644 --- a/java/lint.go +++ b/java/lint.go @@ -451,10 +451,13 @@ func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) { return } - if apex, ok := m.(android.ApexModule); ok && apex.NotAvailableForPlatform() && apex.IsForPlatform() { - // There are stray platform variants of modules in apexes that are not available for - // the platform, and they sometimes can't be built. Don't depend on them. - return + if apex, ok := m.(android.ApexModule); ok && apex.NotAvailableForPlatform() { + apexInfo := ctx.ModuleProvider(m, android.ApexInfoProvider).(android.ApexInfo) + if apexInfo.IsForPlatform() { + // There are stray platform variants of modules in apexes that are not available for + // the platform, and they sometimes can't be built. Don't depend on them. + return + } } if l, ok := m.(lintOutputsIntf); ok { diff --git a/java/sdk_library.go b/java/sdk_library.go index 9caa97a0a..119eb658a 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -1419,22 +1419,14 @@ func PrebuiltJars(ctx android.BaseModuleContext, baseName string, s sdkSpec) and return android.Paths{jarPath.Path()} } -// Get the apex names for module, nil if it is for platform. -func getApexNamesForModule(module android.Module) []string { - if apex, ok := module.(android.ApexModule); ok { - return apex.InApexes() - } - - return nil -} - // Check to see if the other module is within the same set of named APEXes as this module. // // If either this or the other module are on the platform then this will return // false. -func withinSameApexesAs(module android.ApexModule, other android.Module) bool { - names := module.InApexes() - return len(names) > 0 && reflect.DeepEqual(names, getApexNamesForModule(other)) +func withinSameApexesAs(ctx android.BaseModuleContext, other android.Module) bool { + apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) + otherApexInfo := ctx.OtherModuleProvider(other, android.ApexInfoProvider).(android.ApexInfo) + return len(otherApexInfo.InApexes) > 0 && reflect.DeepEqual(apexInfo.InApexes, otherApexInfo.InApexes) } func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths { @@ -1453,7 +1445,7 @@ func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkS // Only allow access to the implementation library in the following condition: // * No sdk_version specified on the referencing module. // * The referencing module is in the same apex as this. - if sdkVersion.kind == sdkPrivate || withinSameApexesAs(module, ctx.Module()) { + if sdkVersion.kind == sdkPrivate || withinSameApexesAs(ctx, module) { if headerJars { return module.HeaderJars() } else { @@ -1970,7 +1962,7 @@ func (module *SdkLibraryImport) sdkJars(ctx android.BaseModuleContext, sdkVersio // For consistency with SdkLibrary make the implementation jar available to libraries that // are within the same APEX. implLibraryModule := module.implLibraryModule - if implLibraryModule != nil && withinSameApexesAs(module, ctx.Module()) { + if implLibraryModule != nil && withinSameApexesAs(ctx, module) { if headerJars { return implLibraryModule.HeaderJars() } else { @@ -2066,6 +2058,8 @@ type sdkLibraryXml struct { outputFilePath android.OutputPath installDirPath android.InstallPath + + hideApexVariantFromMake bool } type sdkLibraryXmlProperties struct { @@ -2123,13 +2117,13 @@ func (module *sdkLibraryXml) ShouldSupportSdkVersion(ctx android.BaseModuleConte } // File path to the runtime implementation library -func (module *sdkLibraryXml) implPath() string { +func (module *sdkLibraryXml) implPath(ctx android.ModuleContext) string { implName := proptools.String(module.properties.Lib_name) - if apexName := module.ApexVariationName(); apexName != "" { + if apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo); !apexInfo.IsForPlatform() { // TODO(b/146468504): ApexVariationName() is only a soong module name, not apex name. // In most cases, this works fine. But when apex_name is set or override_apex is used // this can be wrong. - return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexName, implName) + return fmt.Sprintf("/apex/%s/javalib/%s.jar", apexInfo.ApexVariationName, implName) } partition := "system" if module.SocSpecific() { @@ -2145,8 +2139,10 @@ func (module *sdkLibraryXml) implPath() string { } func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleContext) { + module.hideApexVariantFromMake = !ctx.Provider(android.ApexInfoProvider).(android.ApexInfo).IsForPlatform() + libName := proptools.String(module.properties.Lib_name) - xmlContent := fmt.Sprintf(permissionsTemplate, libName, module.implPath()) + xmlContent := fmt.Sprintf(permissionsTemplate, libName, module.implPath(ctx)) module.outputFilePath = android.PathForModuleOut(ctx, libName+".xml").OutputPath rule := android.NewRuleBuilder() @@ -2160,7 +2156,7 @@ func (module *sdkLibraryXml) GenerateAndroidBuildActions(ctx android.ModuleConte } func (module *sdkLibraryXml) AndroidMkEntries() []android.AndroidMkEntries { - if !module.IsForPlatform() { + if module.hideApexVariantFromMake { return []android.AndroidMkEntries{android.AndroidMkEntries{ Disabled: true, }}