From 1356d8c0f32dfd598e586e1b135445d0c4af68dc Mon Sep 17 00:00:00 2001 From: Paul Duffin Date: Tue, 25 Feb 2020 19:26:33 +0000 Subject: [PATCH] Add CommonOS variant for sdk Adds a CommonOS variant for sdk that depends on the os specific variants and is used to generate a single sdk for multiple OsTypes, e.g. host linux and android. At the minute the member types only support a single OsType but the basic mechanism for managing the CommonOS variant and collating the variants across all of them is there. The only visible effect of this change is that the location of the generated snapshot is changed, it is no longer os specific and instead is in the same location irrespective of which os it is built for. A lot of tests needed to be changed to specify "common_os" as the variant type instead of the specific os type. As that is the same across all tests it is hard coded in CheckSnapshot method. Test: m nothing Bug: 150451422 Change-Id: If36be39b06d6910453649f7c288c2d34f688b2f4 --- android/arch.go | 85 ++++++++++++++++++++++++++++++++++++----- android/config.go | 3 ++ android/module.go | 36 +++++++++++++++++- sdk/cc_sdk_test.go | 23 +++++------ sdk/exports_test.go | 2 +- sdk/java_sdk_test.go | 24 ++++++------ sdk/sdk.go | 35 +++++++++++++++-- sdk/sdk_test.go | 2 +- sdk/testing.go | 5 ++- sdk/update.go | 90 ++++++++++++++++++++++++++++---------------- 10 files changed, 232 insertions(+), 73 deletions(-) diff --git a/android/arch.go b/android/arch.go index 73a490d79..16c9bddcd 100644 --- a/android/arch.go +++ b/android/arch.go @@ -607,6 +607,10 @@ var ( Android = NewOsType("android", Device, false) Fuchsia = NewOsType("fuchsia", Device, false) + // A pseudo OSType for a common os variant, which is OSType agnostic and which + // has dependencies on all the OS variants. + CommonOS = NewOsType("common_os", Generic, false) + osArchTypeMap = map[OsType][]ArchType{ Linux: []ArchType{X86, X86_64}, LinuxBionic: []ArchType{X86_64}, @@ -775,12 +779,64 @@ func osMutator(mctx BottomUpMutatorContext) { osNames[i] = os.String() } - modules := mctx.CreateVariations(osNames...) - for i, m := range modules { - m.(Module).base().commonProperties.CompileOS = moduleOSList[i] - m.(Module).base().setOSProperties(mctx) + createCommonOSVariant := base.commonProperties.CreateCommonOSVariant + if createCommonOSVariant { + // A CommonOS variant was requested so add it to the list of OS's variants to + // create. It needs to be added to the end because it needs to depend on the + // the other variants in the list returned by CreateVariations(...) and inter + // variant dependencies can only be created from a later variant in that list to + // an earlier one. That is because variants are always processed in the order in + // which they are returned from CreateVariations(...). + osNames = append(osNames, CommonOS.Name) + moduleOSList = append(moduleOSList, CommonOS) } + modules := mctx.CreateVariations(osNames...) + for i, m := range modules { + m.base().commonProperties.CompileOS = moduleOSList[i] + m.base().setOSProperties(mctx) + } + + if createCommonOSVariant { + // A CommonOS variant was requested so add dependencies from it (the last one in + // the list) to the OS type specific variants. + last := len(modules) - 1 + commonOSVariant := modules[last] + commonOSVariant.base().commonProperties.CommonOSVariant = true + for _, module := range modules[0:last] { + // Ignore modules that are enabled. Note, this will only avoid adding + // dependencies on OsType variants that are explicitly disabled in their + // properties. The CommonOS variant will still depend on disabled variants + // if they are disabled afterwards, e.g. in archMutator if + if module.Enabled() { + mctx.AddInterVariantDependency(commonOsToOsSpecificVariantTag, commonOSVariant, module) + } + } + } +} + +// Identifies the dependency from CommonOS variant to the os specific variants. +type commonOSTag struct{ blueprint.BaseDependencyTag } + +var commonOsToOsSpecificVariantTag = commonOSTag{} + +// Get the OsType specific variants for the current CommonOS variant. +// +// The returned list will only contain enabled OsType specific variants of the +// module referenced in the supplied context. An empty list is returned if there +// are no enabled variants or the supplied context is not for an CommonOS +// variant. +func GetOsSpecificVariantsOfCommonOSVariant(mctx BaseModuleContext) []Module { + var variants []Module + mctx.VisitDirectDeps(func(m Module) { + if mctx.OtherModuleDependencyTag(m) == commonOsToOsSpecificVariantTag { + if m.Enabled() { + variants = append(variants, m) + } + } + }) + + return variants } // archMutator splits a module into a variant for each Target requested by the module. Target selection @@ -821,6 +877,15 @@ func archMutator(mctx BottomUpMutatorContext) { } os := base.commonProperties.CompileOS + if os == CommonOS { + // Make sure that the target related properties are initialized for the + // CommonOS variant. + addTargetProperties(module, commonTargetMap[os.Name], nil, true) + + // Do not create arch specific variants for the CommonOS variant. + return + } + osTargets := mctx.Config().Targets[os] image := base.commonProperties.ImageVariation // Filter NativeBridge targets unless they are explicitly supported @@ -881,15 +946,17 @@ func archMutator(mctx BottomUpMutatorContext) { modules := mctx.CreateVariations(targetNames...) for i, m := range modules { - m.(Module).base().commonProperties.CompileTarget = targets[i] - m.(Module).base().commonProperties.CompileMultiTargets = multiTargets - if i == 0 { - m.(Module).base().commonProperties.CompilePrimary = true - } + addTargetProperties(m, targets[i], multiTargets, i == 0) m.(Module).base().setArchProperties(mctx) } } +func addTargetProperties(m Module, target Target, multiTargets []Target, primaryTarget bool) { + m.base().commonProperties.CompileTarget = target + m.base().commonProperties.CompileMultiTargets = multiTargets + m.base().commonProperties.CompilePrimary = primaryTarget +} + func decodeMultilib(base *ModuleBase, class OsClass) (multilib, extraMultilib string) { switch class { case Device: diff --git a/android/config.go b/android/config.go index b2bda2a44..9b1297cd8 100644 --- a/android/config.go +++ b/android/config.go @@ -359,6 +359,9 @@ func NewConfig(srcDir, buildDir string) (Config, error) { return Config{}, err } + // Make the CommonOS OsType available for all products. + targets[CommonOS] = []Target{commonTargetMap[CommonOS.Name]} + var archConfig []archConfig if Bool(config.Mega_device) { archConfig = getMegaDeviceConfig() diff --git a/android/module.go b/android/module.go index 1026bdfeb..b6363ea23 100644 --- a/android/module.go +++ b/android/module.go @@ -452,6 +452,22 @@ type commonProperties struct { HostOrDeviceSupported HostOrDeviceSupported `blueprint:"mutated"` ArchSpecific bool `blueprint:"mutated"` + // If set to true then a CommonOS variant will be created which will have dependencies + // on all its OsType specific variants. Used by sdk/module_exports to create a snapshot + // that covers all os and architecture variants. + // + // The OsType specific variants can be retrieved by calling + // GetOsSpecificVariantsOfCommonOSVariant + // + // Set at module initialization time by calling InitCommonOSAndroidMultiTargetsArchModule + CreateCommonOSVariant bool `blueprint:"mutated"` + + // If set to true then this variant is the CommonOS variant that has dependencies on its + // OsType specific variants. + // + // Set by osMutator. + CommonOSVariant bool `blueprint:"mutated"` + SkipInstall bool `blueprint:"mutated"` NamespaceExportedToMake bool `blueprint:"mutated"` @@ -584,6 +600,14 @@ func InitAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defa m.base().commonProperties.UseTargetVariants = false } +// As InitAndroidMultiTargetsArchModule except it creates an additional CommonOS variant that +// has dependencies on all the OsType specific variants. +func InitCommonOSAndroidMultiTargetsArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) { + InitAndroidArchModule(m, hod, defaultMultilib) + m.base().commonProperties.UseTargetVariants = false + m.base().commonProperties.CreateCommonOSVariant = true +} + // A ModuleBase object contains the properties that are common to all Android // modules. It should be included as an anonymous field in every module // struct definition. InitAndroidModule should then be called from the module's @@ -775,6 +799,11 @@ func (m *ModuleBase) ArchSpecific() bool { return m.commonProperties.ArchSpecific } +// True if the current variant is a CommonOS variant, false otherwise. +func (m *ModuleBase) IsCommonOSVariant() bool { + return m.commonProperties.CommonOSVariant +} + func (m *ModuleBase) OsClassSupported() []OsClass { switch m.commonProperties.HostOrDeviceSupported { case HostSupported: @@ -1103,8 +1132,11 @@ func (m *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) blueprintCtx.GetMissingDependencies() // For the final GenerateAndroidBuildActions pass, require that all visited dependencies Soong modules and - // are enabled. - ctx.baseModuleContext.strictVisitDeps = true + // are enabled. Unless the module is a CommonOS variant which may have dependencies on disabled variants + // (because the dependencies are added before the modules are disabled). The + // GetOsSpecificVariantsOfCommonOSVariant(...) method will ensure that the disabled variants are + // ignored. + ctx.baseModuleContext.strictVisitDeps = !m.IsCommonOSVariant() if ctx.config.captureBuild { ctx.ruleParams = make(map[blueprint.Rule]blueprint.RuleParams) diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go index ecb1da0a0..45b548ccb 100644 --- a/sdk/cc_sdk_test.go +++ b/sdk/cc_sdk_test.go @@ -17,6 +17,7 @@ package sdk import ( "testing" + "android/soong/android" "android/soong/cc" ) @@ -54,7 +55,7 @@ func TestSdkIsCompileMultilibBoth(t *testing.T) { arm64Output := result.Module("sdkmember", "android_arm64_armv8-a_shared").(*cc.Module).OutputFile() var inputs []string - buildParams := result.Module("mysdk", "android_common").BuildParamsForTests() + buildParams := result.Module("mysdk", android.CommonOS.Name).BuildParamsForTests() for _, bp := range buildParams { if bp.Input != nil { inputs = append(inputs, bp.Input.String()) @@ -250,7 +251,7 @@ func TestSnapshotWithCcDuplicateHeaders(t *testing.T) { } `) - result.CheckSnapshot("mysdk", "android_common", "", + result.CheckSnapshot("mysdk", "", checkAllCopyRules(` include/Test.h -> include/include/Test.h .intermediates/mynativelib1/android_arm64_armv8-a_shared/mynativelib1.so -> arm64/lib/mynativelib1.so @@ -287,7 +288,7 @@ func TestSnapshotWithCcSharedLibraryCommonProperties(t *testing.T) { } `) - result.CheckSnapshot("mysdk", "android_common", "", + result.CheckSnapshot("mysdk", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -356,7 +357,7 @@ func TestSnapshotWithCcBinary(t *testing.T) { } `) - result.CheckSnapshot("mymodule_exports", "android_common", "", + result.CheckSnapshot("mymodule_exports", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -422,7 +423,7 @@ func TestSnapshotWithCcSharedLibrary(t *testing.T) { } `) - result.CheckSnapshot("mysdk", "android_common", "", + result.CheckSnapshot("mysdk", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -510,7 +511,7 @@ func TestHostSnapshotWithCcSharedLibrary(t *testing.T) { } `) - result.CheckSnapshot("mysdk", "linux_glibc_common", "", + result.CheckSnapshot("mysdk", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -597,7 +598,7 @@ func TestSnapshotWithCcStaticLibrary(t *testing.T) { } `) - result.CheckSnapshot("myexports", "android_common", "", + result.CheckSnapshot("myexports", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -685,7 +686,7 @@ func TestHostSnapshotWithCcStaticLibrary(t *testing.T) { } `) - result.CheckSnapshot("myexports", "linux_glibc_common", "", + result.CheckSnapshot("myexports", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -784,7 +785,7 @@ func TestHostSnapshotWithMultiLib64(t *testing.T) { } `) - result.CheckSnapshot("myexports", "linux_glibc_common", "", + result.CheckSnapshot("myexports", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -856,7 +857,7 @@ func TestSnapshotWithCcHeadersLibrary(t *testing.T) { } `) - result.CheckSnapshot("mysdk", "android_common", "", + result.CheckSnapshot("mysdk", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -909,7 +910,7 @@ func TestHostSnapshotWithCcHeadersLibrary(t *testing.T) { } `) - result.CheckSnapshot("mysdk", "linux_glibc_common", "", + result.CheckSnapshot("mysdk", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. diff --git a/sdk/exports_test.go b/sdk/exports_test.go index b905d719a..20e25212c 100644 --- a/sdk/exports_test.go +++ b/sdk/exports_test.go @@ -42,7 +42,7 @@ func TestModuleExportsSnapshot(t *testing.T) { "package/Android.bp": []byte(packageBp), }) - result.CheckSnapshot("myexports", "android_common", "package", + result.CheckSnapshot("myexports", "package", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index 0737e5e2f..9046eeca0 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -141,7 +141,7 @@ func TestSnapshotWithJavaHeaderLibrary(t *testing.T) { } `) - result.CheckSnapshot("mysdk", "android_common", "", + result.CheckSnapshot("mysdk", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -196,7 +196,7 @@ func TestHostSnapshotWithJavaHeaderLibrary(t *testing.T) { } `) - result.CheckSnapshot("mysdk", "linux_glibc_common", "", + result.CheckSnapshot("mysdk", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -250,7 +250,7 @@ func TestSnapshotWithJavaImplLibrary(t *testing.T) { } `) - result.CheckSnapshot("myexports", "android_common", "", + result.CheckSnapshot("myexports", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -305,7 +305,7 @@ func TestHostSnapshotWithJavaImplLibrary(t *testing.T) { } `) - result.CheckSnapshot("myexports", "linux_glibc_common", "", + result.CheckSnapshot("myexports", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -356,7 +356,7 @@ func TestSnapshotWithJavaTest(t *testing.T) { } `) - result.CheckSnapshot("myexports", "android_common", "", + result.CheckSnapshot("myexports", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -409,7 +409,7 @@ func TestHostSnapshotWithJavaTest(t *testing.T) { } `) - result.CheckSnapshot("myexports", "linux_glibc_common", "", + result.CheckSnapshot("myexports", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -503,7 +503,7 @@ func TestSnapshotWithDroidstubs(t *testing.T) { } `) - result.CheckSnapshot("myexports", "android_common", "", + result.CheckSnapshot("myexports", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -526,7 +526,7 @@ module_exports_snapshot { `), checkAllCopyRules(""), - checkMergeZip(".intermediates/myexports/android_common/tmp/java/myjavaapistubs_stubs_sources.zip"), + checkMergeZip(".intermediates/myexports/common_os/tmp/java/myjavaapistubs_stubs_sources.zip"), ) } @@ -552,7 +552,7 @@ func TestHostSnapshotWithDroidstubs(t *testing.T) { } `) - result.CheckSnapshot("myexports", "linux_glibc_common", "", + result.CheckSnapshot("myexports", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -580,7 +580,7 @@ module_exports_snapshot { } `), checkAllCopyRules(""), - checkMergeZip(".intermediates/myexports/linux_glibc_common/tmp/java/myjavaapistubs_stubs_sources.zip"), + checkMergeZip(".intermediates/myexports/common_os/tmp/java/myjavaapistubs_stubs_sources.zip"), ) } @@ -612,7 +612,7 @@ func TestSnapshotWithJavaSystemModules(t *testing.T) { } `) - result.CheckSnapshot("mysdk", "android_common", "", + result.CheckSnapshot("mysdk", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. @@ -702,7 +702,7 @@ func TestHostSnapshotWithJavaSystemModules(t *testing.T) { } `) - result.CheckSnapshot("mysdk", "linux_glibc_common", "", + result.CheckSnapshot("mysdk", "", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. diff --git a/sdk/sdk.go b/sdk/sdk.go index c194ac1f8..14e44bfb4 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -53,6 +53,13 @@ type sdk struct { // The set of exported members. exportedMembers map[string]struct{} + // Information about the OsType specific member variants associated with this variant. + // + // Set by OsType specific variants when their GenerateAndroidBuildActions is invoked + // and used by the CommonOS variant when its GenerateAndroidBuildActions is invoked, which + // is guaranteed to occur afterwards. + memberRefs []sdkMemberRef + properties sdkProperties snapshotFile android.OptionalPath @@ -201,7 +208,7 @@ func newSdkModule(moduleExports bool) *sdk { // properties for the member type specific list properties. s.dynamicMemberTypeListProperties = s.dynamicSdkMemberTypes.createMemberListProperties() s.AddProperties(&s.properties, s.dynamicMemberTypeListProperties) - android.InitAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon) + android.InitCommonOSAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon) android.InitDefaultableModule(s) android.AddLoadHook(s, func(ctx android.LoadHookContext) { type props struct { @@ -252,10 +259,29 @@ func (s *sdk) snapshot() bool { } func (s *sdk) GenerateAndroidBuildActions(ctx android.ModuleContext) { - if !s.snapshot() { + if s.snapshot() { // We don't need to create a snapshot out of sdk_snapshot. // That doesn't make sense. We need a snapshot to create sdk_snapshot. - s.snapshotFile = android.OptionalPathForPath(s.buildSnapshot(ctx)) + return + } + + // This method is guaranteed to be called on OsType specific variants before it is called + // on their corresponding CommonOS variant. + if !s.IsCommonOSVariant() { + // Collect the OsType specific members are add them to the OsType specific variant. + s.memberRefs = s.collectMembers(ctx) + } else { + // Get the OsType specific variants on which the CommonOS depends. + osSpecificVariants := android.GetOsSpecificVariantsOfCommonOSVariant(ctx) + var sdkVariants []*sdk + for _, m := range osSpecificVariants { + if sdkVariant, ok := m.(*sdk); ok { + sdkVariants = append(sdkVariants, sdkVariant) + } + } + + // Generate the snapshot from the member info. + s.snapshotFile = android.OptionalPathForPath(s.buildSnapshot(ctx, sdkVariants)) } } @@ -320,7 +346,8 @@ func (t sdkMemberVersionedDepTag) ExcludeFromVisibilityEnforcement() {} // Step 1: create dependencies from an SDK module to its members. func memberMutator(mctx android.BottomUpMutatorContext) { if s, ok := mctx.Module().(*sdk); ok { - if s.Enabled() { + // Add dependencies from enabled and non CommonOS variants to the sdk member variants. + if s.Enabled() && !s.IsCommonOSVariant() { for _, memberListProperty := range s.memberListProperties() { names := memberListProperty.getter(s.dynamicMemberTypeListProperties) if len(names) > 0 { diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go index 934bdae01..d06401a0e 100644 --- a/sdk/sdk_test.go +++ b/sdk/sdk_test.go @@ -145,7 +145,7 @@ func TestSnapshotVisibility(t *testing.T) { "package/Android.bp": []byte(packageBp), }) - result.CheckSnapshot("mysdk", "android_common", "package", + result.CheckSnapshot("mysdk", "package", checkAndroidBpContents(` // This is auto-generated. DO NOT EDIT. diff --git a/sdk/testing.go b/sdk/testing.go index 7352c7444..be882d436 100644 --- a/sdk/testing.go +++ b/sdk/testing.go @@ -246,9 +246,12 @@ func (r *testSdkResult) ModuleForTests(name string, variant string) android.Test // Takes a list of functions which check different facets of the snapshot build rules. // Allows each test to customize what is checked without duplicating lots of code // or proliferating check methods of different flavors. -func (r *testSdkResult) CheckSnapshot(name string, variant string, dir string, checkers ...snapshotBuildInfoChecker) { +func (r *testSdkResult) CheckSnapshot(name string, dir string, checkers ...snapshotBuildInfoChecker) { r.t.Helper() + // The sdk CommonOS variant is always responsible for generating the snapshot. + variant := android.CommonOS.Name + sdk := r.Module(name, variant).(*sdk) snapshotBuildInfo := r.getSdkSnapshotBuildInfo(sdk) diff --git a/sdk/update.go b/sdk/update.go index d211e80d7..087b8bc64 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -104,18 +104,9 @@ func (gf *generatedFile) build(pctx android.PackageContext, ctx android.BuilderC // Collect all the members. // -// The members are first grouped by type and then grouped by name. The order of -// the types is the order they are referenced in android.SdkMemberTypesRegistry. -// The names are in the order in which the dependencies were added. -// -// Returns the members as well as the multilib setting to use. -func (s *sdk) collectMembers(ctx android.ModuleContext) ([]*sdkMember, string) { - byType := make(map[android.SdkMemberType][]*sdkMember) - byName := make(map[string]*sdkMember) - - lib32 := false // True if any of the members have 32 bit version. - lib64 := false // True if any of the members have 64 bit version. - +// Returns a list containing type (extracted from the dependency tag) and the variant. +func (s *sdk) collectMembers(ctx android.ModuleContext) []sdkMemberRef { + var memberRefs []sdkMemberRef ctx.WalkDeps(func(child android.Module, parent android.Module) bool { tag := ctx.OtherModuleDependencyTag(child) if memberTag, ok := tag.(android.SdkMemberTypeDependencyTag); ok { @@ -126,24 +117,7 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) ([]*sdkMember, string) { ctx.ModuleErrorf("module %q is not valid in property %s", ctx.OtherModuleName(child), memberType.SdkPropertyName()) } - name := ctx.OtherModuleName(child) - member := byName[name] - if member == nil { - member = &sdkMember{memberType: memberType, name: name} - byName[name] = member - byType[memberType] = append(byType[memberType], member) - } - - multilib := child.Target().Arch.ArchType.Multilib - if multilib == "lib32" { - lib32 = true - } else if multilib == "lib64" { - lib64 = true - } - - // Only append new variants to the list. This is needed because a member can be both - // exported by the sdk and also be a transitive sdk member. - member.variants = appendUniqueVariants(member.variants, child.(android.SdkAware)) + memberRefs = append(memberRefs, sdkMemberRef{memberType, child.(android.SdkAware)}) // If the member type supports transitive sdk members then recurse down into // its dependencies, otherwise exit traversal. @@ -153,6 +127,47 @@ func (s *sdk) collectMembers(ctx android.ModuleContext) ([]*sdkMember, string) { return false }) + return memberRefs +} + +// Organize the members. +// +// The members are first grouped by type and then grouped by name. The order of +// the types is the order they are referenced in android.SdkMemberTypesRegistry. +// The names are in the order in which the dependencies were added. +// +// Returns the members as well as the multilib setting to use. +func (s *sdk) organizeMembers(ctx android.ModuleContext, memberRefs []sdkMemberRef) ([]*sdkMember, string) { + byType := make(map[android.SdkMemberType][]*sdkMember) + byName := make(map[string]*sdkMember) + + lib32 := false // True if any of the members have 32 bit version. + lib64 := false // True if any of the members have 64 bit version. + + for _, memberRef := range memberRefs { + memberType := memberRef.memberType + variant := memberRef.variant + + name := ctx.OtherModuleName(variant) + member := byName[name] + if member == nil { + member = &sdkMember{memberType: memberType, name: name} + byName[name] = member + byType[memberType] = append(byType[memberType], member) + } + + multilib := variant.Target().Arch.ArchType.Multilib + if multilib == "lib32" { + lib32 = true + } else if multilib == "lib64" { + lib64 = true + } + + // Only append new variants to the list. This is needed because a member can be both + // exported by the sdk and also be a transitive sdk member. + member.variants = appendUniqueVariants(member.variants, variant) + } + var members []*sdkMember for _, memberListProperty := range s.memberListProperties() { membersOfType := byType[memberListProperty.memberType] @@ -207,7 +222,13 @@ func versionedSdkMemberName(ctx android.ModuleContext, memberName string, versio // buildSnapshot is the main function in this source file. It creates rules to copy // the contents (header files, stub libraries, etc) into the zip file. -func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath { +func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) android.OutputPath { + + var memberRefs []sdkMemberRef + for _, sdkVariant := range sdkVariants { + memberRefs = append(memberRefs, sdkVariant.memberRefs...) + } + snapshotDir := android.PathForModuleOut(ctx, "snapshot") bp := newGeneratedFile(ctx, "snapshot", "Android.bp") @@ -228,7 +249,7 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath { } s.builderForTests = builder - members, multilib := s.collectMembers(ctx) + members, multilib := s.organizeMembers(ctx, memberRefs) for _, member := range members { member.memberType.BuildSnapshot(ctx, builder, member) } @@ -592,6 +613,11 @@ func (s *snapshotBuilder) unversionedSdkMemberNames(members []string) []string { return references } +type sdkMemberRef struct { + memberType android.SdkMemberType + variant android.SdkAware +} + var _ android.SdkMember = (*sdkMember)(nil) type sdkMember struct {