Support VNDK extensions

am: f351174107

Change-Id: Ic8694308013e535da7431da1520e5ea023f5f0e1
This commit is contained in:
Logan Chien
2018-01-23 02:19:20 +00:00
committed by android-build-merger
5 changed files with 779 additions and 54 deletions

View File

@@ -38,7 +38,6 @@ const (
var (
abiCheckAllowFlags = []string{
"-allow-extensions",
"-allow-unreferenced-changes",
"-allow-unreferenced-elf-symbol-changes",
}
@@ -711,12 +710,18 @@ func UnzipRefDump(ctx android.ModuleContext, zippedRefDump android.Path, baseNam
}
func SourceAbiDiff(ctx android.ModuleContext, inputDump android.Path, referenceDump android.Path,
baseName, exportedHeaderFlags string) android.OptionalPath {
baseName, exportedHeaderFlags string, isVndkExt bool) android.OptionalPath {
outputFile := android.PathForModuleOut(ctx, baseName+".abidiff")
localAbiCheckAllowFlags := append([]string(nil), abiCheckAllowFlags...)
if exportedHeaderFlags == "" {
localAbiCheckAllowFlags = append(localAbiCheckAllowFlags, "-advice-only")
}
if isVndkExt {
localAbiCheckAllowFlags = append(localAbiCheckAllowFlags, "-allow-extensions")
}
ctx.Build(pctx, android.BuildParams{
Rule: sAbiDiff,
Description: "header-abi-diff " + outputFile.Base(),

104
cc/cc.go
View File

@@ -205,9 +205,11 @@ type ModuleContextIntf interface {
useVndk() bool
isVndk() bool
isVndkSp() bool
isVndkExt() bool
createVndkSourceAbiDump() bool
selectedStl() string
baseModuleName() string
getVndkExtendsModuleName() string
}
type ModuleContext interface {
@@ -289,6 +291,7 @@ var (
reuseObjTag = dependencyTag{name: "reuse objects"}
ndkStubDepTag = dependencyTag{name: "ndk stub", library: true}
ndkLateStubDepTag = dependencyTag{name: "ndk late stub", library: true}
vndkExtDepTag = dependencyTag{name: "vndk extends", library: true}
)
// Module contains the properties and members used by all C/C++ module types, and implements
@@ -398,12 +401,33 @@ func (c *Module) useVndk() bool {
}
func (c *Module) isVndk() bool {
if c.vndkdep != nil {
return c.vndkdep.isVndk()
if vndkdep := c.vndkdep; vndkdep != nil {
return vndkdep.isVndk()
}
return false
}
func (c *Module) isVndkSp() bool {
if vndkdep := c.vndkdep; vndkdep != nil {
return vndkdep.isVndkSp()
}
return false
}
func (c *Module) isVndkExt() bool {
if vndkdep := c.vndkdep; vndkdep != nil {
return vndkdep.isVndkExt()
}
return false
}
func (c *Module) getVndkExtendsModuleName() string {
if vndkdep := c.vndkdep; vndkdep != nil {
return vndkdep.getVndkExtendsModuleName()
}
return ""
}
// Returns true only when this module is configured to have core and vendor
// variants.
func (c *Module) hasVendorVariant() bool {
@@ -474,18 +498,20 @@ func (ctx *moduleContextImpl) sdkVersion() string {
return ""
}
func (ctx *moduleContextImpl) isVndk() bool {
return ctx.mod.isVndk()
}
func (ctx *moduleContextImpl) useVndk() bool {
return ctx.mod.useVndk()
}
func (ctx *moduleContextImpl) isVndkSp() bool {
if vndk := ctx.mod.vndkdep; vndk != nil {
return vndk.isVndkSp()
func (ctx *moduleContextImpl) isVndk() bool {
return ctx.mod.isVndk()
}
return false
func (ctx *moduleContextImpl) isVndkSp() bool {
return ctx.mod.isVndkSp()
}
func (ctx *moduleContextImpl) isVndkExt() bool {
return ctx.mod.isVndkExt()
}
// Create source abi dumps if the module belongs to the list of VndkLibraries.
@@ -504,6 +530,10 @@ func (ctx *moduleContextImpl) baseModuleName() string {
return ctx.mod.ModuleBase.BaseModuleName()
}
func (ctx *moduleContextImpl) getVndkExtendsModuleName() string {
return ctx.mod.getVndkExtendsModuleName()
}
func newBaseModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module {
return &Module{
hod: hod,
@@ -935,6 +965,18 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
{"ndk_api", version}, {"link", "shared"}}, ndkStubDepTag, variantNdkLibs...)
actx.AddVariationDependencies([]blueprint.Variation{
{"ndk_api", version}, {"link", "shared"}}, ndkLateStubDepTag, variantLateNdkLibs...)
if vndkdep := c.vndkdep; vndkdep != nil {
if vndkdep.isVndkExt() {
baseModuleMode := vendorMode
if actx.DeviceConfig().VndkVersion() == "" {
baseModuleMode = coreMode
}
actx.AddVariationDependencies([]blueprint.Variation{
{"image", baseModuleMode}, {"link", "shared"}}, vndkExtDepTag,
vndkdep.getVndkExtendsModuleName())
}
}
}
func beginMutator(ctx android.BottomUpMutatorContext) {
@@ -959,7 +1001,7 @@ func (c *Module) clang(ctx BaseModuleContext) bool {
// Whether a module can link to another module, taking into
// account NDK linking.
func checkLinkType(ctx android.ModuleContext, from *Module, to *Module) {
func checkLinkType(ctx android.ModuleContext, from *Module, to *Module, tag dependencyTag) {
if from.Target().Os != android.Android {
// Host code is not restricted
return
@@ -969,7 +1011,7 @@ func checkLinkType(ctx android.ModuleContext, from *Module, to *Module) {
// each vendor-available module needs to check
// link-type for VNDK.
if from.vndkdep != nil {
from.vndkdep.vndkCheckLinkType(ctx, to)
from.vndkdep.vndkCheckLinkType(ctx, to, tag)
}
return
}
@@ -1151,7 +1193,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
}
}
checkLinkType(ctx, c, ccDep)
checkLinkType(ctx, c, ccDep, t)
}
var ptr *android.Paths
@@ -1411,22 +1453,48 @@ func vendorMutator(mctx android.BottomUpMutatorContext) {
}
// Sanity check
if m.VendorProperties.Vendor_available != nil && (mctx.SocSpecific() || mctx.DeviceSpecific()) {
vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
if m.VendorProperties.Vendor_available != nil && vendorSpecific {
mctx.PropertyErrorf("vendor_available",
"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`")
return
}
if vndk := m.vndkdep; vndk != nil {
if vndk.isVndk() && m.VendorProperties.Vendor_available == nil {
if vndkdep := m.vndkdep; vndkdep != nil {
if vndkdep.isVndk() {
if vendorSpecific {
if !vndkdep.isVndkExt() {
mctx.PropertyErrorf("vndk",
"must set `extends: \"...\"` to vndk extension")
return
}
} else {
if vndkdep.isVndkExt() {
mctx.PropertyErrorf("vndk",
"must set `vendor: true` to set `extends: %q`",
m.getVndkExtendsModuleName())
return
}
if m.VendorProperties.Vendor_available == nil {
mctx.PropertyErrorf("vndk",
"vendor_available must be set to either true or false when `vndk: {enabled: true}`")
return
}
if !vndk.isVndk() && vndk.isVndkSp() {
}
} else {
if vndkdep.isVndkSp() {
mctx.PropertyErrorf("vndk",
"must set `enabled: true` to set `support_system_process: true`")
return
}
if vndkdep.isVndkExt() {
mctx.PropertyErrorf("vndk",
"must set `enabled: true` to set `extends: %q`",
m.getVndkExtendsModuleName())
return
}
}
}
if mctx.DeviceConfig().VndkVersion() == "" {
@@ -1453,14 +1521,14 @@ func vendorMutator(mctx android.BottomUpMutatorContext) {
vendor.Properties.PreventInstall = true
vendor.Properties.HideFromMake = true
}
} else if m.hasVendorVariant() {
} else if m.hasVendorVariant() && !vendorSpecific {
// This will be available in both /system and /vendor
// or a /system directory that is available to vendor.
mod := mctx.CreateVariations(coreMode, vendorMode)
vendor := mod[1].(*Module)
vendor.Properties.UseVndk = true
squashVendorSrcs(vendor)
} else if (mctx.SocSpecific() || mctx.DeviceSpecific()) && String(m.Properties.Sdk_version) == "" {
} else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
// This will be available in /vendor (or /odm) only
mod := mctx.CreateVariations(vendorMode)
vendor := mod[0].(*Module)

View File

@@ -22,6 +22,7 @@ import (
"io/ioutil"
"os"
"reflect"
"regexp"
"sort"
"strings"
"testing"
@@ -52,10 +53,7 @@ func TestMain(m *testing.M) {
os.Exit(run())
}
func testCc(t *testing.T, bp string) *android.TestContext {
config := android.TestArchConfig(buildDir, nil)
config.ProductVariables.DeviceVndkVersion = StringPtr("current")
func createTestContext(t *testing.T, config android.Config, bp string) *android.TestContext {
ctx := android.NewTestArchContext()
ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
@@ -142,6 +140,12 @@ func testCc(t *testing.T, bp string) *android.TestContext {
"my_include": nil,
})
return ctx
}
func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
ctx := createTestContext(t, config, bp)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
failIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
@@ -150,6 +154,48 @@ func testCc(t *testing.T, bp string) *android.TestContext {
return ctx
}
func testCc(t *testing.T, bp string) *android.TestContext {
config := android.TestArchConfig(buildDir, nil)
config.ProductVariables.DeviceVndkVersion = StringPtr("current")
config.ProductVariables.Platform_vndk_version = StringPtr("VER")
return testCcWithConfig(t, bp, config)
}
func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
config := android.TestArchConfig(buildDir, nil)
config.ProductVariables.Platform_vndk_version = StringPtr("VER")
return testCcWithConfig(t, bp, config)
}
func testCcError(t *testing.T, pattern string, bp string) {
config := android.TestArchConfig(buildDir, nil)
config.ProductVariables.DeviceVndkVersion = StringPtr("current")
config.ProductVariables.Platform_vndk_version = StringPtr("VER")
ctx := createTestContext(t, config, bp)
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
if len(errs) > 0 {
failIfNoMatchingErrors(t, pattern, errs)
return
}
_, errs = ctx.PrepareBuildActions(config)
if len(errs) > 0 {
failIfNoMatchingErrors(t, pattern, errs)
return
}
t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
}
const (
coreVariant = "android_arm64_armv8-a_core_shared"
vendorVariant = "android_arm64_armv8-a_vendor_shared"
)
func TestVendorSrc(t *testing.T) {
ctx := testCc(t, `
cc_library {
@@ -167,7 +213,7 @@ func TestVendorSrc(t *testing.T) {
}
`)
ld := ctx.ModuleForTests("libTest", "android_arm_armv7-a-neon_vendor_shared").Rule("ld")
ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
var objs []string
for _, o := range ld.Inputs {
objs = append(objs, o.Base())
@@ -177,6 +223,524 @@ func TestVendorSrc(t *testing.T) {
}
}
func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
isVndkSp bool, extends string) {
mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
if !mod.hasVendorVariant() {
t.Error("%q must have vendor variant", name)
}
// Check library properties.
lib, ok := mod.compiler.(*libraryDecorator)
if !ok {
t.Errorf("%q must have libraryDecorator", name)
} else if lib.baseInstaller.subDir != subDir {
t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
lib.baseInstaller.subDir)
}
// Check VNDK properties.
if mod.vndkdep == nil {
t.Fatalf("%q must have `vndkdep`", name)
}
if !mod.isVndk() {
t.Errorf("%q isVndk() must equal to true", name)
}
if mod.isVndkSp() != isVndkSp {
t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
}
// Check VNDK extension properties.
isVndkExt := extends != ""
if mod.isVndkExt() != isVndkExt {
t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
}
if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
}
}
func TestVndk(t *testing.T) {
ctx := testCc(t, `
cc_library {
name: "libvndk",
vendor_available: true,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_private",
vendor_available: false,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_sp",
vendor_available: true,
vndk: {
enabled: true,
support_system_process: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_sp_private",
vendor_available: false,
vndk: {
enabled: true,
support_system_process: true,
},
nocrt: true,
}
`)
checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
}
func TestVndkExt(t *testing.T) {
// This test checks the VNDK-Ext properties.
ctx := testCc(t, `
cc_library {
name: "libvndk",
vendor_available: true,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk",
},
nocrt: true,
}
`)
checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
}
func TestVndkExtNoVndk(t *testing.T) {
// This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
ctx := testCcNoVndk(t, `
cc_library {
name: "libvndk",
vendor_available: true,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk",
},
nocrt: true,
}
`)
// Ensures that the core variant of "libvndk_ext" can be found.
mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
}
}
func TestVndkExtError(t *testing.T) {
// This test ensures an error is emitted in ill-formed vndk-ext definition.
testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
cc_library {
name: "libvndk",
vendor_available: true,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_ext",
vndk: {
enabled: true,
extends: "libvndk",
},
nocrt: true,
}
`)
testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
cc_library {
name: "libvndk",
vendor_available: true,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_ext",
vendor: true,
vndk: {
enabled: true,
},
nocrt: true,
}
`)
}
func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
// This test ensures an error is emitted for inconsistent support_system_process.
testCcError(t, "module \".*\" with mismatched support_system_process", `
cc_library {
name: "libvndk",
vendor_available: true,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_sp_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk",
support_system_process: true,
},
nocrt: true,
}
`)
testCcError(t, "module \".*\" with mismatched support_system_process", `
cc_library {
name: "libvndk_sp",
vendor_available: true,
vndk: {
enabled: true,
support_system_process: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk_sp",
},
nocrt: true,
}
`)
}
func TestVndkExtVendorAvailableFalseError(t *testing.T) {
// This test ensures an error is emitted when a vndk-ext library extends a vndk library
// with `vendor_available: false`.
testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
cc_library {
name: "libvndk",
vendor_available: false,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk",
},
nocrt: true,
}
`)
}
func TestVendorModuleUsesVndkExt(t *testing.T) {
// This test ensures a vendor module can depend on a vndk-ext library.
testCc(t, `
cc_library {
name: "libvndk",
vendor_available: true,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk",
},
nocrt: true,
}
cc_library {
name: "libvndk_sp",
vendor_available: true,
vndk: {
enabled: true,
support_system_process: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_sp_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk_sp",
support_system_process: true,
},
nocrt: true,
}
cc_library {
name: "libvendor",
vendor: true,
shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
nocrt: true,
}
`)
}
func TestVndkExtUsesVendorLib(t *testing.T) {
// This test ensures a vndk-ext library can depend on a vendor library.
testCc(t, `
cc_library {
name: "libvndk",
vendor_available: true,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk",
},
shared_libs: ["libvendor"],
nocrt: true,
}
cc_library {
name: "libvendor",
vendor: true,
nocrt: true,
}
`)
}
func TestVndkSpExtUsesVendorLibError(t *testing.T) {
// This test ensures an error is emitted if a vndk-sp-ext library depends on a vendor
// library.
testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
cc_library {
name: "libvndk_sp",
vendor_available: true,
vndk: {
enabled: true,
support_system_process: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_sp_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk_sp",
support_system_process: true,
},
shared_libs: ["libvendor"], // Cause an error
nocrt: true,
}
cc_library {
name: "libvendor",
vendor: true,
nocrt: true,
}
`)
}
func TestVndkUsesVndkExtError(t *testing.T) {
// This test ensures an error is emitted if a vndk/vndk-sp library depends on a
// vndk-ext/vndk-sp-ext library.
testCcError(t, "dependency \".*\" of \".*\" missing variant", `
cc_library {
name: "libvndk",
vendor_available: true,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk",
},
nocrt: true,
}
cc_library {
name: "libvndk2",
vendor_available: true,
vndk: {
enabled: true,
},
shared_libs: ["libvndk_ext"],
nocrt: true,
}
`)
// The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
// but target.vendor.shared_libs has not been supported yet.
testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
cc_library {
name: "libvndk",
vendor_available: true,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk",
},
nocrt: true,
}
cc_library {
name: "libvndk2",
vendor_available: true,
vndk: {
enabled: true,
},
target: {
vendor: {
shared_libs: ["libvndk_ext"],
},
},
nocrt: true,
}
`)
testCcError(t, "dependency \".*\" of \".*\" missing variant", `
cc_library {
name: "libvndk_sp",
vendor_available: true,
vndk: {
enabled: true,
support_system_process: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_sp_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk_sp",
support_system_process: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_sp_2",
vendor_available: true,
vndk: {
enabled: true,
support_system_process: true,
},
shared_libs: ["libvndk_sp_ext"],
nocrt: true,
}
`)
// The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
// but target.vendor.shared_libs has not been supported yet.
testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
cc_library {
name: "libvndk_sp",
vendor_available: true,
vndk: {
enabled: true,
},
nocrt: true,
}
cc_library {
name: "libvndk_sp_ext",
vendor: true,
vndk: {
enabled: true,
extends: "libvndk_sp",
},
nocrt: true,
}
cc_library {
name: "libvndk_sp2",
vendor_available: true,
vndk: {
enabled: true,
},
target: {
vendor: {
shared_libs: ["libvndk_sp_ext"],
},
},
nocrt: true,
}
`)
}
var (
str11 = "01234567891"
str10 = str11[:10]
@@ -499,6 +1063,7 @@ func TestLinkReordering(t *testing.T) {
}
}
}
func failIfErrored(t *testing.T, errs []error) {
if len(errs) > 0 {
for _, err := range errs {
@@ -508,6 +1073,29 @@ func failIfErrored(t *testing.T, errs []error) {
}
}
func failIfNoMatchingErrors(t *testing.T, pattern string, errs []error) {
matcher, err := regexp.Compile(pattern)
if err != nil {
t.Errorf("failed to compile regular expression %q because %s", pattern, err)
}
found := false
for _, err := range errs {
if matcher.FindStringIndex(err.Error()) != nil {
found = true
break
}
}
if !found {
t.Errorf("missing the expected error %q (checked %d error(s))", pattern, len(errs))
for i, err := range errs {
t.Errorf("errs[%d] = %s", i, err)
}
}
}
func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
for _, moduleName := range moduleNames {
module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)

View File

@@ -416,6 +416,10 @@ func (library *libraryDecorator) getLibName(ctx ModuleContext) string {
name = ctx.baseModuleName()
}
if ctx.isVndkExt() {
name = ctx.getVndkExtendsModuleName()
}
if ctx.Host() && Bool(library.Properties.Unique_host_soname) {
if !strings.HasSuffix(name, "-host") {
name = name + "-host"
@@ -619,7 +623,12 @@ func (library *libraryDecorator) linkShared(ctx ModuleContext,
func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
//Also take into account object re-use.
if len(objs.sAbiDumpFiles) > 0 && ctx.createVndkSourceAbiDump() {
refSourceDumpFile := android.PathForVndkRefAbiDump(ctx, "current", fileName, vndkVsNdk(ctx), true)
vndkVersion := "current"
if ver := ctx.DeviceConfig().VndkVersion(); ver != "" {
vndkVersion = ver
}
refSourceDumpFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, vndkVsNdk(ctx), true)
exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
var SourceAbiFlags []string
for _, dir := range exportIncludeDirs.Strings() {
@@ -632,7 +641,8 @@ func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objec
library.sAbiOutputFile = TransformDumpToLinkedDump(ctx, objs.sAbiDumpFiles, soFile, fileName, exportedHeaderFlags)
if refSourceDumpFile.Valid() {
unzippedRefDump := UnzipRefDump(ctx, refSourceDumpFile.Path(), fileName)
library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(), unzippedRefDump, fileName, exportedHeaderFlags)
library.sAbiDiff = SourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
unzippedRefDump, fileName, exportedHeaderFlags, ctx.isVndkExt())
}
}
}
@@ -721,8 +731,13 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
} else if ctx.isVndk() {
library.baseInstaller.subDir = "vndk"
}
if ctx.isVndk() && ctx.DeviceConfig().PlatformVndkVersion() != "current" {
library.baseInstaller.subDir += "-" + ctx.DeviceConfig().PlatformVndkVersion()
// Append a version to vndk or vndk-sp directories on the system partition.
if ctx.isVndk() && !ctx.isVndkExt() {
vndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
if vndkVersion != "current" && vndkVersion != "" {
library.baseInstaller.subDir += "-" + vndkVersion
}
}
}
library.baseInstaller.install(ctx, file)

View File

@@ -42,6 +42,9 @@ type VndkProperties struct {
// the module is VNDK-core and can link to other VNDK-core,
// VNDK-SP or LL-NDK modules only.
Support_system_process *bool
// Extending another module
Extends *string
}
}
@@ -67,17 +70,31 @@ func (vndk *vndkdep) isVndkSp() bool {
return Bool(vndk.Properties.Vndk.Support_system_process)
}
func (vndk *vndkdep) isVndkExt() bool {
return vndk.Properties.Vndk.Extends != nil
}
func (vndk *vndkdep) getVndkExtendsModuleName() string {
return String(vndk.Properties.Vndk.Extends)
}
func (vndk *vndkdep) typeName() string {
if !vndk.isVndk() {
return "native:vendor"
}
if !vndk.isVndkExt() {
if !vndk.isVndkSp() {
return "native:vendor:vndk"
}
return "native:vendor:vndksp"
}
if !vndk.isVndkSp() {
return "native:vendor:vndkext"
}
return "native:vendor:vndkspext"
}
func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module) {
func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, tag dependencyTag) {
if to.linker == nil {
return
}
@@ -109,10 +126,42 @@ func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module) {
vndk.typeName(), to.Name())
return
}
if tag == vndkExtDepTag {
// Ensure `extends: "name"` property refers a vndk module that has vendor_available
// and has identical vndk properties.
if to.vndkdep == nil || !to.vndkdep.isVndk() {
ctx.ModuleErrorf("`extends` refers a non-vndk module %q", to.Name())
return
}
if vndk.isVndkSp() != to.vndkdep.isVndkSp() {
ctx.ModuleErrorf(
"`extends` refers a module %q with mismatched support_system_process",
to.Name())
return
}
if !Bool(to.VendorProperties.Vendor_available) {
ctx.ModuleErrorf(
"`extends` refers module %q which does not have `vendor_available: true`",
to.Name())
return
}
}
if to.vndkdep == nil {
return
}
if (vndk.isVndk() && !to.vndkdep.isVndk()) || (vndk.isVndkSp() && !to.vndkdep.isVndkSp()) {
// VNDK-core and VNDK-SP must not depend on VNDK extensions.
if (vndk.isVndk() || vndk.isVndkSp()) && !vndk.isVndkExt() && to.vndkdep.isVndkExt() {
ctx.ModuleErrorf("(%s) should not link to %q (%s)",
vndk.typeName(), to.Name(), to.vndkdep.typeName())
return
}
// VNDK-core must be only depend on VNDK-SP or LL-NDK. VNDK-SP must only depend on
// LL-NDK, regardless the extension status. VNDK-Ext may depend on vendor libraries, but
// VNDK-SP-Ext must remain self-contained.
if (vndk.isVndk() && !to.vndkdep.isVndk() && !vndk.isVndkExt()) ||
(vndk.isVndkSp() && !to.vndkdep.isVndkSp()) {
ctx.ModuleErrorf("(%s) should not link to %q (%s)",
vndk.typeName(), to.Name(), to.vndkdep.typeName())
return
@@ -149,7 +198,7 @@ func vndkMutator(mctx android.BottomUpMutatorContext) {
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() {
if m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() {
vndkLibrariesLock.Lock()
defer vndkLibrariesLock.Unlock()
if m.vndkdep.isVndkSp() {