diff --git a/android/apex.go b/android/apex.go index a4de6dd7f..eb7912323 100644 --- a/android/apex.go +++ b/android/apex.go @@ -168,7 +168,7 @@ func (m *ApexModuleBase) IsInstallableToApex() bool { const ( AvailableToPlatform = "//apex_available:platform" - availableToAnyApex = "//apex_available:anyapex" + AvailableToAnyApex = "//apex_available:anyapex" ) func CheckAvailableForApex(what string, apex_available []string) bool { @@ -178,7 +178,7 @@ func CheckAvailableForApex(what string, apex_available []string) bool { return what == AvailableToPlatform } return InList(what, apex_available) || - (what != AvailableToPlatform && InList(availableToAnyApex, apex_available)) + (what != AvailableToPlatform && InList(AvailableToAnyApex, apex_available)) } func (m *ApexModuleBase) AvailableFor(what string) bool { @@ -212,7 +212,7 @@ func (m *ApexModuleBase) ShouldSupportAndroid10() bool { func (m *ApexModuleBase) checkApexAvailableProperty(mctx BaseModuleContext) { for _, n := range m.ApexProperties.Apex_available { - if n == AvailableToPlatform || n == availableToAnyApex { + if n == AvailableToPlatform || n == AvailableToAnyApex { continue } if !mctx.OtherModuleExists(n) && !mctx.Config().AllowMissingDependencies() { diff --git a/apex/apex.go b/apex/apex.go index a33117b0c..730dc52b8 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -63,8 +63,26 @@ var ( usesTag = dependencyTag{name: "uses"} androidAppTag = dependencyTag{name: "androidApp", payload: true} apexAvailWl = makeApexAvailableWhitelist() + + inverseApexAvailWl = invertApexWhiteList(apexAvailWl) ) +// Transform the map of apex -> modules to module -> apexes. +func invertApexWhiteList(m map[string][]string) map[string][]string { + r := make(map[string][]string) + for apex, modules := range m { + for _, module := range modules { + r[module] = append(r[module], apex) + } + } + return r +} + +// Retrieve the while list of apexes to which the supplied module belongs. +func WhitelistedApexAvailable(moduleName string) []string { + return inverseApexAvailWl[normalizeModuleName(moduleName)] +} + // This is a map from apex to modules, which overrides the // apex_available setting for that particular module to make // it available for the apex regardless of its setting. @@ -969,7 +987,7 @@ func makeApexAvailableWhitelist() map[string][]string { // // Module separator // - m["//any"] = []string{ + m[android.AvailableToAnyApex] = []string{ "crtbegin_dynamic", "crtbegin_dynamic1", "crtbegin_so", @@ -2400,6 +2418,21 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { func whitelistedApexAvailable(apex, moduleName string) bool { key := apex + moduleName = normalizeModuleName(moduleName) + + if val, ok := apexAvailWl[key]; ok && android.InList(moduleName, val) { + return true + } + + key = android.AvailableToAnyApex + if val, ok := apexAvailWl[key]; ok && android.InList(moduleName, val) { + return true + } + + return false +} + +func normalizeModuleName(moduleName string) string { // Prebuilt modules (e.g. java_import, etc.) have "prebuilt_" prefix added by the build // system. Trim the prefix for the check since they are confusing moduleName = strings.TrimPrefix(moduleName, "prebuilt_") @@ -2408,17 +2441,7 @@ func whitelistedApexAvailable(apex, moduleName string) bool { // We don't want to list them all moduleName = "libclang_rt" } - - if val, ok := apexAvailWl[key]; ok && android.InList(moduleName, val) { - return true - } - - key = "//any" - if val, ok := apexAvailWl[key]; ok && android.InList(moduleName, val) { - return true - } - - return false + return moduleName } func newApexBundle() *apexBundle { diff --git a/cc/cc.go b/cc/cc.go index 8b3c77202..4310a36c2 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -250,6 +250,8 @@ type BaseProperties struct { // Used by vendor snapshot to record dependencies from snapshot modules. SnapshotSharedLibs []string `blueprint:"mutated"` SnapshotRuntimeLibs []string `blueprint:"mutated"` + + Installable *bool } type VendorProperties struct { @@ -371,6 +373,7 @@ type linker interface { type installer interface { installerProps() []interface{} install(ctx ModuleContext, path android.Path) + everInstallable() bool inData() bool inSanitizerDir() bool hostToolPath() android.OptionalPath @@ -1488,6 +1491,13 @@ func (c *Module) GenerateAndroidBuildActions(actx android.ModuleContext) { if ctx.Failed() { return } + } else if !proptools.BoolDefault(c.Properties.Installable, true) { + // If the module has been specifically configure to not be installed then + // skip the installation as otherwise it will break when running inside make + // as the output path to install will not be specified. Not all uninstallable + // modules can skip installation as some are needed for resolving make side + // dependencies. + c.SkipInstall() } } @@ -2629,8 +2639,18 @@ func (c *Module) AvailableFor(what string) bool { } } +// Return true if the module is ever installable. +func (c *Module) EverInstallable() bool { + return c.installer != nil && + // Check to see whether the module is actually ever installable. + c.installer.everInstallable() +} + func (c *Module) installable() bool { - ret := c.installer != nil && !c.Properties.PreventInstall && c.outputFile.Valid() + ret := c.EverInstallable() && + // Check to see whether the module has been configured to not be installed. + proptools.BoolDefault(c.Properties.Installable, true) && + !c.Properties.PreventInstall && c.outputFile.Valid() // 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 diff --git a/cc/installer.go b/cc/installer.go index 2f55ac57b..200d59e9f 100644 --- a/cc/installer.go +++ b/cc/installer.go @@ -86,6 +86,11 @@ func (installer *baseInstaller) install(ctx ModuleContext, file android.Path) { installer.path = ctx.InstallFile(installer.installDir(ctx), file.Base(), file) } +func (installer *baseInstaller) everInstallable() bool { + // Most cc modules are installable. + return true +} + func (installer *baseInstaller) inData() bool { return installer.location == InstallInData } diff --git a/cc/library.go b/cc/library.go index e1d0b34a0..47ac7b032 100644 --- a/cc/library.go +++ b/cc/library.go @@ -1220,6 +1220,12 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) { } } +func (library *libraryDecorator) everInstallable() bool { + // Only shared and static libraries are installed. Header libraries (which are + // neither static or shared) are not installed. + return library.shared() || library.static() +} + func (library *libraryDecorator) static() bool { return library.MutatedProperties.VariantIsStatic } diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go index 11bc90238..2b0fd3c93 100644 --- a/sdk/cc_sdk_test.go +++ b/sdk/cc_sdk_test.go @@ -297,6 +297,7 @@ func TestSnapshotWithCcSharedLibraryCommonProperties(t *testing.T) { cc_prebuilt_library_shared { name: "mysdk_mynativelib@current", sdk_member_name: "mynativelib", + installable: false, export_include_dirs: ["include/include"], arch: { arm64: { @@ -366,6 +367,7 @@ func TestSnapshotWithCcBinary(t *testing.T) { cc_prebuilt_binary { name: "mymodule_exports_mynativebinary@current", sdk_member_name: "mynativebinary", + installable: false, compile_multilib: "both", arch: { arm64: { @@ -447,6 +449,7 @@ cc_prebuilt_binary { sdk_member_name: "mynativebinary", device_supported: false, host_supported: true, + installable: false, target: { linux_glibc: { compile_multilib: "both", @@ -539,6 +542,7 @@ cc_prebuilt_library_shared { "apex1", "apex2", ], + installable: false, export_include_dirs: ["include/include"], arch: { arm64: { @@ -634,6 +638,7 @@ cc_prebuilt_library_shared { sdk_member_name: "mynativelib", device_supported: false, host_supported: true, + installable: false, sdk_version: "minimum", export_include_dirs: ["include/include"], arch: { @@ -735,6 +740,7 @@ cc_prebuilt_library_shared { sdk_member_name: "mynativelib", device_supported: false, host_supported: true, + installable: false, target: { linux_glibc_x86_64: { srcs: ["linux_glibc/x86_64/lib/mynativelib.so"], @@ -814,6 +820,7 @@ func TestSnapshotWithCcStaticLibrary(t *testing.T) { cc_prebuilt_library_static { name: "myexports_mynativelib@current", sdk_member_name: "mynativelib", + installable: false, export_include_dirs: ["include/include"], arch: { arm64: { @@ -904,6 +911,7 @@ cc_prebuilt_library_static { sdk_member_name: "mynativelib", device_supported: false, host_supported: true, + installable: false, export_include_dirs: ["include/include"], arch: { x86_64: { @@ -1003,6 +1011,7 @@ cc_prebuilt_library_static { sdk_member_name: "mynativelib", device_supported: false, host_supported: true, + installable: false, export_include_dirs: ["include/include"], arch: { x86_64: { diff --git a/sdk/update.go b/sdk/update.go index a43a14b85..0084eb76d 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -20,6 +20,7 @@ import ( "sort" "strings" + "android/soong/apex" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -409,8 +410,19 @@ type propertyTag struct { name string } +// 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 sdkMemberReferencePropertyTag = propertyTag{"sdkMemberReferencePropertyTag"} +// A BpPropertyTag that indicates the property should only be present in the versioned +// module. +// +// This will cause the property to be removed from the unversioned instance of a +// snapshot module. +var sdkVersionedOnlyPropertyTag = propertyTag{"sdkVersionedOnlyPropertyTag"} + type unversionedToVersionedTransformation struct { identityTransformation builder *snapshotBuilder @@ -452,6 +464,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 + } else if tag == sdkVersionedOnlyPropertyTag { + // The property is not allowed in the unversioned module so remove it. + return nil, nil } else { return value, tag } @@ -626,11 +641,26 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType // Where available copy apex_available properties from the member. if apexAware, ok := variant.(interface{ ApexAvailable() []string }); ok { apexAvailable := apexAware.ApexAvailable() + + // Add in any white listed apex available settings. + apexAvailable = append(apexAvailable, apex.WhitelistedApexAvailable(member.Name())...) + if len(apexAvailable) > 0 { + // Remove duplicates and sort. + apexAvailable = android.FirstUniqueStrings(apexAvailable) + sort.Strings(apexAvailable) + m.AddProperty("apex_available", apexAvailable) } } + // Disable installation in the versioned module of those modules that are ever installable. + if installable, ok := variant.(interface{ EverInstallable() bool }); ok { + if installable.EverInstallable() { + m.AddPropertyWithTag("installable", false, sdkVersionedOnlyPropertyTag) + } + } + s.prebuiltModules[name] = m s.prebuiltOrder = append(s.prebuiltOrder, m) return m