123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- // 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.RegisterParallelSingletonType("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())
- }
|