Add module based host-tools snapshot
Add new module:
host_snapshot {
name: "host-snapshot"
deps: [
(list of host tools)
],
...
}
Package host tools using android.PackagingBase to capture host tools and transitive packaging data.
Add JSON meta data to snapshot that allows snapshot to be installed via development/vendor_snapshot/update.py
Add support to generate a fake host snapshot of all host modules that is used to detect required
modules via development/vendor_snapshot/update.py.
Bug: 192556798
Bug: 194799048
Bug: 192896149
Test: m HOST_FAKE_SNAPSHOT_ENABLE=true host-fake-snapshot dist -- check snapshot exists in dist
Change-Id: I849c4db801cd858408f6fe6a3ce69262a23a5be9
diff --git a/snapshot/host_fake_snapshot.go b/snapshot/host_fake_snapshot.go
new file mode 100644
index 0000000..6b4e12b
--- /dev/null
+++ b/snapshot/host_fake_snapshot.go
@@ -0,0 +1,149 @@
+// Copyright 2021 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package snapshot
+
+import (
+ "encoding/json"
+ "path/filepath"
+
+ "android/soong/android"
+)
+
+// The host_snapshot module creates a snapshot of host tools to be used
+// in a minimal source tree. In order to create the host_snapshot the
+// user must explicitly list the modules to be included. The
+// host-fake-snapshot, defined in this file, is a utility to help determine
+// which host modules are being used in the minimal source tree.
+//
+// The host-fake-snapshot is designed to run in a full source tree and
+// will result in a snapshot that contains an empty file for each host
+// tool found in the tree. The fake snapshot is only used to determine
+// the host modules that the minimal source tree depends on, hence the
+// snapshot uses an empty file for each module and saves on having to
+// actually build any tool to generate the snapshot. The fake snapshot
+// is compatible with an actual host_snapshot and is installed into a
+// minimal source tree via the development/vendor_snapshot/update.py
+// script.
+//
+// After generating the fake snapshot and installing into the minimal
+// source tree, the dependent modules are determined via the
+// development/vendor_snapshot/update.py script (see script for more
+// information). These modules are then used to define the actual
+// host_snapshot to be used. This is a similar process to the other
+// snapshots (vendor, recovery,...)
+//
+// Example
+//
+// Full source tree:
+// 1/ Generate fake host snapshot
+//
+// Minimal source tree:
+// 2/ Install the fake host snapshot
+// 3/ List the host modules used from the snapshot
+// 4/ Remove fake host snapshot
+//
+// Full source tree:
+// 4/ Create host_snapshot with modules identified in step 3
+//
+// Minimal source tree:
+// 5/ Install host snapshot
+// 6/ Build
+//
+// The host-fake-snapshot is a singleton module, that will be built
+// if HOST_FAKE_SNAPSHOT_ENABLE=true.
+
+func init() {
+ registerHostSnapshotComponents(android.InitRegistrationContext)
+}
+
+func registerHostSnapshotComponents(ctx android.RegistrationContext) {
+ ctx.RegisterSingletonType("host-fake-snapshot", HostToolsFakeAndroidSingleton)
+}
+
+type hostFakeSingleton struct {
+ snapshotDir string
+ zipFile android.OptionalPath
+}
+
+func (c *hostFakeSingleton) init() {
+ c.snapshotDir = "host-fake-snapshot"
+
+}
+func HostToolsFakeAndroidSingleton() android.Singleton {
+ singleton := &hostFakeSingleton{}
+ singleton.init()
+ return singleton
+}
+
+func (c *hostFakeSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ if !ctx.DeviceConfig().HostFakeSnapshotEnabled() {
+ return
+ }
+ // Find all host binary modules add 'fake' versions to snapshot
+ var outputs android.Paths
+ seen := make(map[string]bool)
+ var jsonData []SnapshotJsonFlags
+ ctx.VisitAllModules(func(module android.Module) {
+ if module.Target().Os != ctx.Config().BuildOSTarget.Os {
+ return
+ }
+ if module.Target().Arch.ArchType != ctx.Config().BuildOSTarget.Arch.ArchType {
+ return
+ }
+
+ if android.IsModulePrebuilt(module) {
+ return
+ }
+
+ if !module.Enabled() || module.IsHideFromMake() {
+ return
+ }
+ apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
+ if !apexInfo.IsForPlatform() {
+ return
+ }
+ path := hostBinToolPath(module)
+ if path.Valid() && path.String() != "" {
+ outFile := filepath.Join(c.snapshotDir, path.String())
+ if !seen[outFile] {
+ seen[outFile] = true
+ outputs = append(outputs, WriteStringToFileRule(ctx, "", outFile))
+ jsonData = append(jsonData, *hostBinJsonDesc(module))
+ }
+ }
+ })
+
+ marsh, err := json.Marshal(jsonData)
+ if err != nil {
+ ctx.Errorf("host fake snapshot json marshal failure: %#v", err)
+ return
+ }
+ outputs = append(outputs, WriteStringToFileRule(ctx, string(marsh), filepath.Join(c.snapshotDir, "host_snapshot.json")))
+ c.zipFile = zipSnapshot(ctx, c.snapshotDir, c.snapshotDir, outputs)
+
+}
+func (c *hostFakeSingleton) MakeVars(ctx android.MakeVarsContext) {
+ if !c.zipFile.Valid() {
+ return
+ }
+ ctx.Phony(
+ "host-fake-snapshot",
+ c.zipFile.Path())
+
+ ctx.DistForGoal(
+ "host-fake-snapshot",
+ c.zipFile.Path())
+
+}