Implement fake vendor snapshot
A fake vendor snapshot is a vendor snapshot whose prebuilt binaries and captured headers are all empty. It's much faster to be built than the real vendor snapshot, so users can exploit the fake vendor snapshot to reduce the size of vendor snapshot they need, by installing the fake snapshot and then inspecting the ninja dependencies. Bug: 157967325 Test: m dist vendor-fake-snapshot Change-Id: I5e16e8dbbf9dd5e753cdd471ca73d06984a6cb2c
This commit is contained in:
@@ -1245,6 +1245,15 @@ func TestVendorSnapshotCapture(t *testing.T) {
|
||||
t.Errorf("%q expected but not found", jsonFile)
|
||||
}
|
||||
}
|
||||
|
||||
// fake snapshot should have all outputs in the normal snapshot.
|
||||
fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot")
|
||||
for _, output := range snapshotSingleton.AllOutputs() {
|
||||
fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1)
|
||||
if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil {
|
||||
t.Errorf("%q expected but not found", fakeOutput)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestVendorSnapshotUse(t *testing.T) {
|
||||
@@ -1676,6 +1685,8 @@ func TestVendorSnapshotExcludeInVendorProprietaryPathErrors(t *testing.T) {
|
||||
`module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
|
||||
`module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
|
||||
`module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
|
||||
`module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
|
||||
`module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1719,6 +1730,10 @@ func TestVendorSnapshotExcludeWithVendorAvailable(t *testing.T) {
|
||||
`module "libinclude\{.+,image:,arch:arm_.+\}" may not use both "vendor_available: true" and "exclude_from_vendor_snapshot: true"`,
|
||||
`module "libinclude\{.+,image:vendor.+,arch:arm64_.+\}" may not use both "vendor_available: true" and "exclude_from_vendor_snapshot: true"`,
|
||||
`module "libinclude\{.+,image:vendor.+,arch:arm_.+\}" may not use both "vendor_available: true" and "exclude_from_vendor_snapshot: true"`,
|
||||
`module "libinclude\{.+,image:,arch:arm64_.+\}" may not use both "vendor_available: true" and "exclude_from_vendor_snapshot: true"`,
|
||||
`module "libinclude\{.+,image:,arch:arm_.+\}" may not use both "vendor_available: true" and "exclude_from_vendor_snapshot: true"`,
|
||||
`module "libinclude\{.+,image:vendor.+,arch:arm64_.+\}" may not use both "vendor_available: true" and "exclude_from_vendor_snapshot: true"`,
|
||||
`module "libinclude\{.+,image:vendor.+,arch:arm_.+\}" may not use both "vendor_available: true" and "exclude_from_vendor_snapshot: true"`,
|
||||
})
|
||||
}
|
||||
|
||||
|
@@ -94,6 +94,8 @@ func (vendorSnapshotImage) init() {
|
||||
android.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory)
|
||||
android.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory)
|
||||
android.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory)
|
||||
|
||||
android.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton)
|
||||
}
|
||||
|
||||
func (vendorSnapshotImage) shouldGenerateSnapshot(ctx android.SingletonContext) bool {
|
||||
|
@@ -577,6 +577,7 @@ func CreateTestContext(config android.Config) *android.TestContext {
|
||||
RegisterRequiredBuildComponentsForTest(ctx)
|
||||
ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
|
||||
ctx.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton)
|
||||
ctx.RegisterSingletonType("vendor-fake-snapshot", VendorFakeSnapshotSingleton)
|
||||
ctx.RegisterSingletonType("recovery-snapshot", RecoverySnapshotSingleton)
|
||||
|
||||
return ctx
|
||||
|
@@ -34,6 +34,16 @@ var vendorSnapshotSingleton = snapshotSingleton{
|
||||
android.OptionalPath{},
|
||||
true,
|
||||
vendorSnapshotImageSingleton,
|
||||
false, /* fake */
|
||||
}
|
||||
|
||||
var vendorFakeSnapshotSingleton = snapshotSingleton{
|
||||
"vendor",
|
||||
"SOONG_VENDOR_FAKE_SNAPSHOT_ZIP",
|
||||
android.OptionalPath{},
|
||||
true,
|
||||
vendorSnapshotImageSingleton,
|
||||
true, /* fake */
|
||||
}
|
||||
|
||||
var recoverySnapshotSingleton = snapshotSingleton{
|
||||
@@ -42,12 +52,17 @@ var recoverySnapshotSingleton = snapshotSingleton{
|
||||
android.OptionalPath{},
|
||||
false,
|
||||
recoverySnapshotImageSingleton,
|
||||
false, /* fake */
|
||||
}
|
||||
|
||||
func VendorSnapshotSingleton() android.Singleton {
|
||||
return &vendorSnapshotSingleton
|
||||
}
|
||||
|
||||
func VendorFakeSnapshotSingleton() android.Singleton {
|
||||
return &vendorFakeSnapshotSingleton
|
||||
}
|
||||
|
||||
func RecoverySnapshotSingleton() android.Singleton {
|
||||
return &recoverySnapshotSingleton
|
||||
}
|
||||
@@ -70,6 +85,11 @@ type snapshotSingleton struct {
|
||||
// associated with this snapshot (e.g., specific to the vendor image,
|
||||
// recovery image, etc.).
|
||||
image snapshotImage
|
||||
|
||||
// Whether this singleton is for fake snapshot or not.
|
||||
// Fake snapshot is a snapshot whose prebuilt binaries and headers are empty.
|
||||
// It is much faster to generate, and can be used to inspect dependencies.
|
||||
fake bool
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -351,6 +371,11 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
*/
|
||||
|
||||
snapshotDir := c.name + "-snapshot"
|
||||
if c.fake {
|
||||
// If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid
|
||||
// collision with real snapshot files
|
||||
snapshotDir = filepath.Join("fake", snapshotDir)
|
||||
}
|
||||
snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
|
||||
|
||||
includeDir := filepath.Join(snapshotArchDir, "include")
|
||||
@@ -362,6 +387,15 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
|
||||
var headers android.Paths
|
||||
|
||||
copyFile := copyFileRule
|
||||
if c.fake {
|
||||
// All prebuilt binaries and headers are installed by copyFile function. This makes a fake
|
||||
// snapshot just touch prebuilts and headers, rather than installing real files.
|
||||
copyFile = func(ctx android.SingletonContext, path android.Path, out string) android.OutputPath {
|
||||
return writeStringToFileRule(ctx, "", out)
|
||||
}
|
||||
}
|
||||
|
||||
// installSnapshot function copies prebuilt file (.so, .a, or executable) and json flag file.
|
||||
// For executables, init_rc and vintf_fragments files are also copied.
|
||||
installSnapshot := func(m *Module) android.Paths {
|
||||
@@ -400,7 +434,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
out := filepath.Join(configsDir, path.Base())
|
||||
if !installedConfigs[out] {
|
||||
installedConfigs[out] = true
|
||||
ret = append(ret, copyFileRule(ctx, path, out))
|
||||
ret = append(ret, copyFile(ctx, path, out))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,7 +485,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
prop.ModuleName += ".cfi"
|
||||
}
|
||||
snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, libType, stem)
|
||||
ret = append(ret, copyFileRule(ctx, libPath, snapshotLibOut))
|
||||
ret = append(ret, copyFile(ctx, libPath, snapshotLibOut))
|
||||
} else {
|
||||
stem = ctx.ModuleName(m)
|
||||
}
|
||||
@@ -465,7 +499,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
// install bin
|
||||
binPath := m.outputFile.Path()
|
||||
snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base())
|
||||
ret = append(ret, copyFileRule(ctx, binPath, snapshotBinOut))
|
||||
ret = append(ret, copyFile(ctx, binPath, snapshotBinOut))
|
||||
propOut = snapshotBinOut + ".json"
|
||||
} else if m.object() {
|
||||
// object files aren't installed to the device, so their names can conflict.
|
||||
@@ -473,7 +507,7 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
objPath := m.outputFile.Path()
|
||||
snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object",
|
||||
ctx.ModuleName(m)+filepath.Ext(objPath.Base()))
|
||||
ret = append(ret, copyFileRule(ctx, objPath, snapshotObjOut))
|
||||
ret = append(ret, copyFile(ctx, objPath, snapshotObjOut))
|
||||
propOut = snapshotObjOut + ".json"
|
||||
} else {
|
||||
ctx.Errorf("unknown module %q in vendor snapshot", m.String())
|
||||
@@ -538,16 +572,14 @@ func (c *snapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
|
||||
// skip already copied notice file
|
||||
if !installedNotices[noticeOut] {
|
||||
installedNotices[noticeOut] = true
|
||||
snapshotOutputs = append(snapshotOutputs, combineNoticesRule(
|
||||
ctx, m.NoticeFiles(), noticeOut))
|
||||
snapshotOutputs = append(snapshotOutputs, combineNoticesRule(ctx, m.NoticeFiles(), noticeOut))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// install all headers after removing duplicates
|
||||
for _, header := range android.FirstUniquePaths(headers) {
|
||||
snapshotOutputs = append(snapshotOutputs, copyFileRule(
|
||||
ctx, header, filepath.Join(includeDir, header.String())))
|
||||
snapshotOutputs = append(snapshotOutputs, copyFile(ctx, header, filepath.Join(includeDir, header.String())))
|
||||
}
|
||||
|
||||
// All artifacts are ready. Sort them to normalize ninja and then zip.
|
||||
|
Reference in New Issue
Block a user