diff --git a/android/sdk.go b/android/sdk.go index ad67bbe6f..32d992199 100644 --- a/android/sdk.go +++ b/android/sdk.go @@ -186,9 +186,33 @@ type SnapshotBuilder interface { // is correctly output for both versioned and unversioned prebuilts in the // snapshot. // + // "required: true" means that the property must only contain references + // to other members of the sdk. Passing a reference to a module that is not a + // member of the sdk will result in a build error. + // + // "required: false" means that the property can contain references to modules + // that are either members or not members of the sdk. If a reference is to a + // module that is a non member then the reference is left unchanged, i.e. it + // is not transformed as references to members are. + // + // The handling of the member names is dependent on whether it is an internal or + // exported member. An exported member is one whose name is specified in one of + // the member type specific properties. An internal member is one that is added + // due to being a part of an exported (or other internal) member and is not itself + // an exported member. + // + // Member names are handled as follows: + // * When creating the unversioned form of the module the name is left unchecked + // unless the member is internal in which case it is transformed into an sdk + // specific name, i.e. by prefixing with the sdk name. + // + // * When creating the versioned form of the module the name is transformed into + // a versioned sdk specific name, i.e. by prefixing with the sdk name and + // suffixing with the version. + // // e.g. - // bpPropertySet.AddPropertyWithTag("libs", []string{"member1", "member2"}, builder.SdkMemberReferencePropertyTag()) - SdkMemberReferencePropertyTag() BpPropertyTag + // bpPropertySet.AddPropertyWithTag("libs", []string{"member1", "member2"}, builder.SdkMemberReferencePropertyTag(true)) + SdkMemberReferencePropertyTag(required bool) BpPropertyTag } type BpPropertyTag interface{} diff --git a/cc/binary_sdk_member.go b/cc/binary_sdk_member.go index fc9b89e75..2778ebd11 100644 --- a/cc/binary_sdk_member.go +++ b/cc/binary_sdk_member.go @@ -95,6 +95,16 @@ type nativeBinaryInfoProperties struct { // outputFile is not exported as it is always arch specific. outputFile android.Path + + // The set of shared libraries + // + // This field is exported as its contents may not be arch specific. + SharedLibs []string + + // The set of system shared libraries + // + // This field is exported as its contents may not be arch specific. + SystemSharedLibs []string } func (p *nativeBinaryInfoProperties) PopulateFromVariant(variant android.SdkAware) { @@ -102,6 +112,14 @@ func (p *nativeBinaryInfoProperties) PopulateFromVariant(variant android.SdkAwar p.archType = ccModule.Target().Arch.ArchType.String() p.outputFile = ccModule.OutputFile().Path() + + if ccModule.linker != nil { + specifiedDeps := specifiedDeps{} + specifiedDeps = ccModule.linker.linkerSpecifiedDeps(specifiedDeps) + + p.SharedLibs = specifiedDeps.sharedLibs + p.SystemSharedLibs = specifiedDeps.systemSharedLibs + } } func (p *nativeBinaryInfoProperties) AddToPropertySet(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, propertySet android.BpPropertySet) { @@ -114,4 +132,12 @@ func (p *nativeBinaryInfoProperties) AddToPropertySet(sdkModuleContext android.M builder.CopyToSnapshot(p.outputFile, nativeBinaryPathFor(*p)) } + + if len(p.SharedLibs) > 0 { + propertySet.AddPropertyWithTag("shared_libs", p.SharedLibs, builder.SdkMemberReferencePropertyTag(false)) + } + + if len(p.SystemSharedLibs) > 0 { + propertySet.AddPropertyWithTag("system_shared_libs", p.SystemSharedLibs, builder.SdkMemberReferencePropertyTag(false)) + } } diff --git a/cc/cc.go b/cc/cc.go index 778531ad5..26fd425a6 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -370,6 +370,15 @@ type linker interface { nativeCoverage() bool coverageOutputFilePath() android.OptionalPath + + // Get the deps that have been explicitly specified in the properties. + // Only updates the + linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps +} + +type specifiedDeps struct { + sharedLibs []string + systemSharedLibs []string } type installer interface { diff --git a/cc/library.go b/cc/library.go index 7a406bfe0..8d2b19dca 100644 --- a/cc/library.go +++ b/cc/library.go @@ -817,6 +817,23 @@ func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps { return deps } +func (library *libraryDecorator) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps { + specifiedDeps = library.baseLinker.linkerSpecifiedDeps(specifiedDeps) + var properties StaticOrSharedProperties + if library.static() { + properties = library.StaticProperties.Static + } else if library.shared() { + properties = library.SharedProperties.Shared + } + + specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, properties.Shared_libs...) + specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, properties.System_shared_libs...) + + specifiedDeps.sharedLibs = android.FirstUniqueStrings(specifiedDeps.sharedLibs) + specifiedDeps.systemSharedLibs = android.FirstUniqueStrings(specifiedDeps.systemSharedLibs) + return specifiedDeps +} + func (library *libraryDecorator) linkStatic(ctx ModuleContext, flags Flags, deps PathDeps, objs Objects) android.Path { diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go index 656df6969..f1b097561 100644 --- a/cc/library_sdk_member.go +++ b/cc/library_sdk_member.go @@ -19,6 +19,7 @@ import ( "android/soong/android" "github.com/google/blueprint" + "github.com/google/blueprint/proptools" ) // This file contains support for using cc library modules within an sdk. @@ -108,8 +109,11 @@ func (mt *librarySdkMemberType) AddPrebuiltModule(sdkModuleContext android.Modul } func (mt *librarySdkMemberType) FinalizeModule(sdkModuleContext android.ModuleContext, builder android.SnapshotBuilder, member android.SdkMember, bpModule android.BpModule) { - bpModule.AddProperty("stl", "none") - bpModule.AddProperty("system_shared_libs", []string{}) + ccModule := (member.Variants()[0]).(*Module) + stl := ccModule.stl.Properties.Stl + if stl != nil { + bpModule.AddProperty("stl", proptools.String(stl)) + } } func (mt *librarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { @@ -193,6 +197,14 @@ func addPossiblyArchSpecificProperties(sdkModuleContext android.ModuleContext, b outputProperties.AddProperty("srcs", []string{nativeLibraryPath}) } + if len(libInfo.SharedLibs) > 0 { + outputProperties.AddPropertyWithTag("shared_libs", libInfo.SharedLibs, builder.SdkMemberReferencePropertyTag(false)) + } + + if len(libInfo.SystemSharedLibs) > 0 { + outputProperties.AddPropertyWithTag("system_shared_libs", libInfo.SystemSharedLibs, builder.SdkMemberReferencePropertyTag(false)) + } + // Map from property name to the include dirs to add to the prebuilt module in the snapshot. includeDirs := make(map[string][]string) @@ -299,6 +311,16 @@ type nativeLibInfoProperties struct { // This field is exported as its contents may not be arch specific. ExportedFlags []string + // The set of shared libraries + // + // This field is exported as its contents may not be arch specific. + SharedLibs []string + + // The set of system shared libraries + // + // This field is exported as its contents may not be arch specific. + SystemSharedLibs []string + // outputFile is not exported as it is always arch specific. outputFile android.Path } @@ -323,6 +345,13 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(variant android.SdkAware) p.exportedGeneratedIncludeDirs = exportedGeneratedIncludeDirs p.ExportedSystemIncludeDirs = ccModule.ExportedSystemIncludeDirs() p.ExportedFlags = ccModule.ExportedFlags() + if ccModule.linker != nil { + specifiedDeps := specifiedDeps{} + specifiedDeps = ccModule.linker.linkerSpecifiedDeps(specifiedDeps) + + p.SharedLibs = specifiedDeps.sharedLibs + p.SystemSharedLibs = specifiedDeps.systemSharedLibs + } p.exportedGeneratedHeaders = ccModule.ExportedGeneratedHeaders() } diff --git a/cc/linker.go b/cc/linker.go index a7b621a91..aa2d0ab24 100644 --- a/cc/linker.go +++ b/cc/linker.go @@ -490,6 +490,12 @@ func (linker *baseLinker) link(ctx ModuleContext, panic(fmt.Errorf("baseLinker doesn't know how to link")) } +func (linker *baseLinker) linkerSpecifiedDeps(specifiedDeps specifiedDeps) specifiedDeps { + specifiedDeps.sharedLibs = append(specifiedDeps.sharedLibs, linker.Properties.Shared_libs...) + specifiedDeps.systemSharedLibs = append(specifiedDeps.systemSharedLibs, linker.Properties.System_shared_libs...) + return specifiedDeps +} + // Injecting version symbols // Some host modules want a version number, but we don't want to rebuild it every time. Optionally add a step // after linking that injects a constant placeholder with the current version number. diff --git a/java/system_modules.go b/java/system_modules.go index 47de6e327..40031cb05 100644 --- a/java/system_modules.go +++ b/java/system_modules.go @@ -255,5 +255,5 @@ func (mt *systemModulesSdkMemberType) BuildSnapshot(sdkModuleContext android.Mod pbm := builder.AddPrebuiltModule(member, "java_system_modules_import") // Add the references to the libraries that form the system module. - pbm.AddPropertyWithTag("libs", systemModule.properties.Libs, builder.SdkMemberReferencePropertyTag()) + pbm.AddPropertyWithTag("libs", systemModule.properties.Libs, builder.SdkMemberReferencePropertyTag(true)) } diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go index 2b0fd3c93..0f84c4ce9 100644 --- a/sdk/cc_sdk_test.go +++ b/sdk/cc_sdk_test.go @@ -309,7 +309,6 @@ cc_prebuilt_library_shared { }, }, stl: "none", - system_shared_libs: [], } cc_prebuilt_library_shared { @@ -326,7 +325,6 @@ cc_prebuilt_library_shared { }, }, stl: "none", - system_shared_libs: [], } sdk_snapshot { @@ -555,7 +553,6 @@ cc_prebuilt_library_shared { }, }, stl: "none", - system_shared_libs: [], } cc_prebuilt_library_shared { @@ -577,7 +574,6 @@ cc_prebuilt_library_shared { }, }, stl: "none", - system_shared_libs: [], } sdk_snapshot { @@ -599,6 +595,189 @@ include/Test.h -> include/include/Test.h ) } +func TestSnapshotWithCcSharedLibrarySharedLibs(t *testing.T) { + result := testSdkWithCc(t, ` + sdk { + name: "mysdk", + native_shared_libs: [ + "mynativelib", + "myothernativelib", + "mysystemnativelib", + ], + } + + cc_library { + name: "mysystemnativelib", + srcs: [ + "Test.cpp", + ], + system_shared_libs: [], + stl: "none", + } + + cc_library_shared { + name: "myothernativelib", + srcs: [ + "Test.cpp", + ], + system_shared_libs: [ + // A reference to a library that is not an sdk member. Uses libm as that + // is in the default set of modules available to this test and so is available + // both here and also when the generated Android.bp file is tested in + // CheckSnapshot(). This ensures that the system_shared_libs property correctly + // handles references to modules that are not sdk members. + "libm", + ], + stl: "none", + } + + cc_library { + name: "mynativelib", + srcs: [ + "Test.cpp", + ], + shared_libs: [ + // A reference to another sdk member. + "myothernativelib", + ], + target: { + android: { + shared: { + shared_libs: [ + // A reference to a library that is not an sdk member. The libc library + // is used here to check that the shared_libs property is handled correctly + // in a similar way to how libm is used to check system_shared_libs above. + "libc", + ], + }, + }, + }, + system_shared_libs: [], + stl: "none", + } + `) + + result.CheckSnapshot("mysdk", "", + checkAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +cc_prebuilt_library_shared { + name: "mysdk_mynativelib@current", + sdk_member_name: "mynativelib", + installable: false, + shared_libs: [ + "mysdk_myothernativelib@current", + "libc", + ], + arch: { + arm64: { + srcs: ["arm64/lib/mynativelib.so"], + }, + arm: { + srcs: ["arm/lib/mynativelib.so"], + }, + }, + stl: "none", +} + +cc_prebuilt_library_shared { + name: "mynativelib", + prefer: false, + shared_libs: [ + "myothernativelib", + "libc", + ], + arch: { + arm64: { + srcs: ["arm64/lib/mynativelib.so"], + }, + arm: { + srcs: ["arm/lib/mynativelib.so"], + }, + }, + stl: "none", +} + +cc_prebuilt_library_shared { + name: "mysdk_myothernativelib@current", + sdk_member_name: "myothernativelib", + installable: false, + system_shared_libs: ["libm"], + arch: { + arm64: { + srcs: ["arm64/lib/myothernativelib.so"], + }, + arm: { + srcs: ["arm/lib/myothernativelib.so"], + }, + }, + stl: "none", +} + +cc_prebuilt_library_shared { + name: "myothernativelib", + prefer: false, + system_shared_libs: ["libm"], + arch: { + arm64: { + srcs: ["arm64/lib/myothernativelib.so"], + }, + arm: { + srcs: ["arm/lib/myothernativelib.so"], + }, + }, + stl: "none", +} + +cc_prebuilt_library_shared { + name: "mysdk_mysystemnativelib@current", + sdk_member_name: "mysystemnativelib", + installable: false, + arch: { + arm64: { + srcs: ["arm64/lib/mysystemnativelib.so"], + }, + arm: { + srcs: ["arm/lib/mysystemnativelib.so"], + }, + }, + stl: "none", +} + +cc_prebuilt_library_shared { + name: "mysystemnativelib", + prefer: false, + arch: { + arm64: { + srcs: ["arm64/lib/mysystemnativelib.so"], + }, + arm: { + srcs: ["arm/lib/mysystemnativelib.so"], + }, + }, + stl: "none", +} + +sdk_snapshot { + name: "mysdk@current", + native_shared_libs: [ + "mysdk_mynativelib@current", + "mysdk_myothernativelib@current", + "mysdk_mysystemnativelib@current", + ], +} +`), + checkAllCopyRules(` +.intermediates/mynativelib/android_arm64_armv8-a_shared/mynativelib.so -> arm64/lib/mynativelib.so +.intermediates/mynativelib/android_arm_armv7-a-neon_shared/mynativelib.so -> arm/lib/mynativelib.so +.intermediates/myothernativelib/android_arm64_armv8-a_shared/myothernativelib.so -> arm64/lib/myothernativelib.so +.intermediates/myothernativelib/android_arm_armv7-a-neon_shared/myothernativelib.so -> arm/lib/myothernativelib.so +.intermediates/mysystemnativelib/android_arm64_armv8-a_shared/mysystemnativelib.so -> arm64/lib/mysystemnativelib.so +.intermediates/mysystemnativelib/android_arm_armv7-a-neon_shared/mysystemnativelib.so -> arm/lib/mysystemnativelib.so +`), + ) +} + func TestHostSnapshotWithCcSharedLibrary(t *testing.T) { // b/145598135 - Generating host snapshots for anything other than linux is not supported. SkipIfNotLinux(t) @@ -652,7 +831,6 @@ cc_prebuilt_library_shared { }, }, stl: "none", - system_shared_libs: [], } cc_prebuilt_library_shared { @@ -673,7 +851,6 @@ cc_prebuilt_library_shared { }, }, stl: "none", - system_shared_libs: [], } sdk_snapshot { @@ -753,7 +930,6 @@ cc_prebuilt_library_shared { }, }, stl: "none", - system_shared_libs: [], } cc_prebuilt_library_shared { @@ -773,7 +949,6 @@ cc_prebuilt_library_shared { }, }, stl: "none", - system_shared_libs: [], } sdk_snapshot { @@ -833,7 +1008,6 @@ cc_prebuilt_library_static { }, }, stl: "none", - system_shared_libs: [], } cc_prebuilt_library_static { @@ -851,7 +1025,6 @@ cc_prebuilt_library_static { }, }, stl: "none", - system_shared_libs: [], } module_exports_snapshot { @@ -924,7 +1097,6 @@ cc_prebuilt_library_static { }, }, stl: "none", - system_shared_libs: [], } cc_prebuilt_library_static { @@ -944,7 +1116,6 @@ cc_prebuilt_library_static { }, }, stl: "none", - system_shared_libs: [], } module_exports_snapshot { @@ -1020,7 +1191,6 @@ cc_prebuilt_library_static { }, }, stl: "none", - system_shared_libs: [], } cc_prebuilt_library_static { @@ -1036,7 +1206,6 @@ cc_prebuilt_library_static { }, }, stl: "none", - system_shared_libs: [], } module_exports_snapshot { @@ -1084,7 +1253,6 @@ cc_prebuilt_library_headers { sdk_member_name: "mynativeheaders", export_include_dirs: ["include/include"], stl: "none", - system_shared_libs: [], } cc_prebuilt_library_headers { @@ -1092,7 +1260,6 @@ cc_prebuilt_library_headers { prefer: false, export_include_dirs: ["include/include"], stl: "none", - system_shared_libs: [], } sdk_snapshot { @@ -1139,7 +1306,6 @@ cc_prebuilt_library_headers { host_supported: true, export_include_dirs: ["include/include"], stl: "none", - system_shared_libs: [], } cc_prebuilt_library_headers { @@ -1149,7 +1315,6 @@ cc_prebuilt_library_headers { host_supported: true, export_include_dirs: ["include/include"], stl: "none", - system_shared_libs: [], } sdk_snapshot { @@ -1211,7 +1376,6 @@ cc_prebuilt_library_headers { }, }, stl: "none", - system_shared_libs: [], } cc_prebuilt_library_headers { @@ -1228,7 +1392,6 @@ cc_prebuilt_library_headers { }, }, stl: "none", - system_shared_libs: [], } sdk_snapshot { diff --git a/sdk/sdk.go b/sdk/sdk.go index 8b9d5bc80..984ed7a1d 100644 --- a/sdk/sdk.go +++ b/sdk/sdk.go @@ -50,9 +50,6 @@ type sdk struct { // list properties, e.g. java_libs. dynamicMemberTypeListProperties interface{} - // 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 @@ -233,26 +230,19 @@ func (s *sdk) memberListProperties() []*sdkMemberListProperty { } func (s *sdk) getExportedMembers() map[string]struct{} { - if s.exportedMembers == nil { - // Collect all the exported members. - s.exportedMembers = make(map[string]struct{}) + // Collect all the exported members. + exportedMembers := make(map[string]struct{}) - for _, memberListProperty := range s.memberListProperties() { - names := memberListProperty.getter(s.dynamicMemberTypeListProperties) + for _, memberListProperty := range s.memberListProperties() { + names := memberListProperty.getter(s.dynamicMemberTypeListProperties) - // Every member specified explicitly in the properties is exported by the sdk. - for _, name := range names { - s.exportedMembers[name] = struct{}{} - } + // Every member specified explicitly in the properties is exported by the sdk. + for _, name := range names { + exportedMembers[name] = struct{}{} } } - return s.exportedMembers -} - -func (s *sdk) isInternalMember(memberName string) bool { - _, ok := s.getExportedMembers()[memberName] - return !ok + return exportedMembers } func (s *sdk) snapshot() bool { diff --git a/sdk/update.go b/sdk/update.go index 54d4c7925..a95d06a6f 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -226,17 +226,23 @@ func versionedSdkMemberName(ctx android.ModuleContext, memberName string, versio // the contents (header files, stub libraries, etc) into the zip file. func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) android.OutputPath { - exportedMembers := make(map[string]struct{}) + allMembersByName := make(map[string]struct{}) + exportedMembersByName := make(map[string]struct{}) var memberRefs []sdkMemberRef for _, sdkVariant := range sdkVariants { memberRefs = append(memberRefs, sdkVariant.memberRefs...) + // Record the names of all the members, both explicitly specified and implicitly + // included. + for _, memberRef := range sdkVariant.memberRefs { + allMembersByName[memberRef.variant.Name()] = struct{}{} + } + // Merge the exported member sets from all sdk variants. for key, _ := range sdkVariant.getExportedMembers() { - exportedMembers[key] = struct{}{} + exportedMembersByName[key] = struct{}{} } } - s.exportedMembers = exportedMembers snapshotDir := android.PathForModuleOut(ctx, "snapshot") @@ -247,14 +253,16 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro } builder := &snapshotBuilder{ - ctx: ctx, - sdk: s, - version: "current", - snapshotDir: snapshotDir.OutputPath, - copies: make(map[string]string), - filesToZip: []android.Path{bp.path}, - bpFile: bpFile, - prebuiltModules: make(map[string]*bpModule), + ctx: ctx, + sdk: s, + version: "current", + snapshotDir: snapshotDir.OutputPath, + copies: make(map[string]string), + filesToZip: []android.Path{bp.path}, + bpFile: bpFile, + prebuiltModules: make(map[string]*bpModule), + allMembersByName: allMembersByName, + exportedMembersByName: exportedMembersByName, } s.builderForTests = builder @@ -402,7 +410,7 @@ func (s *sdk) addMemberPropertiesToPropertySet(builder *snapshotBuilder, propert for _, memberListProperty := range s.memberListProperties() { names := memberListProperty.getter(dynamicMemberTypeListProperties) if len(names) > 0 { - propertySet.AddProperty(memberListProperty.propertyName(), builder.versionedSdkMemberNames(names)) + propertySet.AddProperty(memberListProperty.propertyName(), builder.versionedSdkMemberNames(names, false)) } } } @@ -415,7 +423,13 @@ type propertyTag struct { // // This will cause the references to be rewritten to a versioned reference in the version // specific instance of a snapshot module. -var sdkMemberReferencePropertyTag = propertyTag{"sdkMemberReferencePropertyTag"} +var requiredSdkMemberReferencePropertyTag = propertyTag{"requiredSdkMemberReferencePropertyTag"} + +// A BpPropertyTag to add to a property that contains references to other sdk members. +// +// This will cause the references to be rewritten to a versioned reference in the version +// specific instance of a snapshot module. +var optionalSdkMemberReferencePropertyTag = propertyTag{"optionalSdkMemberReferencePropertyTag"} // A BpPropertyTag that indicates the property should only be present in the versioned // module. @@ -433,14 +447,15 @@ func (t unversionedToVersionedTransformation) transformModule(module *bpModule) // Use a versioned name for the module but remember the original name for the // snapshot. name := module.getValue("name").(string) - module.setProperty("name", t.builder.versionedSdkMemberName(name)) + module.setProperty("name", t.builder.versionedSdkMemberName(name, true)) module.insertAfter("name", "sdk_member_name", name) return module } func (t unversionedToVersionedTransformation) transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) { - if tag == sdkMemberReferencePropertyTag { - return t.builder.versionedSdkMemberNames(value.([]string)), tag + if tag == requiredSdkMemberReferencePropertyTag || tag == optionalSdkMemberReferencePropertyTag { + required := tag == requiredSdkMemberReferencePropertyTag + return t.builder.versionedSdkMemberNames(value.([]string), required), tag } else { return value, tag } @@ -454,7 +469,7 @@ type unversionedTransformation struct { func (t unversionedTransformation) transformModule(module *bpModule) *bpModule { // If the module is an internal member then use a unique name for it. name := module.getValue("name").(string) - module.setProperty("name", t.builder.unversionedSdkMemberName(name)) + module.setProperty("name", t.builder.unversionedSdkMemberName(name, true)) // Set prefer: false - this is not strictly required as that is the default. module.insertAfter("name", "prefer", false) @@ -463,8 +478,9 @@ func (t unversionedTransformation) transformModule(module *bpModule) *bpModule { } func (t unversionedTransformation) transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) { - if tag == sdkMemberReferencePropertyTag { - return t.builder.unversionedSdkMemberNames(value.([]string)), tag + if tag == requiredSdkMemberReferencePropertyTag || tag == optionalSdkMemberReferencePropertyTag { + required := tag == requiredSdkMemberReferencePropertyTag + return t.builder.unversionedSdkMemberNames(value.([]string), required), tag } else if tag == sdkVersionedOnlyPropertyTag { // The property is not allowed in the unversioned module so remove it. return nil, nil @@ -559,6 +575,12 @@ type snapshotBuilder struct { prebuiltModules map[string]*bpModule prebuiltOrder []*bpModule + + // The set of all members by name. + allMembersByName map[string]struct{} + + // The set of exported members by name. + exportedMembersByName map[string]struct{} } func (s *snapshotBuilder) CopyToSnapshot(src android.Path, dest string) { @@ -612,7 +634,7 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType variant := member.Variants()[0] - if s.sdk.isInternalMember(name) { + if s.isInternalMember(name) { // An internal member is only referenced from the sdk snapshot which is in the // same package so can be marked as private. m.AddProperty("visibility", []string{"//visibility:private"}) @@ -676,40 +698,66 @@ func addHostDeviceSupportedProperties(deviceSupported bool, hostSupported bool, } } -func (s *snapshotBuilder) SdkMemberReferencePropertyTag() android.BpPropertyTag { - return sdkMemberReferencePropertyTag +func (s *snapshotBuilder) SdkMemberReferencePropertyTag(required bool) android.BpPropertyTag { + if required { + return requiredSdkMemberReferencePropertyTag + } else { + return optionalSdkMemberReferencePropertyTag + } +} + +func (s *snapshotBuilder) OptionalSdkMemberReferencePropertyTag() android.BpPropertyTag { + return optionalSdkMemberReferencePropertyTag } // Get a versioned name appropriate for the SDK snapshot version being taken. -func (s *snapshotBuilder) versionedSdkMemberName(unversionedName string) string { +func (s *snapshotBuilder) versionedSdkMemberName(unversionedName string, required bool) string { + if _, ok := s.allMembersByName[unversionedName]; !ok { + if required { + s.ctx.ModuleErrorf("Required member reference %s is not a member of the sdk", unversionedName) + } + return unversionedName + } return versionedSdkMemberName(s.ctx, unversionedName, s.version) } -func (s *snapshotBuilder) versionedSdkMemberNames(members []string) []string { +func (s *snapshotBuilder) versionedSdkMemberNames(members []string, required bool) []string { var references []string = nil for _, m := range members { - references = append(references, s.versionedSdkMemberName(m)) + references = append(references, s.versionedSdkMemberName(m, required)) } return references } // Get an internal name unique to the sdk. -func (s *snapshotBuilder) unversionedSdkMemberName(unversionedName string) string { - if s.sdk.isInternalMember(unversionedName) { +func (s *snapshotBuilder) unversionedSdkMemberName(unversionedName string, required bool) string { + if _, ok := s.allMembersByName[unversionedName]; !ok { + if required { + s.ctx.ModuleErrorf("Required member reference %s is not a member of the sdk", unversionedName) + } + return unversionedName + } + + if s.isInternalMember(unversionedName) { return s.ctx.ModuleName() + "_" + unversionedName } else { return unversionedName } } -func (s *snapshotBuilder) unversionedSdkMemberNames(members []string) []string { +func (s *snapshotBuilder) unversionedSdkMemberNames(members []string, required bool) []string { var references []string = nil for _, m := range members { - references = append(references, s.unversionedSdkMemberName(m)) + references = append(references, s.unversionedSdkMemberName(m, required)) } return references } +func (s *snapshotBuilder) isInternalMember(memberName string) bool { + _, ok := s.exportedMembersByName[memberName] + return !ok +} + type sdkMemberRef struct { memberType android.SdkMemberType variant android.SdkAware