Browse Source

Add overrides support for snapshots

Overrides properties will now be captured in json flag files, which will
be copied to installed vendor snapshot modules.

Bug: 216567575
Test: soong test && manual install
Change-Id: Ife5e84b126e798fba7802b9cff000c9197756cb9
Inseob Kim 1 year ago
parent
commit
a1888ce78d
8 changed files with 131 additions and 2 deletions
  1. 5 1
      cc/androidmk.go
  2. 6 0
      cc/binary.go
  3. 11 0
      cc/cc.go
  4. 6 0
      cc/library.go
  5. 19 0
      cc/testing.go
  6. 3 0
      cc/vendor_snapshot.go
  7. 79 0
      cc/vendor_snapshot_test.go
  8. 2 1
      snapshot/snapshot_base.go

+ 5 - 1
cc/androidmk.go

@@ -546,7 +546,7 @@ func (c *snapshotLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entrie
 
 	entries.SubName += c.baseProperties.Androidmk_suffix
 
-	entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
+	entries.ExtraEntries = append(entries.ExtraEntries, func(_ android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
 		c.libraryDecorator.androidMkWriteExportedFlags(entries)
 
 		if c.shared() || c.static() {
@@ -567,6 +567,10 @@ func (c *snapshotLibraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entrie
 			if c.tocFile.Valid() {
 				entries.SetString("LOCAL_SOONG_TOC", c.tocFile.String())
 			}
+
+			if c.shared() && len(c.Properties.Overrides) > 0 {
+				entries.SetString("LOCAL_OVERRIDES_MODULES", strings.Join(makeOverrideModuleNames(ctx, c.Properties.Overrides), " "))
+			}
 		}
 
 		if !c.shared() { // static or header

+ 6 - 0
cc/binary.go

@@ -540,6 +540,12 @@ func (binary *binaryDecorator) hostToolPath() android.OptionalPath {
 	return binary.toolPath
 }
 
+func (binary *binaryDecorator) overriddenModules() []string {
+	return binary.Properties.Overrides
+}
+
+var _ overridable = (*binaryDecorator)(nil)
+
 func init() {
 	pctx.HostBinToolVariable("verifyHostBionicCmd", "host_bionic_verify")
 }

+ 11 - 0
cc/cc.go

@@ -616,6 +616,10 @@ type xref interface {
 	XrefCcFiles() android.Paths
 }
 
+type overridable interface {
+	overriddenModules() []string
+}
+
 type libraryDependencyKind int
 
 const (
@@ -3637,6 +3641,13 @@ func (c *Module) UniqueApexVariations() bool {
 	return c.UseVndk() && c.IsVndk()
 }
 
+func (c *Module) overriddenModules() []string {
+	if o, ok := c.linker.(overridable); ok {
+		return o.overriddenModules()
+	}
+	return nil
+}
+
 var _ snapshot.RelativeInstallPath = (*Module)(nil)
 
 type moduleType int

+ 6 - 0
cc/library.go

@@ -2231,6 +2231,12 @@ func (library *libraryDecorator) getAPIListCoverageXMLPath() android.ModuleOutPa
 	return library.apiListCoverageXmlPath
 }
 
+func (library *libraryDecorator) overriddenModules() []string {
+	return library.Properties.Overrides
+}
+
+var _ overridable = (*libraryDecorator)(nil)
+
 var versioningMacroNamesListKey = android.NewOnceKey("versioningMacroNamesList")
 
 // versioningMacroNamesList returns a singleton map, where keys are "version macro names",

+ 19 - 0
cc/testing.go

@@ -15,6 +15,7 @@
 package cc
 
 import (
+	"encoding/json"
 	"path/filepath"
 	"testing"
 
@@ -736,3 +737,21 @@ func AssertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext,
 		t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected)
 	}
 }
+
+func checkOverrides(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, jsonPath string, expected []string) {
+	out := singleton.MaybeOutput(jsonPath)
+	content := android.ContentFromFileRuleForTests(t, out)
+
+	var flags snapshotJsonFlags
+	if err := json.Unmarshal([]byte(content), &flags); err != nil {
+		t.Errorf("Error while unmarshalling json %q: %w", jsonPath, err)
+		return
+	}
+
+	for _, moduleName := range expected {
+		if !android.InList(moduleName, flags.Overrides) {
+			t.Errorf("expected %q to be in %q: %q", moduleName, flags.Overrides, content)
+			return
+		}
+	}
+}

+ 3 - 0
cc/vendor_snapshot.go

@@ -239,6 +239,9 @@ var ccSnapshotAction snapshot.GenerateSnapshotAction = func(s snapshot.SnapshotS
 		}
 		prop.RuntimeLibs = m.SnapshotRuntimeLibs()
 		prop.Required = m.RequiredModuleNames()
+		if o, ok := m.(overridable); ok {
+			prop.Overrides = o.overriddenModules()
+		}
 		for _, path := range m.InitRc() {
 			prop.InitRc = append(prop.InitRc, filepath.Join("configs", path.Base()))
 		}

+ 79 - 0
cc/vendor_snapshot_test.go

@@ -41,6 +41,13 @@ func TestVendorSnapshotCapture(t *testing.T) {
 		nocrt: true,
 	}
 
+	cc_library {
+		name: "libvendor_override",
+		vendor: true,
+		nocrt: true,
+		overrides: ["libvendor"],
+	}
+
 	cc_library {
 		name: "libvendor_available",
 		vendor_available: true,
@@ -65,6 +72,13 @@ func TestVendorSnapshotCapture(t *testing.T) {
 		nocrt: true,
 	}
 
+	cc_binary {
+		name: "vendor_bin_override",
+		vendor: true,
+		nocrt: true,
+		overrides: ["vendor_bin"],
+	}
+
 	cc_prebuilt_library_static {
 		name: "libb",
 		vendor_available: true,
@@ -150,6 +164,8 @@ func TestVendorSnapshotCapture(t *testing.T) {
 			jsonFiles = append(jsonFiles,
 				filepath.Join(binaryDir, "vendor_bin.json"),
 				filepath.Join(binaryDir, "vendor_available_bin.json"))
+
+			checkOverrides(t, ctx, snapshotSingleton, filepath.Join(binaryDir, "vendor_bin_override.json"), []string{"vendor_bin"})
 		}
 
 		// For header libraries, all vendor:true and vendor_available modules are captured.
@@ -161,6 +177,8 @@ func TestVendorSnapshotCapture(t *testing.T) {
 		objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
 		CheckSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
 		jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
+
+		checkOverrides(t, ctx, snapshotSingleton, filepath.Join(sharedDir, "libvendor_override.so.json"), []string{"libvendor"})
 	}
 
 	for _, jsonFile := range jsonFiles {
@@ -506,11 +524,13 @@ func TestVendorSnapshotUse(t *testing.T) {
 				],
 				shared_libs: [
 					"libvendor",
+					"libvendor_override",
 					"libvendor_available",
 					"lib64",
 				],
 				binaries: [
 					"bin",
+					"bin_override",
 				],
 			},
 			arm: {
@@ -526,6 +546,7 @@ func TestVendorSnapshotUse(t *testing.T) {
 				],
 				shared_libs: [
 					"libvendor",
+					"libvendor_override",
 					"libvendor_available",
 					"lib32",
 				],
@@ -577,6 +598,30 @@ func TestVendorSnapshotUse(t *testing.T) {
 		},
 	}
 
+	vendor_snapshot_shared {
+		name: "libvendor_override",
+		version: "31",
+		target_arch: "arm64",
+		compile_multilib: "both",
+		vendor: true,
+		overrides: ["libvendor"],
+		shared_libs: [
+			"libvendor_without_snapshot",
+			"libvendor_available",
+			"libvndk",
+		],
+		arch: {
+			arm64: {
+				src: "override/libvendor.so",
+				export_include_dirs: ["include/libvendor"],
+			},
+			arm: {
+				src: "override/libvendor.so",
+				export_include_dirs: ["include/libvendor"],
+			},
+		},
+	}
+
 	vendor_snapshot_static {
 		name: "lib32",
 		version: "31",
@@ -744,6 +789,21 @@ func TestVendorSnapshotUse(t *testing.T) {
 		symlinks: ["binfoo", "binbar"],
 	}
 
+	vendor_snapshot_binary {
+		name: "bin_override",
+		version: "31",
+		target_arch: "arm64",
+		compile_multilib: "64",
+		vendor: true,
+		overrides: ["bin"],
+		arch: {
+			arm64: {
+				src: "override/bin",
+			},
+		},
+		symlinks: ["binfoo", "binbar"],
+	}
+
 	vendor_snapshot_binary {
 		name: "bin32",
 		version: "31",
@@ -793,6 +853,7 @@ func TestVendorSnapshotUse(t *testing.T) {
 		"framework/symbol.txt":             nil,
 		"vendor/Android.bp":                []byte(vendorProprietaryBp),
 		"vendor/bin":                       nil,
+		"vendor/override/bin":              nil,
 		"vendor/bin32":                     nil,
 		"vendor/bin.cpp":                   nil,
 		"vendor/client.cpp":                nil,
@@ -806,6 +867,7 @@ func TestVendorSnapshotUse(t *testing.T) {
 		"vendor/libvendor.a":               nil,
 		"vendor/libvendor.cfi.a":           nil,
 		"vendor/libvendor.so":              nil,
+		"vendor/override/libvendor.so":     nil,
 		"vendor/lib32.a":                   nil,
 		"vendor/lib32.so":                  nil,
 		"vendor/lib64.a":                   nil,
@@ -958,6 +1020,23 @@ func TestVendorSnapshotUse(t *testing.T) {
 	if inList(binaryVariant, binVariants) {
 		t.Errorf("bin must not have variant %#v, but it does", sharedVariant)
 	}
+
+	// test overrides property
+	binOverrideModule := ctx.ModuleForTests("bin_override.vendor_binary.31.arm64", binaryVariant)
+	binOverrideModule.Output("bin")
+	binOverrideMkEntries := android.AndroidMkEntriesForTest(t, ctx, binOverrideModule.Module())
+	binOverrideEntry := binOverrideMkEntries[0].EntryMap["LOCAL_OVERRIDES_MODULES"]
+	if !inList("bin", binOverrideEntry) {
+		t.Errorf("bin_override must override bin but was %q\n", binOverrideEntry)
+	}
+
+	libvendorOverrideModule := ctx.ModuleForTests("libvendor_override.vendor_shared.31.arm64", sharedVariant)
+	libvendorOverrideModule.Output("libvendor.so")
+	libvendorOverrideMkEntries := android.AndroidMkEntriesForTest(t, ctx, libvendorOverrideModule.Module())
+	libvendorOverrideEntry := libvendorOverrideMkEntries[0].EntryMap["LOCAL_OVERRIDES_MODULES"]
+	if !inList("libvendor", libvendorOverrideEntry) {
+		t.Errorf("libvendor_override must override libvendor but was %q\n", libvendorOverrideEntry)
+	}
 }
 
 func TestVendorSnapshotSanitizer(t *testing.T) {

+ 2 - 1
snapshot/snapshot_base.go

@@ -118,5 +118,6 @@ type SnapshotJsonFlags struct {
 	CrateName           string `json:",omitempty"`
 
 	// dependencies
-	Required []string `json:",omitempty"`
+	Required  []string `json:",omitempty"`
+	Overrides []string `json:",omitempty"`
 }