diff --git a/cc/androidmk.go b/cc/androidmk.go index eb6306539..2114031f6 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -89,7 +89,7 @@ func (c *Module) AndroidMk() android.AndroidMkData { } c.subAndroidMk(&ret, c.installer) - if c.vndk() && Bool(c.VendorProperties.Vendor_available) { + if c.vndk() && c.hasVendorVariant() { // .vendor suffix is added only when we will have two variants: core and vendor. // The suffix is not added for vendor-only module. ret.SubName += vendorSuffix diff --git a/cc/cc.go b/cc/cc.go index 4f10a115d..0404cfb50 100644 --- a/cc/cc.go +++ b/cc/cc.go @@ -168,16 +168,21 @@ type BaseProperties struct { } type VendorProperties struct { - // whether this module should be allowed to install onto /vendor as - // well as /system. The two variants will be built separately, one - // like normal, and the other limited to the set of libraries and - // headers that are exposed to /vendor modules. + // whether this module should be allowed to be directly depended by other + // modules with `vendor: true`, `proprietary: true`, or `vendor_available:true`. + // If set to true, two variants will be built separately, one like + // normal, and the other limited to the set of libraries and headers + // that are exposed to /vendor modules. // // The vendor variant may be used with a different (newer) /system, // so it shouldn't have any unversioned runtime dependencies, or // make assumptions about the system that may not be true in the // future. // + // If set to false, this module becomes inaccessible from /vendor modules. + // + // Default value is true when vndk: {enabled: true} or vendor: true. + // // Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk Vendor_available *bool } @@ -388,6 +393,12 @@ func (c *Module) isVndk() bool { return false } +// Returns true only when this module is configured to have core and vendor +// variants. +func (c *Module) hasVendorVariant() bool { + return c.isVndk() || Bool(c.VendorProperties.Vendor_available) +} + type baseModuleContext struct { android.BaseContext moduleContextImpl @@ -1159,7 +1170,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { // Export the shared libs to the make world. In doing so, .vendor suffix // is added if the lib has both core and vendor variants and this module - // is building against vndk. This is because the vendor variant will be + // is building against vndk. This is because the vendor variant will // have .vendor suffix in its name in the make world. However, if the // lib is a vendor-only lib or this lib is not building against vndk, // then the suffix is not added. @@ -1168,7 +1179,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps { libName := strings.TrimSuffix(name, llndkLibrarySuffix) libName = strings.TrimPrefix(libName, "prebuilt_") isLLndk := inList(libName, llndkLibraries) - if c.vndk() && (Bool(cc.VendorProperties.Vendor_available) || isLLndk) { + if c.vndk() && (cc.hasVendorVariant() || isLLndk) { libName += vendorSuffix } // Note: the order of libs in this list is not important because @@ -1311,15 +1322,15 @@ func vendorMutator(mctx android.BottomUpMutatorContext) { } // Sanity check - if Bool(m.VendorProperties.Vendor_available) && mctx.Vendor() { + if m.VendorProperties.Vendor_available != nil && mctx.Vendor() { mctx.PropertyErrorf("vendor_available", "doesn't make sense at the same time as `vendor: true` or `proprietary: true`") return } if vndk := m.vndkdep; vndk != nil { - if vndk.isVndk() && !Bool(m.VendorProperties.Vendor_available) { + if vndk.isVndk() && m.VendorProperties.Vendor_available == nil { mctx.PropertyErrorf("vndk", - "has to define `vendor_available: true` to enable vndk") + "vendor_available must be set to either true or false when `vndk: {enabled: true}`") return } if !vndk.isVndk() && vndk.isVndkSp() { @@ -1337,7 +1348,7 @@ func vendorMutator(mctx android.BottomUpMutatorContext) { // LL-NDK stubs only exist in the vendor variant, since the // real libraries will be used in the core variant. mctx.CreateVariations(vendorMode) - } else if Bool(m.VendorProperties.Vendor_available) { + } else if m.hasVendorVariant() { // This will be available in both /system and /vendor // or a /system directory that is available to vendor. mod := mctx.CreateVariations(coreMode, vendorMode) diff --git a/cc/llndk_library.go b/cc/llndk_library.go index c3d3462bb..30c4d4ca6 100644 --- a/cc/llndk_library.go +++ b/cc/llndk_library.go @@ -50,6 +50,11 @@ type llndkLibraryProperties struct { // Whether the system library uses symbol versions. Unversioned bool + + // whether this module can be directly depended upon by libs that are installed to /vendor. + // When set to false, this module can only be depended on by VNDK libraries, not vendor + // libraries. This effectively hides this module from vendors. Default value is true. + Vendor_available bool } type llndkStubDecorator struct { @@ -149,6 +154,7 @@ func newLLndkStubLibrary() *Module { stub := &llndkStubDecorator{ libraryDecorator: library, } + stub.Properties.Vendor_available = true module.compiler = stub module.linker = stub module.installer = nil diff --git a/cc/makevars.go b/cc/makevars.go index 2c6af7077..295b4ac00 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -62,6 +62,7 @@ func makeVarsProvider(ctx android.MakeVarsContext) { ctx.Strict("VNDK_CORE_LIBRARIES", strings.Join(vndkCoreLibraries, " ")) ctx.Strict("VNDK_SAMEPROCESS_LIBRARIES", strings.Join(vndkSpLibraries, " ")) ctx.Strict("LLNDK_LIBRARIES", strings.Join(llndkLibraries, " ")) + ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(vndkPrivateLibraries, " ")) ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_CFLAGS", strings.Join(asanCflags, " ")) ctx.Strict("ADDRESS_SANITIZER_CONFIG_EXTRA_LDFLAGS", strings.Join(asanLdflags, " ")) diff --git a/cc/vndk.go b/cc/vndk.go index 395069b29..860678d6f 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -27,8 +27,8 @@ type VndkProperties struct { // declared as a VNDK or VNDK-SP module. The vendor variant // will be installed in /system instead of /vendor partition. // - // `vendor_available: true` must set to together for VNDK - // modules. + // `vendor_vailable` must be explicitly set to either true or + // false together with `vndk: {enabled: true}`. Enabled *bool // declared as a VNDK-SP module, which is a subset of VNDK. @@ -81,6 +81,24 @@ func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module) { if to.linker == nil { return } + if !vndk.isVndk() { + // Non-VNDK modules (those installed to /vendor) can't depend on modules marked with + // vendor_available: false. + violation := false + if lib, ok := to.linker.(*llndkStubDecorator); ok && !lib.Properties.Vendor_available { + violation = true + } else { + if _, ok := to.linker.(libraryInterface); ok && to.VendorProperties.Vendor_available != nil && !Bool(to.VendorProperties.Vendor_available) { + // Vendor_available == nil && !Bool(Vendor_available) should be okay since + // it means a vendor-only library which is a valid dependency for non-VNDK + // modules. + violation = true + } + } + if violation { + ctx.ModuleErrorf("Vendor module that is not VNDK should not link to %q which is marked as `vendor_available: false`", to.Name()) + } + } if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() { // Check only shared libraries. // Other (static and LL-NDK) libraries are allowed to link. @@ -102,16 +120,17 @@ func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module) { } var ( - vndkCoreLibraries []string - vndkSpLibraries []string - llndkLibraries []string - vndkLibrariesLock sync.Mutex + vndkCoreLibraries []string + vndkSpLibraries []string + llndkLibraries []string + vndkPrivateLibraries []string + vndkLibrariesLock sync.Mutex ) // gather list of vndk-core, vndk-sp, and ll-ndk libs func vndkMutator(mctx android.BottomUpMutatorContext) { if m, ok := mctx.Module().(*Module); ok { - if _, ok := m.linker.(*llndkStubDecorator); ok { + if lib, ok := m.linker.(*llndkStubDecorator); ok { vndkLibrariesLock.Lock() defer vndkLibrariesLock.Unlock() name := strings.TrimSuffix(m.Name(), llndkLibrarySuffix) @@ -119,22 +138,40 @@ func vndkMutator(mctx android.BottomUpMutatorContext) { llndkLibraries = append(llndkLibraries, name) sort.Strings(llndkLibraries) } - } else if lib, ok := m.linker.(*libraryDecorator); ok && lib.shared() { - if m.vndkdep.isVndk() { - vndkLibrariesLock.Lock() - defer vndkLibrariesLock.Unlock() - if m.vndkdep.isVndkSp() { - if !inList(m.Name(), vndkSpLibraries) { - vndkSpLibraries = append(vndkSpLibraries, m.Name()) - sort.Strings(vndkSpLibraries) + if !lib.Properties.Vendor_available { + if !inList(name, vndkPrivateLibraries) { + vndkPrivateLibraries = append(vndkPrivateLibraries, name) + sort.Strings(vndkPrivateLibraries) + } + } + } else { + lib, is_lib := m.linker.(*libraryDecorator) + prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker) + if (is_lib && lib.shared()) || (is_prebuilt_lib && prebuilt_lib.shared()) { + name := strings.TrimPrefix(m.Name(), "prebuilt_") + if m.vndkdep.isVndk() { + vndkLibrariesLock.Lock() + defer vndkLibrariesLock.Unlock() + if m.vndkdep.isVndkSp() { + if !inList(name, vndkSpLibraries) { + vndkSpLibraries = append(vndkSpLibraries, name) + sort.Strings(vndkSpLibraries) + } + } else { + if !inList(name, vndkCoreLibraries) { + vndkCoreLibraries = append(vndkCoreLibraries, name) + sort.Strings(vndkCoreLibraries) + } } - } else { - if !inList(m.Name(), vndkCoreLibraries) { - vndkCoreLibraries = append(vndkCoreLibraries, m.Name()) - sort.Strings(vndkCoreLibraries) + if !Bool(m.VendorProperties.Vendor_available) { + if !inList(name, vndkPrivateLibraries) { + vndkPrivateLibraries = append(vndkPrivateLibraries, name) + sort.Strings(vndkPrivateLibraries) + } } } } } + } }