Merge changes I81769f57,I28fb6886
* changes: Define vndk.private property for VNDK-private libraries 'vendor_available: *' will not create product variant
This commit is contained in:
44
cc/cc.go
44
cc/cc.go
@@ -360,7 +360,11 @@ type VendorProperties struct {
|
||||
//
|
||||
// If set to false, this module becomes inaccessible from /vendor modules.
|
||||
//
|
||||
// Default value is true when vndk: {enabled: true} or vendor: true.
|
||||
// The modules with vndk: {enabled: true} must define 'vendor_available'
|
||||
// to either 'true' or 'false'. In this case, 'vendor_available: false' has
|
||||
// a different meaning than that of non-VNDK modules.
|
||||
// 'vendor_available: false' for a VNDK module means 'VNDK-private' that
|
||||
// can only be depended on by VNDK libraries, not by non-VNDK vendor modules.
|
||||
//
|
||||
// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
|
||||
Vendor_available *bool
|
||||
@@ -376,7 +380,19 @@ type VendorProperties struct {
|
||||
// make assumptions about the system that may not be true in the
|
||||
// future.
|
||||
//
|
||||
// It must be set to true by default for vndk: {enabled: true} modules.
|
||||
// If set to false, this module becomes inaccessible from /product modules.
|
||||
//
|
||||
// Different from the 'vendor_available' property, the modules with
|
||||
// vndk: {enabled: true} don't have to define 'product_available'. The VNDK
|
||||
// library without 'product_available' may not be depended on by any other
|
||||
// modules that has product variants including the product available VNDKs.
|
||||
// However, for the modules with vndk: {enabled: true},
|
||||
// 'product_available: false' creates the product variant that is available
|
||||
// only for the other product available VNDK modules but not by non-VNDK
|
||||
// product modules.
|
||||
// In the case of the modules with vndk: {enabled: true}, if
|
||||
// 'product_available' is defined, it must have the same value with the
|
||||
// 'vendor_available'.
|
||||
//
|
||||
// Nothing happens if BOARD_VNDK_VERSION isn't set in the BoardConfig.mk
|
||||
// and PRODUCT_PRODUCT_VNDK_VERSION isn't set.
|
||||
@@ -1060,11 +1076,27 @@ func (c *Module) isImplementationForLLNDKPublic() bool {
|
||||
c.BaseModuleName() != "libft2")
|
||||
}
|
||||
|
||||
// Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private.
|
||||
func (c *Module) IsVndkPrivate() bool {
|
||||
// Returns true for LLNDK-private, VNDK-SP-private, and VNDK-core-private.
|
||||
library, _ := c.library.(*libraryDecorator)
|
||||
return library != nil && !Bool(library.Properties.Llndk.Vendor_available) &&
|
||||
!Bool(c.VendorProperties.Vendor_available) && !c.IsVndkExt()
|
||||
// Check if VNDK-core-private or VNDK-SP-private
|
||||
if c.IsVndk() {
|
||||
if Bool(c.vndkdep.Properties.Vndk.Private) {
|
||||
return true
|
||||
}
|
||||
// TODO(b/175768895) remove this when we clean up "vendor_available: false" use cases.
|
||||
if c.VendorProperties.Vendor_available != nil && !Bool(c.VendorProperties.Vendor_available) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if LLNDK-private
|
||||
if library, ok := c.library.(*libraryDecorator); ok && c.IsLlndk() {
|
||||
// TODO(b/175768895) replace this with 'private' property.
|
||||
return !Bool(library.Properties.Llndk.Vendor_available)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Module) IsVndk() bool {
|
||||
|
192
cc/cc_test.go
192
cc/cc_test.go
@@ -326,7 +326,6 @@ func TestVndk(t *testing.T) {
|
||||
cc_library {
|
||||
name: "libvndk",
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
@@ -335,19 +334,36 @@ func TestVndk(t *testing.T) {
|
||||
|
||||
cc_library {
|
||||
name: "libvndk_private",
|
||||
vendor_available: false,
|
||||
product_available: false,
|
||||
vendor_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
private: true,
|
||||
},
|
||||
nocrt: true,
|
||||
stem: "libvndk-private",
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libvndk_sp",
|
||||
name: "libvndk_product",
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
nocrt: true,
|
||||
target: {
|
||||
vendor: {
|
||||
cflags: ["-DTEST"],
|
||||
},
|
||||
product: {
|
||||
cflags: ["-DTEST"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libvndk_sp",
|
||||
vendor_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
support_system_process: true,
|
||||
@@ -358,11 +374,11 @@ func TestVndk(t *testing.T) {
|
||||
|
||||
cc_library {
|
||||
name: "libvndk_sp_private",
|
||||
vendor_available: false,
|
||||
product_available: false,
|
||||
vendor_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
support_system_process: true,
|
||||
private: true,
|
||||
},
|
||||
nocrt: true,
|
||||
target: {
|
||||
@@ -371,6 +387,27 @@ func TestVndk(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libvndk_sp_product_private",
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
support_system_process: true,
|
||||
private: true,
|
||||
},
|
||||
nocrt: true,
|
||||
target: {
|
||||
vendor: {
|
||||
suffix: "-x",
|
||||
},
|
||||
product: {
|
||||
suffix: "-x",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
vndk_libraries_txt {
|
||||
name: "llndk.libraries.txt",
|
||||
}
|
||||
@@ -399,13 +436,13 @@ func TestVndk(t *testing.T) {
|
||||
// They are installed as part of VNDK APEX instead.
|
||||
checkVndkModule(t, ctx, "libvndk", "", false, "", vendorVariant)
|
||||
checkVndkModule(t, ctx, "libvndk_private", "", false, "", vendorVariant)
|
||||
checkVndkModule(t, ctx, "libvndk_product", "", false, "", vendorVariant)
|
||||
checkVndkModule(t, ctx, "libvndk_sp", "", true, "", vendorVariant)
|
||||
checkVndkModule(t, ctx, "libvndk_sp_private", "", true, "", vendorVariant)
|
||||
checkVndkModule(t, ctx, "libvndk_sp_product_private", "", true, "", vendorVariant)
|
||||
|
||||
checkVndkModule(t, ctx, "libvndk", "", false, "", productVariant)
|
||||
checkVndkModule(t, ctx, "libvndk_private", "", false, "", productVariant)
|
||||
checkVndkModule(t, ctx, "libvndk_sp", "", true, "", productVariant)
|
||||
checkVndkModule(t, ctx, "libvndk_sp_private", "", true, "", productVariant)
|
||||
checkVndkModule(t, ctx, "libvndk_product", "", false, "", productVariant)
|
||||
checkVndkModule(t, ctx, "libvndk_sp_product_private", "", true, "", productVariant)
|
||||
|
||||
// Check VNDK snapshot output.
|
||||
|
||||
@@ -429,6 +466,8 @@ func TestVndk(t *testing.T) {
|
||||
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLibPath, variant)
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLib2ndPath, variant2nd)
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLibPath, variant)
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLib2ndPath, variant2nd)
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLibPath, variant)
|
||||
checkSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLib2ndPath, variant2nd)
|
||||
|
||||
@@ -446,16 +485,19 @@ func TestVndk(t *testing.T) {
|
||||
"VNDK-SP: libc++.so",
|
||||
"VNDK-SP: libvndk_sp-x.so",
|
||||
"VNDK-SP: libvndk_sp_private-x.so",
|
||||
"VNDK-SP: libvndk_sp_product_private-x.so",
|
||||
"VNDK-core: libvndk-private.so",
|
||||
"VNDK-core: libvndk.so",
|
||||
"VNDK-core: libvndk_product.so",
|
||||
"VNDK-private: libft2.so",
|
||||
"VNDK-private: libvndk-private.so",
|
||||
"VNDK-private: libvndk_sp_private-x.so",
|
||||
"VNDK-private: libvndk_sp_product_private-x.so",
|
||||
})
|
||||
checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt", []string{"libc.so", "libdl.so", "libft2.so", "libm.so"})
|
||||
checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk-private.so", "libvndk.so"})
|
||||
checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt", []string{"libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so"})
|
||||
checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so"})
|
||||
checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk-private.so", "libvndk.so", "libvndk_product.so"})
|
||||
checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so", "libvndk_sp_product_private-x.so"})
|
||||
checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt", []string{"libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so", "libvndk_sp_product_private-x.so"})
|
||||
checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", nil)
|
||||
}
|
||||
|
||||
@@ -535,10 +577,11 @@ func TestVndkUsingCoreVariant(t *testing.T) {
|
||||
|
||||
cc_library {
|
||||
name: "libvndk2",
|
||||
vendor_available: false,
|
||||
product_available: false,
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
private: true,
|
||||
},
|
||||
nocrt: true,
|
||||
}
|
||||
@@ -683,17 +726,43 @@ func TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
|
||||
|
||||
func TestVndkModuleError(t *testing.T) {
|
||||
// Check the error message for vendor_available and product_available properties.
|
||||
testCcError(t, "product_available: may not have different value than `vendor_available`", `
|
||||
testCcErrorProductVndk(t, "vndk: vendor_available must be set to either true or false when `vndk: {enabled: true}`", `
|
||||
cc_library {
|
||||
name: "libvndk",
|
||||
vendor_available: true,
|
||||
product_available: false,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
|
||||
testCcErrorProductVndk(t, "vndk: vendor_available must be set to either true or false when `vndk: {enabled: true}`", `
|
||||
cc_library {
|
||||
name: "libvndk",
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
|
||||
testCcErrorProductVndk(t, "product properties must have the same values with the vendor properties for VNDK modules", `
|
||||
cc_library {
|
||||
name: "libvndkprop",
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
nocrt: true,
|
||||
target: {
|
||||
vendor: {
|
||||
cflags: ["-DTEST",],
|
||||
},
|
||||
},
|
||||
}
|
||||
`)
|
||||
}
|
||||
|
||||
func TestVndkDepError(t *testing.T) {
|
||||
@@ -826,10 +895,11 @@ func TestVndkDepError(t *testing.T) {
|
||||
testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
|
||||
cc_library {
|
||||
name: "libvndkprivate",
|
||||
vendor_available: false,
|
||||
product_available: false,
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
private: true,
|
||||
},
|
||||
shared_libs: ["libnonvndk"],
|
||||
nocrt: true,
|
||||
@@ -867,11 +937,12 @@ func TestVndkDepError(t *testing.T) {
|
||||
testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
|
||||
cc_library {
|
||||
name: "libvndkspprivate",
|
||||
vendor_available: false,
|
||||
product_available: false,
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
support_system_process: true,
|
||||
private: true,
|
||||
},
|
||||
shared_libs: ["libnonvndk"],
|
||||
nocrt: true,
|
||||
@@ -962,10 +1033,11 @@ func TestDoubleLoadbleDep(t *testing.T) {
|
||||
|
||||
cc_library {
|
||||
name: "libnondoubleloadable",
|
||||
vendor_available: false,
|
||||
product_available: false,
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
private: true,
|
||||
},
|
||||
double_loadable: true,
|
||||
}
|
||||
@@ -1831,10 +1903,11 @@ func TestDoubleLoadableDepError(t *testing.T) {
|
||||
|
||||
cc_library {
|
||||
name: "libnondoubleloadable",
|
||||
vendor_available: false,
|
||||
product_available: false,
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
private: true,
|
||||
},
|
||||
}
|
||||
`)
|
||||
@@ -2185,14 +2258,15 @@ 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
|
||||
// with `vendor_available: false`.
|
||||
testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
|
||||
// with `private: true`.
|
||||
testCcError(t, "`extends` refers module \".*\" which has `private: true`", `
|
||||
cc_library {
|
||||
name: "libvndk",
|
||||
vendor_available: false,
|
||||
product_available: false,
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
private: true,
|
||||
},
|
||||
nocrt: true,
|
||||
}
|
||||
@@ -2208,13 +2282,14 @@ func TestVndkExtVendorAvailableFalseError(t *testing.T) {
|
||||
}
|
||||
`)
|
||||
|
||||
testCcErrorProductVndk(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
|
||||
testCcErrorProductVndk(t, "`extends` refers module \".*\" which has `private: true`", `
|
||||
cc_library {
|
||||
name: "libvndk",
|
||||
vendor_available: false,
|
||||
product_available: false,
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
private: true,
|
||||
},
|
||||
nocrt: true,
|
||||
}
|
||||
@@ -2562,7 +2637,6 @@ func TestVndkUseVndkExtError(t *testing.T) {
|
||||
cc_library {
|
||||
name: "libvndk2",
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
@@ -2635,7 +2709,6 @@ func TestVndkUseVndkExtError(t *testing.T) {
|
||||
cc_library {
|
||||
name: "libvndk_sp2",
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
@@ -2688,6 +2761,20 @@ func TestEnforceProductVndkVersion(t *testing.T) {
|
||||
product_available: true,
|
||||
nocrt: true,
|
||||
}
|
||||
cc_library {
|
||||
name: "libboth_available",
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
nocrt: true,
|
||||
target: {
|
||||
vendor: {
|
||||
suffix: "-vendor",
|
||||
},
|
||||
product: {
|
||||
suffix: "-product",
|
||||
},
|
||||
}
|
||||
}
|
||||
cc_library {
|
||||
name: "libproduct_va",
|
||||
product_specific: true,
|
||||
@@ -2702,6 +2789,7 @@ func TestEnforceProductVndkVersion(t *testing.T) {
|
||||
"libvndk",
|
||||
"libvndk_sp",
|
||||
"libpa",
|
||||
"libboth_available",
|
||||
"libproduct_va",
|
||||
],
|
||||
nocrt: true,
|
||||
@@ -2714,6 +2802,7 @@ func TestEnforceProductVndkVersion(t *testing.T) {
|
||||
"libvndk",
|
||||
"libvndk_sp",
|
||||
"libva",
|
||||
"libboth_available",
|
||||
"libproduct_va",
|
||||
],
|
||||
nocrt: true,
|
||||
@@ -2729,6 +2818,12 @@ func TestEnforceProductVndkVersion(t *testing.T) {
|
||||
|
||||
checkVndkModule(t, ctx, "libvndk", "", false, "", productVariant)
|
||||
checkVndkModule(t, ctx, "libvndk_sp", "", true, "", productVariant)
|
||||
|
||||
mod_vendor := ctx.ModuleForTests("libboth_available", vendorVariant).Module().(*Module)
|
||||
assertString(t, mod_vendor.outputFile.Path().Base(), "libboth_available-vendor.so")
|
||||
|
||||
mod_product := ctx.ModuleForTests("libboth_available", productVariant).Module().(*Module)
|
||||
assertString(t, mod_product.outputFile.Path().Base(), "libboth_available-product.so")
|
||||
}
|
||||
|
||||
func TestEnforceProductVndkVersionErrors(t *testing.T) {
|
||||
@@ -2761,7 +2856,22 @@ func TestEnforceProductVndkVersionErrors(t *testing.T) {
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
testCcErrorProductVndk(t, "Vendor module that is not VNDK should not link to \".*\" which is marked as `vendor_available: false`", `
|
||||
testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.VER", `
|
||||
cc_library {
|
||||
name: "libprod",
|
||||
product_specific: true,
|
||||
shared_libs: [
|
||||
"libva",
|
||||
],
|
||||
nocrt: true,
|
||||
}
|
||||
cc_library {
|
||||
name: "libva",
|
||||
vendor_available: true,
|
||||
nocrt: true,
|
||||
}
|
||||
`)
|
||||
testCcErrorProductVndk(t, "non-VNDK module should not link to \".*\" which has `private: true`", `
|
||||
cc_library {
|
||||
name: "libprod",
|
||||
product_specific: true,
|
||||
@@ -2772,10 +2882,11 @@ func TestEnforceProductVndkVersionErrors(t *testing.T) {
|
||||
}
|
||||
cc_library {
|
||||
name: "libvndk_private",
|
||||
vendor_available: false,
|
||||
product_available: false,
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
private: true,
|
||||
},
|
||||
nocrt: true,
|
||||
}
|
||||
@@ -2833,10 +2944,11 @@ func TestMakeLinkType(t *testing.T) {
|
||||
}
|
||||
cc_library {
|
||||
name: "libvndkprivate",
|
||||
vendor_available: false,
|
||||
product_available: false,
|
||||
vendor_available: true,
|
||||
product_available: true,
|
||||
vndk: {
|
||||
enabled: true,
|
||||
private: true,
|
||||
},
|
||||
}
|
||||
cc_library {
|
||||
|
@@ -479,8 +479,7 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps
|
||||
}
|
||||
|
||||
if ctx.inProduct() {
|
||||
// TODO(b/150902910): must use 'compiler.Properties.Target.Product.Cflags'
|
||||
flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Vendor.Cflags)...)
|
||||
flags.Local.CFlags = append(flags.Local.CFlags, esc(compiler.Properties.Target.Product.Cflags)...)
|
||||
}
|
||||
|
||||
if ctx.inRecovery() {
|
||||
|
@@ -101,8 +101,7 @@ func (g *GenruleExtraProperties) ExtraImageVariations(ctx android.BaseModuleCont
|
||||
return variants
|
||||
}
|
||||
|
||||
// TODO(b/150902910): vendor_available will not create product variant. Remove Bool(g.Vendor_available)
|
||||
if Bool(g.Vendor_available) || Bool(g.Product_available) || ctx.ProductSpecific() {
|
||||
if Bool(g.Product_available) || ctx.ProductSpecific() {
|
||||
variants = append(variants, ProductVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion())
|
||||
if vndkVersion := ctx.DeviceConfig().ProductVndkVersion(); vndkVersion != "current" {
|
||||
variants = append(variants, ProductVariationPrefix+vndkVersion)
|
||||
|
89
cc/image.go
89
cc/image.go
@@ -17,6 +17,8 @@ package cc
|
||||
// functions to determine where a module is installed, etc.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"android/soong/android"
|
||||
@@ -97,17 +99,23 @@ func (ctx *moduleContextImpl) inRecovery() bool {
|
||||
|
||||
// Returns true when this module is configured to have core and vendor variants.
|
||||
func (c *Module) HasVendorVariant() bool {
|
||||
// In case of a VNDK, 'vendor_available: false' still creates a vendor variant.
|
||||
return c.IsVndk() || Bool(c.VendorProperties.Vendor_available)
|
||||
}
|
||||
|
||||
// Returns true when this module is configured to have core and product variants.
|
||||
func (c *Module) HasProductVariant() bool {
|
||||
if c.VendorProperties.Product_available == nil {
|
||||
// Without 'product_available', product variant will not be created even for VNDKs.
|
||||
return false
|
||||
}
|
||||
// However, 'product_available: false' in a VNDK still creates a product variant.
|
||||
return c.IsVndk() || Bool(c.VendorProperties.Product_available)
|
||||
}
|
||||
|
||||
// Returns true when this module is configured to have core and either product or vendor variants.
|
||||
func (c *Module) HasNonSystemVariants() bool {
|
||||
return c.IsVndk() || Bool(c.VendorProperties.Vendor_available) || Bool(c.VendorProperties.Product_available)
|
||||
return c.HasVendorVariant() || c.HasProductVariant()
|
||||
}
|
||||
|
||||
// Returns true if the module is "product" variant. Usually these modules are installed in /product
|
||||
@@ -144,6 +152,52 @@ func (c *Module) OnlyInRecovery() bool {
|
||||
return c.ModuleBase.InstallInRecovery()
|
||||
}
|
||||
|
||||
func visitPropsAndCompareVendorAndProductProps(v reflect.Value) bool {
|
||||
if v.Kind() != reflect.Struct {
|
||||
return true
|
||||
}
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
prop := v.Field(i)
|
||||
if prop.Kind() == reflect.Struct && v.Type().Field(i).Name == "Target" {
|
||||
vendor_prop := prop.FieldByName("Vendor")
|
||||
product_prop := prop.FieldByName("Product")
|
||||
if vendor_prop.Kind() != reflect.Struct && product_prop.Kind() != reflect.Struct {
|
||||
// Neither Target.Vendor nor Target.Product is defined
|
||||
continue
|
||||
}
|
||||
if vendor_prop.Kind() != reflect.Struct || product_prop.Kind() != reflect.Struct ||
|
||||
!reflect.DeepEqual(vendor_prop.Interface(), product_prop.Interface()) {
|
||||
// If only one of either Target.Vendor or Target.Product is
|
||||
// defined or they have different values, it fails the build
|
||||
// since VNDK must have the same properties for both vendor
|
||||
// and product variants.
|
||||
return false
|
||||
}
|
||||
} else if !visitPropsAndCompareVendorAndProductProps(prop) {
|
||||
// Visit the substructures to find Target.Vendor and Target.Product
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// In the case of VNDK, vendor and product variants must have the same properties.
|
||||
// VNDK installs only one file and shares it for both vendor and product modules on
|
||||
// runtime. We may not define different versions of a VNDK lib for each partition.
|
||||
// This function is used only for the VNDK modules that is available to both vendor
|
||||
// and product partitions.
|
||||
func (c *Module) compareVendorAndProductProps() bool {
|
||||
if !c.IsVndk() && c.VendorProperties.Product_available != nil {
|
||||
panic(fmt.Errorf("This is only for product available VNDK libs. %q is not a VNDK library or not product available", c.Name()))
|
||||
}
|
||||
for _, properties := range c.GetProperties() {
|
||||
if !visitPropsAndCompareVendorAndProductProps(reflect.ValueOf(properties).Elem()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
|
||||
// Validation check
|
||||
vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific()
|
||||
@@ -154,14 +208,6 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
|
||||
mctx.PropertyErrorf("vendor_available",
|
||||
"doesn't make sense at the same time as `vendor: true`, `proprietary: true`, or `device_specific:true`")
|
||||
}
|
||||
// If defined, make sure vendor_available and product_available has the
|
||||
// same value since `false` for these properties means the module is
|
||||
// for system only but provides the variant.
|
||||
if m.VendorProperties.Product_available != nil {
|
||||
if Bool(m.VendorProperties.Vendor_available) != Bool(m.VendorProperties.Product_available) {
|
||||
mctx.PropertyErrorf("product_available", "may not have different value than `vendor_available`")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if m.VendorProperties.Product_available != nil {
|
||||
@@ -198,6 +244,14 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
|
||||
mctx.PropertyErrorf("vndk",
|
||||
"vendor_available must be set to either true or false when `vndk: {enabled: true}`")
|
||||
}
|
||||
if m.VendorProperties.Product_available != nil {
|
||||
// If a VNDK module creates both product and vendor variants, they
|
||||
// must have the same properties since they share a single VNDK
|
||||
// library on runtime.
|
||||
if !m.compareVendorAndProductProps() {
|
||||
mctx.ModuleErrorf("product properties must have the same values with the vendor properties for VNDK modules")
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if vndkdep.isVndkSp() {
|
||||
@@ -281,13 +335,13 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) {
|
||||
}
|
||||
}
|
||||
|
||||
// vendor_available modules are also available to /product.
|
||||
// TODO(b/150902910): product variant will be created only if
|
||||
// m.HasProductVariant() is true.
|
||||
productVariants = append(productVariants, platformVndkVersion)
|
||||
// VNDK is always PLATFORM_VNDK_VERSION
|
||||
if !m.IsVndk() {
|
||||
productVariants = append(productVariants, productVndkVersion)
|
||||
// product_available modules are available to /product.
|
||||
if m.HasProductVariant() {
|
||||
productVariants = append(productVariants, platformVndkVersion)
|
||||
// VNDK is always PLATFORM_VNDK_VERSION
|
||||
if !m.IsVndk() {
|
||||
productVariants = append(productVariants, productVndkVersion)
|
||||
}
|
||||
}
|
||||
} else if vendorSpecific && String(m.Properties.Sdk_version) == "" {
|
||||
// This will be available in /vendor (or /odm) only
|
||||
@@ -471,7 +525,6 @@ func (c *Module) SetImageVariation(ctx android.BaseModuleContext, variant string
|
||||
} else if strings.HasPrefix(variant, ProductVariationPrefix) {
|
||||
m.Properties.ImageVariationPrefix = ProductVariationPrefix
|
||||
m.Properties.VndkVersion = strings.TrimPrefix(variant, ProductVariationPrefix)
|
||||
// TODO (b/150902910): This will be replaced with squashProductSrcs(m).
|
||||
squashVendorSrcs(m)
|
||||
squashProductSrcs(m)
|
||||
}
|
||||
}
|
||||
|
@@ -275,12 +275,13 @@ type flagExporter struct {
|
||||
// any module that links against this module. This is obtained from
|
||||
// the export_include_dirs property in the appropriate target stanza.
|
||||
func (f *flagExporter) exportedIncludes(ctx ModuleContext) android.Paths {
|
||||
// TODO(b/150902910): product variant must use Target.Product
|
||||
if ctx.useVndk() && f.Properties.Target.Vendor.Override_export_include_dirs != nil {
|
||||
if ctx.inVendor() && f.Properties.Target.Vendor.Override_export_include_dirs != nil {
|
||||
return android.PathsForModuleSrc(ctx, f.Properties.Target.Vendor.Override_export_include_dirs)
|
||||
} else {
|
||||
return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
|
||||
}
|
||||
if ctx.inProduct() && f.Properties.Target.Product.Override_export_include_dirs != nil {
|
||||
return android.PathsForModuleSrc(ctx, f.Properties.Target.Product.Override_export_include_dirs)
|
||||
}
|
||||
return android.PathsForModuleSrc(ctx, f.Properties.Export_include_dirs)
|
||||
}
|
||||
|
||||
// exportIncludes registers the include directories and system include directories to be exported
|
||||
@@ -726,7 +727,7 @@ type versionedInterface interface {
|
||||
var _ libraryInterface = (*libraryDecorator)(nil)
|
||||
var _ versionedInterface = (*libraryDecorator)(nil)
|
||||
|
||||
func (library *libraryDecorator) getLibNameHelper(baseModuleName string, useVndk bool) string {
|
||||
func (library *libraryDecorator) getLibNameHelper(baseModuleName string, inVendor bool, inProduct bool) string {
|
||||
name := library.libName
|
||||
if name == "" {
|
||||
name = String(library.Properties.Stem)
|
||||
@@ -736,9 +737,10 @@ func (library *libraryDecorator) getLibNameHelper(baseModuleName string, useVndk
|
||||
}
|
||||
|
||||
suffix := ""
|
||||
if useVndk {
|
||||
// TODO(b/150902910): product variant must use Target.Product
|
||||
if inVendor {
|
||||
suffix = String(library.Properties.Target.Vendor.Suffix)
|
||||
} else if inProduct {
|
||||
suffix = String(library.Properties.Target.Product.Suffix)
|
||||
}
|
||||
if suffix == "" {
|
||||
suffix = String(library.Properties.Suffix)
|
||||
@@ -750,7 +752,7 @@ func (library *libraryDecorator) getLibNameHelper(baseModuleName string, useVndk
|
||||
// getLibName returns the actual canonical name of the library (the name which
|
||||
// should be passed to the linker via linker flags).
|
||||
func (library *libraryDecorator) getLibName(ctx BaseModuleContext) string {
|
||||
name := library.getLibNameHelper(ctx.baseModuleName(), ctx.useVndk())
|
||||
name := library.getLibNameHelper(ctx.baseModuleName(), ctx.inVendor(), ctx.inProduct())
|
||||
|
||||
if ctx.IsVndkExt() {
|
||||
// vndk-ext lib should have the same name with original lib
|
||||
@@ -851,14 +853,20 @@ func (library *libraryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
||||
deps.ReexportSharedLibHeaders = append(deps.ReexportSharedLibHeaders, library.SharedProperties.Shared.Export_shared_lib_headers...)
|
||||
deps.ReexportStaticLibHeaders = append(deps.ReexportStaticLibHeaders, library.SharedProperties.Shared.Export_static_lib_headers...)
|
||||
}
|
||||
// TODO(b/150902910): product variant must use Target.Product
|
||||
if ctx.useVndk() {
|
||||
if ctx.inVendor() {
|
||||
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
|
||||
deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs)
|
||||
deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
|
||||
deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_shared_libs)
|
||||
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Vendor.Exclude_static_libs)
|
||||
}
|
||||
if ctx.inProduct() {
|
||||
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Product.Exclude_static_libs)
|
||||
deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Product.Exclude_shared_libs)
|
||||
deps.StaticLibs = removeListFromList(deps.StaticLibs, library.baseLinker.Properties.Target.Product.Exclude_static_libs)
|
||||
deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, library.baseLinker.Properties.Target.Product.Exclude_shared_libs)
|
||||
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, library.baseLinker.Properties.Target.Product.Exclude_static_libs)
|
||||
}
|
||||
if ctx.inRecovery() {
|
||||
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, library.baseLinker.Properties.Target.Recovery.Exclude_static_libs)
|
||||
deps.SharedLibs = removeListFromList(deps.SharedLibs, library.baseLinker.Properties.Target.Recovery.Exclude_shared_libs)
|
||||
|
22
cc/linker.go
22
cc/linker.go
@@ -263,8 +263,7 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
||||
deps.WholeStaticLibs = append(deps.WholeStaticLibs, "libbuildversion")
|
||||
}
|
||||
|
||||
// TODO(b/150902910): product variant must use Target.Product
|
||||
if ctx.useVndk() {
|
||||
if ctx.inVendor() {
|
||||
deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Vendor.Shared_libs...)
|
||||
deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Vendor.Exclude_shared_libs)
|
||||
deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Vendor.Exclude_shared_libs)
|
||||
@@ -276,6 +275,18 @@ func (linker *baseLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
|
||||
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Vendor.Exclude_runtime_libs)
|
||||
}
|
||||
|
||||
if ctx.inProduct() {
|
||||
deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Product.Shared_libs...)
|
||||
deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Product.Exclude_shared_libs)
|
||||
deps.ReexportSharedLibHeaders = removeListFromList(deps.ReexportSharedLibHeaders, linker.Properties.Target.Product.Exclude_shared_libs)
|
||||
deps.StaticLibs = append(deps.StaticLibs, linker.Properties.Target.Product.Static_libs...)
|
||||
deps.StaticLibs = removeListFromList(deps.StaticLibs, linker.Properties.Target.Product.Exclude_static_libs)
|
||||
deps.HeaderLibs = removeListFromList(deps.HeaderLibs, linker.Properties.Target.Product.Exclude_header_libs)
|
||||
deps.ReexportStaticLibHeaders = removeListFromList(deps.ReexportStaticLibHeaders, linker.Properties.Target.Product.Exclude_static_libs)
|
||||
deps.WholeStaticLibs = removeListFromList(deps.WholeStaticLibs, linker.Properties.Target.Product.Exclude_static_libs)
|
||||
deps.RuntimeLibs = removeListFromList(deps.RuntimeLibs, linker.Properties.Target.Product.Exclude_runtime_libs)
|
||||
}
|
||||
|
||||
if ctx.inRecovery() {
|
||||
deps.SharedLibs = append(deps.SharedLibs, linker.Properties.Target.Recovery.Shared_libs...)
|
||||
deps.SharedLibs = removeListFromList(deps.SharedLibs, linker.Properties.Target.Recovery.Exclude_shared_libs)
|
||||
@@ -500,11 +511,14 @@ func (linker *baseLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
|
||||
versionScript := ctx.ExpandOptionalSource(
|
||||
linker.Properties.Version_script, "version_script")
|
||||
|
||||
// TODO(b/150902910): product variant must use Target.Product
|
||||
if ctx.useVndk() && linker.Properties.Target.Vendor.Version_script != nil {
|
||||
if ctx.inVendor() && linker.Properties.Target.Vendor.Version_script != nil {
|
||||
versionScript = ctx.ExpandOptionalSource(
|
||||
linker.Properties.Target.Vendor.Version_script,
|
||||
"target.vendor.version_script")
|
||||
} else if ctx.inProduct() && linker.Properties.Target.Product.Version_script != nil {
|
||||
versionScript = ctx.ExpandOptionalSource(
|
||||
linker.Properties.Target.Product.Version_script,
|
||||
"target.product.version_script")
|
||||
}
|
||||
|
||||
if versionScript.Valid() {
|
||||
|
48
cc/vndk.go
48
cc/vndk.go
@@ -78,6 +78,13 @@ type VndkProperties struct {
|
||||
// VNDK-SP or LL-NDK modules only.
|
||||
Support_system_process *bool
|
||||
|
||||
// declared as a VNDK-private module.
|
||||
// This module still creates the vendor and product variants refering
|
||||
// to the `vendor_available: true` and `product_available: true`
|
||||
// properties. However, it is only available to the other VNDK modules
|
||||
// but not to the non-VNDK vendor or product modules.
|
||||
Private *bool
|
||||
|
||||
// Extending another module
|
||||
Extends *string
|
||||
}
|
||||
@@ -135,23 +142,11 @@ func (vndk *vndkdep) vndkCheckLinkType(ctx android.BaseModuleContext, to *Module
|
||||
return
|
||||
}
|
||||
if !vndk.isVndk() {
|
||||
// Non-VNDK modules those installed to /vendor or /system/vendor
|
||||
// can't depend on modules marked with vendor_available: false;
|
||||
// or those installed to /product or /system/product can't depend
|
||||
// on modules marked with product_available: false.
|
||||
violation := false
|
||||
if lib, ok := to.linker.(*llndkStubDecorator); ok && !Bool(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, or product-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())
|
||||
// Non-VNDK modules those installed to /vendor, /system/vendor,
|
||||
// /product or /system/product cannot depend on VNDK-private modules
|
||||
// that include VNDK-core-private, VNDK-SP-private and LLNDK-private.
|
||||
if to.IsVndkPrivate() {
|
||||
ctx.ModuleErrorf("non-VNDK module should not link to %q which has `private: true`", to.Name())
|
||||
}
|
||||
}
|
||||
if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() {
|
||||
@@ -183,10 +178,9 @@ func (vndk *vndkdep) vndkCheckLinkType(ctx android.BaseModuleContext, to *Module
|
||||
to.Name())
|
||||
return
|
||||
}
|
||||
// TODO(b/150902910): vndk-ext for product must check product_available.
|
||||
if !Bool(to.VendorProperties.Vendor_available) {
|
||||
if to.IsVndkPrivate() {
|
||||
ctx.ModuleErrorf(
|
||||
"`extends` refers module %q which does not have `vendor_available: true`",
|
||||
"`extends` refers module %q which has `private: true`",
|
||||
to.Name())
|
||||
return
|
||||
}
|
||||
@@ -324,6 +318,12 @@ func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
|
||||
vndkLibrariesLock.Lock()
|
||||
defer vndkLibrariesLock.Unlock()
|
||||
|
||||
if m.InProduct() {
|
||||
// We may skip the other steps for the product variants because they
|
||||
// are already covered by the vendor variants.
|
||||
return
|
||||
}
|
||||
|
||||
if inList(name, vndkMustUseVendorVariantList(mctx.Config())) {
|
||||
m.Properties.MustUseVendorVariant = true
|
||||
}
|
||||
@@ -336,9 +336,7 @@ func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) {
|
||||
} else {
|
||||
vndkCoreLibraries(mctx.Config())[name] = filename
|
||||
}
|
||||
// As `vendor_available` and `product_available` has the same value for VNDK modules,
|
||||
// we don't need to check both values.
|
||||
if !Bool(m.VendorProperties.Vendor_available) {
|
||||
if m.IsVndkPrivate() {
|
||||
vndkPrivateLibraries(mctx.Config())[name] = filename
|
||||
}
|
||||
}
|
||||
@@ -796,10 +794,10 @@ func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContex
|
||||
|
||||
func getVndkFileName(m *Module) (string, error) {
|
||||
if library, ok := m.linker.(*libraryDecorator); ok {
|
||||
return library.getLibNameHelper(m.BaseModuleName(), true) + ".so", nil
|
||||
return library.getLibNameHelper(m.BaseModuleName(), true, false) + ".so", nil
|
||||
}
|
||||
if prebuilt, ok := m.linker.(*prebuiltLibraryLinker); ok {
|
||||
return prebuilt.libraryDecorator.getLibNameHelper(m.BaseModuleName(), true) + ".so", nil
|
||||
return prebuilt.libraryDecorator.getLibNameHelper(m.BaseModuleName(), true, false) + ".so", nil
|
||||
}
|
||||
return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", m.linker)
|
||||
}
|
||||
|
Reference in New Issue
Block a user