• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2021 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14package snapshot
15
16import (
17	"path/filepath"
18	"sort"
19
20	"android/soong/android"
21)
22
23// This file contains singletons to capture snapshots. This singleton will generate snapshot of each target
24// image, and capturing snapshot module will be delegated to each module which implements GenerateSnapshotAction
25// function and register with RegisterSnapshotAction.
26
27var pctx = android.NewPackageContext("android/soong/snapshot")
28
29type SnapshotSingleton struct {
30	// Name, e.g., "vendor", "recovery", "ramdisk".
31	name string
32
33	// Make variable that points to the snapshot file, e.g.,
34	// "SOONG_RECOVERY_SNAPSHOT_ZIP".
35	makeVar string
36
37	// Path to the snapshot zip file.
38	snapshotZipFile android.OptionalPath
39
40	// Implementation of the image interface specific to the image
41	// associated with this snapshot (e.g., specific to the vendor image,
42	// recovery image, etc.).
43	Image SnapshotImage
44
45	// Whether this singleton is for fake snapshot or not.
46	// Fake snapshot is a snapshot whose prebuilt binaries and headers are empty.
47	// It is much faster to generate, and can be used to inspect dependencies.
48	Fake bool
49}
50
51// Interface of function to capture snapshot from each module
52type GenerateSnapshotAction func(snapshot SnapshotSingleton, ctx android.SingletonContext, snapshotArchDir string) android.Paths
53
54var snapshotActionList []GenerateSnapshotAction
55
56// Register GenerateSnapshotAction function so it can be called while generating snapshot
57func RegisterSnapshotAction(x GenerateSnapshotAction) {
58	snapshotActionList = append(snapshotActionList, x)
59}
60
61func (c *SnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) {
62	if !c.Image.shouldGenerateSnapshot(ctx) {
63		return
64	}
65
66	var snapshotOutputs android.Paths
67
68	// Snapshot zipped artifacts will be captured under {SNAPSHOT_ARCH} directory
69
70	snapshotDir := c.name + "-snapshot"
71	if c.Fake {
72		// If this is a fake snapshot singleton, place all files under fake/ subdirectory to avoid
73		// collision with real snapshot files
74		snapshotDir = filepath.Join("fake", snapshotDir)
75	}
76	snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch())
77
78	for _, f := range snapshotActionList {
79		snapshotOutputs = append(snapshotOutputs, f(*c, ctx, snapshotArchDir)...)
80	}
81
82	// All artifacts are ready. Sort them to normalize ninja and then zip.
83	sort.Slice(snapshotOutputs, func(i, j int) bool {
84		return snapshotOutputs[i].String() < snapshotOutputs[j].String()
85	})
86
87	zipPath := android.PathForOutput(
88		ctx,
89		snapshotDir,
90		c.name+"-"+ctx.Config().DeviceName()+".zip")
91	zipRule := android.NewRuleBuilder(pctx, ctx)
92
93	// filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with tr
94	snapshotOutputList := android.PathForOutput(
95		ctx,
96		snapshotDir,
97		c.name+"-"+ctx.Config().DeviceName()+"_list")
98	rspFile := snapshotOutputList.ReplaceExtension(ctx, "rsp")
99	zipRule.Command().
100		Text("tr").
101		FlagWithArg("-d ", "\\'").
102		FlagWithRspFileInputList("< ", rspFile, snapshotOutputs).
103		FlagWithOutput("> ", snapshotOutputList)
104
105	zipRule.Temporary(snapshotOutputList)
106
107	zipRule.Command().
108		BuiltTool("soong_zip").
109		FlagWithOutput("-o ", zipPath).
110		FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()).
111		FlagWithInput("-l ", snapshotOutputList)
112
113	zipRule.Build(zipPath.String(), c.name+" snapshot "+zipPath.String())
114	zipRule.DeleteTemporaryFiles()
115	c.snapshotZipFile = android.OptionalPathForPath(zipPath)
116}
117
118func (c *SnapshotSingleton) MakeVars(ctx android.MakeVarsContext) {
119	ctx.Strict(
120		c.makeVar,
121		c.snapshotZipFile.String())
122}
123