diff --git a/android/module.go b/android/module.go index 2e33056ac..057a5c71f 100644 --- a/android/module.go +++ b/android/module.go @@ -985,6 +985,16 @@ func (m *ModuleBase) ImageVariation() blueprint.Variation { } } +func (m *ModuleBase) getVariationByMutatorName(mutator string) string { + for i, v := range m.commonProperties.DebugMutators { + if v == mutator { + return m.commonProperties.DebugVariations[i] + } + } + + return "" +} + func (m *ModuleBase) InRamdisk() bool { return m.base().commonProperties.ImageVariation == RamdiskVariation } diff --git a/cc/library.go b/cc/library.go index 6bd93f969..0dd077eab 100644 --- a/cc/library.go +++ b/cc/library.go @@ -195,6 +195,7 @@ func LibraryFactory() android.Module { module.sdkMemberTypes = []android.SdkMemberType{ sharedLibrarySdkMemberType, staticLibrarySdkMemberType, + staticAndSharedLibrarySdkMemberType, } return module.Init() } diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go index 69c3d18d2..d010db10e 100644 --- a/cc/library_sdk_member.go +++ b/cc/library_sdk_member.go @@ -43,10 +43,20 @@ var staticLibrarySdkMemberType = &librarySdkMemberType{ linkTypes: []string{"static"}, } +var staticAndSharedLibrarySdkMemberType = &librarySdkMemberType{ + SdkMemberTypeBase: android.SdkMemberTypeBase{ + PropertyName: "native_libs", + SupportsSdk: true, + }, + prebuiltModuleType: "cc_prebuilt_library", + linkTypes: []string{"static", "shared"}, +} + func init() { // Register sdk member types. android.RegisterSdkMemberType(sharedLibrarySdkMemberType) android.RegisterSdkMemberType(staticLibrarySdkMemberType) + android.RegisterSdkMemberType(staticAndSharedLibrarySdkMemberType) } type librarySdkMemberType struct { @@ -342,9 +352,12 @@ func (p *nativeLibInfoProperties) PopulateFromVariant(variant android.SdkAware) p.name = variant.Name() p.archType = ccModule.Target().Arch.ArchType.String() - p.ExportedIncludeDirs = exportedIncludeDirs - p.exportedGeneratedIncludeDirs = exportedGeneratedIncludeDirs - p.ExportedSystemIncludeDirs = ccModule.ExportedSystemIncludeDirs() + + // Make sure that the include directories are unique. + p.ExportedIncludeDirs = android.FirstUniquePaths(exportedIncludeDirs) + p.exportedGeneratedIncludeDirs = android.FirstUniquePaths(exportedGeneratedIncludeDirs) + p.ExportedSystemIncludeDirs = android.FirstUniquePaths(ccModule.ExportedSystemIncludeDirs()) + p.ExportedFlags = ccModule.ExportedFlags() if ccModule.linker != nil { specifiedDeps := specifiedDeps{} diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go index 6727b4bf0..27a951865 100644 --- a/sdk/cc_sdk_test.go +++ b/sdk/cc_sdk_test.go @@ -1196,6 +1196,93 @@ include/Test.h -> include/include/Test.h ) } +func TestSnapshotWithCcLibrary(t *testing.T) { + result := testSdkWithCc(t, ` + module_exports { + name: "myexports", + native_libs: ["mynativelib"], + } + + cc_library { + name: "mynativelib", + srcs: [ + "Test.cpp", + ], + export_include_dirs: ["include"], + system_shared_libs: [], + stl: "none", + } + `) + + result.CheckSnapshot("myexports", "", + checkAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +cc_prebuilt_library { + name: "myexports_mynativelib@current", + sdk_member_name: "mynativelib", + installable: false, + stl: "none", + export_include_dirs: ["include/include"], + arch: { + arm64: { + static: { + srcs: ["arm64/lib/mynativelib.a"], + }, + shared: { + srcs: ["arm64/lib/mynativelib.so"], + }, + }, + arm: { + static: { + srcs: ["arm/lib/mynativelib.a"], + }, + shared: { + srcs: ["arm/lib/mynativelib.so"], + }, + }, + }, +} + +cc_prebuilt_library { + name: "mynativelib", + prefer: false, + stl: "none", + export_include_dirs: ["include/include"], + arch: { + arm64: { + static: { + srcs: ["arm64/lib/mynativelib.a"], + }, + shared: { + srcs: ["arm64/lib/mynativelib.so"], + }, + }, + arm: { + static: { + srcs: ["arm/lib/mynativelib.a"], + }, + shared: { + srcs: ["arm/lib/mynativelib.so"], + }, + }, + }, +} + +module_exports_snapshot { + name: "myexports@current", + native_libs: ["myexports_mynativelib@current"], +} +`), + checkAllCopyRules(` +include/Test.h -> include/include/Test.h +.intermediates/mynativelib/android_arm64_armv8-a_static/mynativelib.a -> arm64/lib/mynativelib.a +.intermediates/mynativelib/android_arm64_armv8-a_shared/mynativelib.so -> arm64/lib/mynativelib.so +.intermediates/mynativelib/android_arm_armv7-a-neon_static/mynativelib.a -> arm/lib/mynativelib.a +.intermediates/mynativelib/android_arm_armv7-a-neon_shared/mynativelib.so -> arm/lib/mynativelib.so`), + ) +} + func TestHostSnapshotWithMultiLib64(t *testing.T) { // b/145598135 - Generating host snapshots for anything other than linux is not supported. SkipIfNotLinux(t) diff --git a/sdk/update.go b/sdk/update.go index c622ddf3e..ce25fc40a 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -21,6 +21,7 @@ import ( "strings" "android/soong/apex" + "android/soong/cc" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -866,6 +867,9 @@ func (osInfo *osTypeSpecificInfo) optimizeProperties(commonValueExtractor *commo var archPropertiesList []android.SdkMemberProperties for _, archInfo := range osInfo.archInfos { + // Optimize the arch properties first. + archInfo.optimizeProperties(commonValueExtractor) + archPropertiesList = append(archPropertiesList, archInfo.Properties) } @@ -961,32 +965,107 @@ type archTypeSpecificInfo struct { baseInfo archType android.ArchType + + linkInfos []*linkTypeSpecificInfo } // Create a new archTypeSpecificInfo for the specified arch type and its properties // structures populated with information from the variants. func newArchSpecificInfo(archType android.ArchType, variantPropertiesFactory variantPropertiesFactoryFunc, archVariants []android.SdkAware) *archTypeSpecificInfo { - if len(archVariants) != 1 { - panic(fmt.Errorf("expected one arch specific variant but found %d", len(archVariants))) - } - // Create an arch specific info into which the variant properties can be copied. archInfo := &archTypeSpecificInfo{archType: archType} // Create the properties into which the arch type specific properties will be // added. archInfo.Properties = variantPropertiesFactory() - archInfo.Properties.PopulateFromVariant(archVariants[0]) + + if len(archVariants) == 1 { + archInfo.Properties.PopulateFromVariant(archVariants[0]) + } else { + // There is more than one variant for this arch type which must be differentiated + // by link type. + for _, linkVariant := range archVariants { + linkType := getLinkType(linkVariant) + if linkType == "" { + panic(fmt.Errorf("expected one arch specific variant as it is not identified by link type but found %d", len(archVariants))) + } else { + linkInfo := newLinkSpecificInfo(linkType, variantPropertiesFactory, linkVariant) + + archInfo.linkInfos = append(archInfo.linkInfos, linkInfo) + } + } + } return archInfo } +// Get the link type of the variant +// +// If the variant is not differentiated by link type then it returns "", +// otherwise it returns one of "static" or "shared". +func getLinkType(variant android.Module) string { + linkType := "" + if linkable, ok := variant.(cc.LinkableInterface); ok { + if linkable.Shared() && linkable.Static() { + panic(fmt.Errorf("expected variant %q to be either static or shared but was both", variant.String())) + } else if linkable.Shared() { + linkType = "shared" + } else if linkable.Static() { + linkType = "static" + } else { + panic(fmt.Errorf("expected variant %q to be either static or shared but was neither", variant.String())) + } + } + return linkType +} + +// Optimize the properties by extracting common properties from link type specific +// properties into arch type specific properties. +func (archInfo *archTypeSpecificInfo) optimizeProperties(commonValueExtractor *commonValueExtractor) { + if len(archInfo.linkInfos) == 0 { + return + } + + var propertiesList []android.SdkMemberProperties + for _, linkInfo := range archInfo.linkInfos { + propertiesList = append(propertiesList, linkInfo.Properties) + } + + commonValueExtractor.extractCommonProperties(archInfo.Properties, propertiesList) +} + // Add the properties for an arch type to a property set. func (archInfo *archTypeSpecificInfo) addToPropertySet(builder *snapshotBuilder, archPropertySet android.BpPropertySet, archOsPrefix string) { archTypeName := archInfo.archType.Name archTypePropertySet := archPropertySet.AddPropertySet(archOsPrefix + archTypeName) archInfo.Properties.AddToPropertySet(builder.ctx, builder, archTypePropertySet) + + for _, linkInfo := range archInfo.linkInfos { + linkPropertySet := archTypePropertySet.AddPropertySet(linkInfo.linkType) + linkInfo.Properties.AddToPropertySet(builder.ctx, builder, linkPropertySet) + } +} + +type linkTypeSpecificInfo struct { + baseInfo + + linkType string +} + +// Create a new linkTypeSpecificInfo for the specified link type and its properties +// structures populated with information from the variant. +func newLinkSpecificInfo(linkType string, variantPropertiesFactory variantPropertiesFactoryFunc, linkVariant android.SdkAware) *linkTypeSpecificInfo { + linkInfo := &linkTypeSpecificInfo{ + baseInfo: baseInfo{ + // Create the properties into which the link type specific properties will be + // added. + Properties: variantPropertiesFactory(), + }, + linkType: linkType, + } + linkInfo.Properties.PopulateFromVariant(linkVariant) + return linkInfo } func (s *sdk) createMemberSnapshot(sdkModuleContext android.ModuleContext, builder *snapshotBuilder, member *sdkMember, bpModule android.BpModule) {