Experimental code to support build action caching.
Bug: 335718784
Test: build locally
Change-Id: Icc1f1fb15f9fe305e95dd51e2e7aff1e9cbf340c
diff --git a/android/module.go b/android/module.go
index dc585d2..7e73f70 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1913,9 +1913,54 @@
return
}
- m.module.GenerateAndroidBuildActions(ctx)
- if ctx.Failed() {
- return
+ incrementalAnalysis := false
+ incrementalEnabled := false
+ var cacheKey *blueprint.BuildActionCacheKey = nil
+ var incrementalModule *blueprint.Incremental = nil
+ if ctx.bp.GetIncrementalEnabled() {
+ if im, ok := m.module.(blueprint.Incremental); ok {
+ incrementalModule = &im
+ incrementalEnabled = im.IncrementalSupported()
+ incrementalAnalysis = ctx.bp.GetIncrementalAnalysis() && incrementalEnabled
+ }
+ }
+ if incrementalEnabled {
+ hash, err := proptools.CalculateHash(m.GetProperties())
+ if err != nil {
+ ctx.ModuleErrorf("failed to calculate properties hash: %s", err)
+ return
+ }
+ cacheInput := new(blueprint.BuildActionCacheInput)
+ cacheInput.PropertiesHash = hash
+ ctx.VisitDirectDeps(func(module Module) {
+ cacheInput.ProvidersHash =
+ append(cacheInput.ProvidersHash, ctx.bp.OtherModuleProviderInitialValueHashes(module))
+ })
+ hash, err = proptools.CalculateHash(&cacheInput)
+ if err != nil {
+ ctx.ModuleErrorf("failed to calculate cache input hash: %s", err)
+ return
+ }
+ cacheKey = &blueprint.BuildActionCacheKey{
+ Id: ctx.bp.ModuleId(),
+ InputHash: hash,
+ }
+ }
+
+ restored := false
+ if incrementalAnalysis && cacheKey != nil {
+ restored = ctx.bp.RestoreBuildActions(cacheKey, incrementalModule)
+ }
+
+ if !restored {
+ m.module.GenerateAndroidBuildActions(ctx)
+ if ctx.Failed() {
+ return
+ }
+ }
+
+ if incrementalEnabled && cacheKey != nil {
+ ctx.bp.CacheBuildActions(cacheKey, incrementalModule)
}
// Create the set of tagged dist files after calling GenerateAndroidBuildActions
diff --git a/android/paths.go b/android/paths.go
index edc0700..adbee70 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -15,6 +15,9 @@
package android
import (
+ "bytes"
+ "encoding/gob"
+ "errors"
"fmt"
"os"
"path/filepath"
@@ -1068,6 +1071,28 @@
rel string
}
+func (p basePath) GobEncode() ([]byte, error) {
+ w := new(bytes.Buffer)
+ encoder := gob.NewEncoder(w)
+ err := errors.Join(encoder.Encode(p.path), encoder.Encode(p.rel))
+ if err != nil {
+ return nil, err
+ }
+
+ return w.Bytes(), nil
+}
+
+func (p *basePath) GobDecode(data []byte) error {
+ r := bytes.NewBuffer(data)
+ decoder := gob.NewDecoder(r)
+ err := errors.Join(decoder.Decode(&p.path), decoder.Decode(&p.rel))
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
func (p basePath) Ext() string {
return filepath.Ext(p.path)
}
@@ -1306,6 +1331,28 @@
fullPath string
}
+func (p OutputPath) GobEncode() ([]byte, error) {
+ w := new(bytes.Buffer)
+ encoder := gob.NewEncoder(w)
+ err := errors.Join(encoder.Encode(p.basePath), encoder.Encode(p.soongOutDir), encoder.Encode(p.fullPath))
+ if err != nil {
+ return nil, err
+ }
+
+ return w.Bytes(), nil
+}
+
+func (p *OutputPath) GobDecode(data []byte) error {
+ r := bytes.NewBuffer(data)
+ decoder := gob.NewDecoder(r)
+ err := errors.Join(decoder.Decode(&p.basePath), decoder.Decode(&p.soongOutDir), decoder.Decode(&p.fullPath))
+ if err != nil {
+ return err
+ }
+
+ return nil
+}
+
func (p OutputPath) withRel(rel string) OutputPath {
p.basePath = p.basePath.withRel(rel)
p.fullPath = filepath.Join(p.fullPath, rel)