vendor_available:false hides a lib from vendors
When a lib is explicitly marked as `vendor_available: false`, then it can't be directly depended by a vendor lib which is installed to /vendor partition. This is to hide some VNDK libs (including llndk) from vendors so that platform owners can have a freedom of modifying their ABI without breaking vendors. In addition, the list of the private libs are exported to the make world as VNDK_PRIVATE_LIBRARIES. Also, fixed a bug that allowed a vndk lib to link against to vendor library (or vendor variant of a system lib) if the lib is prebuilt. Bug: 64730695 Bug: 64994918 Test: Add `vendor_available: false` to libft2 and libcompiler_rt. Add the libs to shared_libs property of a vendor library in soong (i.e. libnbaio_mono). The build fails with the error message. Change-Id: Iab575db96bb4f6739a592f3fa0a75124296bea0c
This commit is contained in:
parent
c7ba6a2e46
commit
82e2bf3b7f
5 changed files with 85 additions and 30 deletions
|
@ -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
|
||||
|
|
31
cc/cc.go
31
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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, " "))
|
||||
|
|
75
cc/vndk.go
75
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue