Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2187e41f authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I81769f57,I28fb6886

* changes:
  Define vndk.private property for VNDK-private libraries
  'vendor_available: *' will not create product variant
parents b2d77d4a fd9e8044
Loading
Loading
Loading
Loading
+38 −6
Original line number Diff line number Diff line
@@ -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")
}

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()
func (c *Module) IsVndkPrivate() bool {
	// 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 {
+151 −39
Original line number Diff line number Diff line
@@ -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,15 +726,41 @@ 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",
			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: false,
			product_available: true,
			vndk: {
				enabled: true,
			},
			nocrt: true,
			target: {
				vendor: {
					cflags: ["-DTEST",],
				},
			},
		}
	`)
}
@@ -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 {
+1 −2
Original line number Diff line number Diff line
@@ -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() {
+1 −2
Original line number Diff line number Diff line
@@ -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)
+71 −18
Original line number Diff line number Diff line
@@ -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,14 +335,14 @@ 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.
		// 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)
	}
}
Loading