1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
// 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)
}
// Add prebuilt information to snapshot data
type hostSnapshotFakeJsonFlags struct {
SnapshotJsonFlags
Prebuilt bool `json:",omitempty"`
}
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 []hostSnapshotFakeJsonFlags
prebuilts := make(map[string]bool)
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) {
// Add non-prebuilt module name to map of prebuilts
prebuilts[android.RemoveOptionalPrebuiltPrefix(module.Name())] = true
return
}
if !module.Enabled() || module.IsHideFromMake() {
return
}
apexInfo := ctx.ModuleProvider(module, android.ApexInfoProvider).(android.ApexInfo)
if !apexInfo.IsForPlatform() {
return
}
path := hostToolPath(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, hostSnapshotFakeJsonFlags{*hostJsonDesc(module), false})
}
}
})
// Update any module prebuilt information
for idx, _ := range jsonData {
if _, ok := prebuilts[jsonData[idx].ModuleName]; ok {
// Prebuilt exists for this module
jsonData[idx].Prebuilt = true
}
}
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())
}
|