Browse Source

Merge changes I11693286,I8d79a434

* changes:
  VNDK libs use "unique" APEX variants
  use_vndk_as_stable APEX shouldn't include VNDK lib
Jooyung Han 2 years ago
parent
commit
472be14f26
3 changed files with 131 additions and 21 deletions
  1. 12 3
      apex/apex.go
  2. 111 18
      apex/apex_test.go
  3. 8 0
      cc/cc.go

+ 12 - 3
apex/apex.go

@@ -888,9 +888,18 @@ func (a *apexBundle) ApexInfoMutator(mctx android.TopDownMutatorContext) {
 	// APEX, but shared across APEXes via the VNDK APEX.
 	useVndk := a.SocSpecific() || a.DeviceSpecific() || (a.ProductSpecific() && mctx.Config().EnforceProductPartitionInterface())
 	excludeVndkLibs := useVndk && proptools.Bool(a.properties.Use_vndk_as_stable)
-	if !useVndk && proptools.Bool(a.properties.Use_vndk_as_stable) {
-		mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
-		return
+	if proptools.Bool(a.properties.Use_vndk_as_stable) {
+		if !useVndk {
+			mctx.PropertyErrorf("use_vndk_as_stable", "not supported for system/system_ext APEXes")
+		}
+		mctx.VisitDirectDepsWithTag(sharedLibTag, func(dep android.Module) {
+			if c, ok := dep.(*cc.Module); ok && c.IsVndk() {
+				mctx.PropertyErrorf("use_vndk_as_stable", "Trying to include a VNDK library(%s) while use_vndk_as_stable is true.", dep.Name())
+			}
+		})
+		if mctx.Failed() {
+			return
+		}
 	}
 
 	continueApexDepsWalk := func(child, parent android.Module) bool {

+ 111 - 18
apex/apex_test.go

@@ -2713,7 +2713,33 @@ func TestVendorApex(t *testing.T) {
 	ensureListNotContains(t, requireNativeLibs, ":vndk")
 }
 
+func TestVendorApex_use_vndk_as_stable_TryingToIncludeVNDKLib(t *testing.T) {
+	testApexError(t, `Trying to include a VNDK library`, `
+		apex {
+			name: "myapex",
+			key: "myapex.key",
+			native_shared_libs: ["libc++"], // libc++ is a VNDK lib
+			vendor: true,
+			use_vndk_as_stable: true,
+			updatable: false,
+		}
+		apex_key {
+			name: "myapex.key",
+			public_key: "testkey.avbpubkey",
+			private_key: "testkey.pem",
+		}`)
+}
+
 func TestVendorApex_use_vndk_as_stable(t *testing.T) {
+	//   myapex                  myapex2
+	//    |                       |
+	//  mybin ------.           mybin2
+	//   \           \          /  |
+	// (stable)   .---\--------`   |
+	//     \     /     \           |
+	//      \   /       \         /
+	//      libvndk       libvendor
+	//      (vndk)
 	ctx := testApex(t, `
 		apex {
 			name: "myapex",
@@ -2744,28 +2770,95 @@ func TestVendorApex_use_vndk_as_stable(t *testing.T) {
 		cc_library {
 			name: "libvendor",
 			vendor: true,
+			stl: "none",
+		}
+		apex {
+			name: "myapex2",
+			key: "myapex.key",
+			binaries: ["mybin2"],
+			vendor: true,
+			use_vndk_as_stable: false,
+			updatable: false,
+		}
+		cc_binary {
+			name: "mybin2",
+			vendor: true,
+			shared_libs: ["libvndk", "libvendor"],
 		}
 	`)
 
 	vendorVariant := "android_vendor.29_arm64_armv8-a"
 
-	ldRule := ctx.ModuleForTests("mybin", vendorVariant+"_apex10000").Rule("ld")
-	libs := names(ldRule.Args["libFlags"])
-	// VNDK libs(libvndk/libc++) as they are
-	ensureListContains(t, libs, "out/soong/.intermediates/libvndk/"+vendorVariant+"_shared/libvndk.so")
-	ensureListContains(t, libs, "out/soong/.intermediates/"+cc.DefaultCcCommonTestModulesDir+"libc++/"+vendorVariant+"_shared/libc++.so")
-	// non-stable Vendor libs as APEX variants
-	ensureListContains(t, libs, "out/soong/.intermediates/libvendor/"+vendorVariant+"_shared_apex10000/libvendor.so")
-
-	// VNDK libs are not included when use_vndk_as_stable: true
-	ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
-		"bin/mybin",
-		"lib64/libvendor.so",
-	})
-
-	apexManifestRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexManifestRule")
-	requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
-	ensureListContains(t, requireNativeLibs, ":vndk")
+	for _, tc := range []struct {
+		name                 string
+		apexName             string
+		moduleName           string
+		moduleVariant        string
+		libs                 []string
+		contents             []string
+		requireVndkNamespace bool
+	}{
+		{
+			name:          "use_vndk_as_stable",
+			apexName:      "myapex",
+			moduleName:    "mybin",
+			moduleVariant: vendorVariant + "_apex10000",
+			libs: []string{
+				// should link with vendor variants of VNDK libs(libvndk/libc++)
+				"out/soong/.intermediates/libvndk/" + vendorVariant + "_shared/libvndk.so",
+				"out/soong/.intermediates/" + cc.DefaultCcCommonTestModulesDir + "libc++/" + vendorVariant + "_shared/libc++.so",
+				// unstable Vendor libs as APEX variant
+				"out/soong/.intermediates/libvendor/" + vendorVariant + "_shared_apex10000/libvendor.so",
+			},
+			contents: []string{
+				"bin/mybin",
+				"lib64/libvendor.so",
+				// VNDK libs (libvndk/libc++) are not included
+			},
+			requireVndkNamespace: true,
+		},
+		{
+			name:          "!use_vndk_as_stable",
+			apexName:      "myapex2",
+			moduleName:    "mybin2",
+			moduleVariant: vendorVariant + "_myapex2",
+			libs: []string{
+				// should link with "unique" APEX(myapex2) variant of VNDK libs(libvndk/libc++)
+				"out/soong/.intermediates/libvndk/" + vendorVariant + "_shared_myapex2/libvndk.so",
+				"out/soong/.intermediates/" + cc.DefaultCcCommonTestModulesDir + "libc++/" + vendorVariant + "_shared_myapex2/libc++.so",
+				// unstable vendor libs have "merged" APEX variants
+				"out/soong/.intermediates/libvendor/" + vendorVariant + "_shared_apex10000/libvendor.so",
+			},
+			contents: []string{
+				"bin/mybin2",
+				"lib64/libvendor.so",
+				// VNDK libs are included as well
+				"lib64/libvndk.so",
+				"lib64/libc++.so",
+			},
+			requireVndkNamespace: false,
+		},
+	} {
+		t.Run(tc.name, func(t *testing.T) {
+			// Check linked libs
+			ldRule := ctx.ModuleForTests(tc.moduleName, tc.moduleVariant).Rule("ld")
+			libs := names(ldRule.Args["libFlags"])
+			for _, lib := range tc.libs {
+				ensureListContains(t, libs, lib)
+			}
+			// Check apex contents
+			ensureExactContents(t, ctx, tc.apexName, "android_common_"+tc.apexName+"_image", tc.contents)
+
+			// Check "requireNativeLibs"
+			apexManifestRule := ctx.ModuleForTests(tc.apexName, "android_common_"+tc.apexName+"_image").Rule("apexManifestRule")
+			requireNativeLibs := names(apexManifestRule.Args["requireNativeLibs"])
+			if tc.requireVndkNamespace {
+				ensureListContains(t, requireNativeLibs, ":vndk")
+			} else {
+				ensureListNotContains(t, requireNativeLibs, ":vndk")
+			}
+		})
+	}
 }
 
 func TestProductVariant(t *testing.T) {
@@ -2796,7 +2889,7 @@ func TestProductVariant(t *testing.T) {
 	)
 
 	cflags := strings.Fields(
-		ctx.ModuleForTests("foo", "android_product.29_arm64_armv8-a_apex10000").Rule("cc").Args["cFlags"])
+		ctx.ModuleForTests("foo", "android_product.29_arm64_armv8-a_myapex").Rule("cc").Args["cFlags"])
 	ensureListContains(t, cflags, "-D__ANDROID_VNDK__")
 	ensureListContains(t, cflags, "-D__ANDROID_APEX__")
 	ensureListContains(t, cflags, "-D__ANDROID_PRODUCT__")

+ 8 - 0
cc/cc.go

@@ -3465,6 +3465,14 @@ func (c *Module) AlwaysRequiresPlatformApexVariant() bool {
 	return c.IsStubs() || c.Target().NativeBridge == android.NativeBridgeEnabled
 }
 
+// Overrides android.ApexModuleBase.UniqueApexVariations
+func (c *Module) UniqueApexVariations() bool {
+	// When a vendor APEX needs a VNDK lib in it (use_vndk_as_stable: false), it should be a unique
+	// APEX variation. Otherwise, another vendor APEX with use_vndk_as_stable:true may use a wrong
+	// variation of the VNDK lib because APEX variations are merged/grouped.
+	return c.UseVndk() && c.IsVndk()
+}
+
 var _ snapshot.RelativeInstallPath = (*Module)(nil)
 
 type moduleType int