Allow VNDK-SP extensions to use vendor lib
This commit changes the VNDK-SP dependencies check. With the commit,
VNDK-SP-Ext can link to non-VNDK vendor shared libs. This commit also
refines the "cc_test" so that more error handling cases are properly
tested.
Before this commit, VNDK-SP-Ext could not depend on vendor libs. It
was disallowed because there were no correct way to load vendor libs.
The fallback link had to specify the shared lib names. On the other
hand, adding "/vendor/${LIB}" to search paths will lead to
double-loading issue.
In aosp/595067, "allow_all_shared_libs" was added to bionic dynamic
linker. Now, we can link the "vndk" namespace to "sphal" namespace.
Thus, like VNDK-Ext, VNDK-SP-Ext can link to vendor libs now.
Bug: 77249955
Test: lunch aosp_walleye-userdebug && make -j8 # runs unit tests
Test: lunch aosp_sailfish-userdebug && make -j8 # runs unit tests
Test: Create a VNDK-SP-Ext, link to vendor libs, and run it.
Change-Id: I5511204539a22c998528111076f46756807faf29
Merged-In: I5511204539a22c998528111076f46756807faf29
(cherry picked from commit d3c59a2b3a
)
This commit is contained in:
parent
be6b6a63f8
commit
6010adbbbb
2 changed files with 227 additions and 24 deletions
214
cc/cc_test.go
214
cc/cc_test.go
|
@ -143,6 +143,7 @@ func createTestContext(t *testing.T, config android.Config, bp string) *android.
|
|||
}
|
||||
|
||||
func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
|
||||
t.Helper()
|
||||
ctx := createTestContext(t, config, bp)
|
||||
|
||||
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
|
||||
|
@ -154,6 +155,7 @@ func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.T
|
|||
}
|
||||
|
||||
func testCc(t *testing.T, bp string) *android.TestContext {
|
||||
t.Helper()
|
||||
config := android.TestArchConfig(buildDir, nil)
|
||||
config.ProductVariables.DeviceVndkVersion = StringPtr("current")
|
||||
config.ProductVariables.Platform_vndk_version = StringPtr("VER")
|
||||
|
@ -162,6 +164,7 @@ func testCc(t *testing.T, bp string) *android.TestContext {
|
|||
}
|
||||
|
||||
func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
|
||||
t.Helper()
|
||||
config := android.TestArchConfig(buildDir, nil)
|
||||
config.ProductVariables.Platform_vndk_version = StringPtr("VER")
|
||||
|
||||
|
@ -169,6 +172,7 @@ func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
|
|||
}
|
||||
|
||||
func testCcError(t *testing.T, pattern string, bp string) {
|
||||
t.Helper()
|
||||
config := android.TestArchConfig(buildDir, nil)
|
||||
config.ProductVariables.DeviceVndkVersion = StringPtr("current")
|
||||
config.ProductVariables.Platform_vndk_version = StringPtr("VER")
|
||||
|
@ -225,6 +229,8 @@ func TestVendorSrc(t *testing.T) {
|
|||
func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
|
||||
isVndkSp bool, extends string) {
|
||||
|
||||
t.Helper()
|
||||
|
||||
mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
|
||||
if !mod.hasVendorVariant() {
|
||||
t.Error("%q must have vendor variant", name)
|
||||
|
@ -308,6 +314,107 @@ func TestVndk(t *testing.T) {
|
|||
checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
|
||||
}
|
||||
|
||||
func TestVndkDepError(t *testing.T) {
|
||||
// Check whether an error is emitted when a VNDK lib depends on a system lib.
|
||||
testCcError(t, "dependency \".*\" of \".*\" missing variant", `
|
||||
cc_library {
|
||||
name: "libvndk",
|
||||
vendor_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
shared_libs: ["libfwk"], // Cause error
|
||||
nocrt: true,
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libfwk",
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
|
||||
// Check whether an error is emitted when a VNDK lib depends on a vendor lib.
|
||||
testCcError(t, "dependency \".*\" of \".*\" missing variant", `
|
||||
cc_library {
|
||||
name: "libvndk",
|
||||
vendor_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
shared_libs: ["libvendor"], // Cause error
|
||||
nocrt: true,
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libvendor",
|
||||
vendor: true,
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
|
||||
// Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
|
||||
testCcError(t, "dependency \".*\" of \".*\" missing variant", `
|
||||
cc_library {
|
||||
name: "libvndk_sp",
|
||||
vendor_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
support_system_process: true,
|
||||
},
|
||||
shared_libs: ["libfwk"], // Cause error
|
||||
nocrt: true,
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libfwk",
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
|
||||
// Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
|
||||
testCcError(t, "dependency \".*\" of \".*\" missing variant", `
|
||||
cc_library {
|
||||
name: "libvndk_sp",
|
||||
vendor_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
support_system_process: true,
|
||||
},
|
||||
shared_libs: ["libvendor"], // Cause error
|
||||
nocrt: true,
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libvendor",
|
||||
vendor: true,
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
|
||||
// Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
|
||||
testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
|
||||
cc_library {
|
||||
name: "libvndk_sp",
|
||||
vendor_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
support_system_process: true,
|
||||
},
|
||||
shared_libs: ["libvndk"], // Cause error
|
||||
nocrt: true,
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libvndk",
|
||||
vendor_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
||||
func TestVndkExt(t *testing.T) {
|
||||
// This test checks the VNDK-Ext properties.
|
||||
ctx := testCc(t, `
|
||||
|
@ -334,7 +441,7 @@ func TestVndkExt(t *testing.T) {
|
|||
checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
|
||||
}
|
||||
|
||||
func TestVndkExtNoVndk(t *testing.T) {
|
||||
func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
|
||||
// This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
|
||||
ctx := testCcNoVndk(t, `
|
||||
cc_library {
|
||||
|
@ -455,7 +562,7 @@ func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestVndkExtVendorAvailableFalseError(t *testing.T) {
|
||||
// This test ensures an error is emitted when a vndk-ext library extends a vndk library
|
||||
// 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 {
|
||||
|
@ -479,8 +586,8 @@ func TestVndkExtVendorAvailableFalseError(t *testing.T) {
|
|||
`)
|
||||
}
|
||||
|
||||
func TestVendorModuleUsesVndkExt(t *testing.T) {
|
||||
// This test ensures a vendor module can depend on a vndk-ext library.
|
||||
func TestVendorModuleUseVndkExt(t *testing.T) {
|
||||
// This test ensures a vendor module can depend on a VNDK-Ext library.
|
||||
testCc(t, `
|
||||
cc_library {
|
||||
name: "libvndk",
|
||||
|
@ -532,8 +639,8 @@ func TestVendorModuleUsesVndkExt(t *testing.T) {
|
|||
`)
|
||||
}
|
||||
|
||||
func TestVndkExtUsesVendorLib(t *testing.T) {
|
||||
// This test ensures a vndk-ext library can depend on a vendor library.
|
||||
func TestVndkExtUseVendorLib(t *testing.T) {
|
||||
// This test ensures a VNDK-Ext library can depend on a vendor library.
|
||||
testCc(t, `
|
||||
cc_library {
|
||||
name: "libvndk",
|
||||
|
@ -561,12 +668,9 @@ func TestVndkExtUsesVendorLib(t *testing.T) {
|
|||
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 \".*\"", `
|
||||
// This test ensures a VNDK-SP-Ext library can depend on a vendor library.
|
||||
testCc(t, `
|
||||
cc_library {
|
||||
name: "libvndk_sp",
|
||||
vendor_available: true,
|
||||
|
@ -597,9 +701,91 @@ func TestVndkSpExtUsesVendorLibError(t *testing.T) {
|
|||
`)
|
||||
}
|
||||
|
||||
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.
|
||||
func TestVndkSpExtUseVndkError(t *testing.T) {
|
||||
// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
|
||||
// library.
|
||||
testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
|
||||
cc_library {
|
||||
name: "libvndk",
|
||||
vendor_available: true,
|
||||
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_ext",
|
||||
vendor: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
extends: "libvndk_sp",
|
||||
support_system_process: true,
|
||||
},
|
||||
shared_libs: ["libvndk"], // Cause an error
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
|
||||
// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
|
||||
// library.
|
||||
testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
|
||||
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,
|
||||
},
|
||||
shared_libs: ["libvndk_ext"], // Cause an error
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
||||
func TestVndkUseVndkExtError(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",
|
||||
|
|
37
cc/vndk.go
37
cc/vndk.go
|
@ -150,22 +150,39 @@ func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, ta
|
|||
return
|
||||
}
|
||||
|
||||
// VNDK-core and VNDK-SP must not depend on VNDK extensions.
|
||||
if (vndk.isVndk() || vndk.isVndkSp()) && !vndk.isVndkExt() && to.vndkdep.isVndkExt() {
|
||||
// Check the dependencies of VNDK shared libraries.
|
||||
if !vndkIsVndkDepAllowed(vndk, to.vndkdep) {
|
||||
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
|
||||
func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) bool {
|
||||
// Check the dependencies of VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext and vendor modules.
|
||||
if from.isVndkExt() {
|
||||
if from.isVndkSp() {
|
||||
// VNDK-SP-Ext may depend on VNDK-SP, VNDK-SP-Ext, or vendor libs (excluding
|
||||
// VNDK and VNDK-Ext).
|
||||
return to.isVndkSp() || !to.isVndk()
|
||||
}
|
||||
// VNDK-Ext may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
|
||||
return true
|
||||
}
|
||||
if from.isVndk() {
|
||||
if to.isVndkExt() {
|
||||
// VNDK-core and VNDK-SP must not depend on VNDK extensions.
|
||||
return false
|
||||
}
|
||||
if from.isVndkSp() {
|
||||
// VNDK-SP must only depend on VNDK-SP.
|
||||
return to.isVndkSp()
|
||||
}
|
||||
// VNDK-core may depend on VNDK-core or VNDK-SP.
|
||||
return to.isVndk()
|
||||
}
|
||||
// Vendor modules may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs.
|
||||
return true
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
Loading…
Reference in a new issue