summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Cole Faust <colefaust@google.com> 2025-02-11 13:32:51 -0800
committer Cole Faust <colefaust@google.com> 2025-02-11 13:32:51 -0800
commitf2aab5e73fd046dac104144b23d21b566a18cae3 (patch)
treed83adcba7bf1501d733fcfb20c21aafb03aa31a0
parentc8c2553d639e1d2e7e66195ddbe048351180ec39 (diff)
Allow calling ctx.DistForGoal from Singletons
Right now singletons have to dist files in either in MakeVars providers. Allow dist from GenerateBuildActions so that we can further remove our reliance on make. Bug: 395184523 Test: m nothing --no-skip-soong-tests Change-Id: Ie3004c2b038b45754279dfadcb7f7455ae740136
-rw-r--r--android/androidmk.go7
-rw-r--r--android/makevars.go5
-rw-r--r--android/makevars_test.go56
-rw-r--r--android/singleton.go70
4 files changed, 137 insertions, 1 deletions
diff --git a/android/androidmk.go b/android/androidmk.go
index 9c72606f4..db838f0d3 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -791,6 +791,13 @@ func (so *soongOnlyAndroidMkSingleton) soongOnlyBuildActions(ctx SingletonContex
}
}
+ singletonDists := getSingletonDists(ctx.Config())
+ singletonDists.lock.Lock()
+ if contribution := distsToDistContributions(singletonDists.dists); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ singletonDists.lock.Unlock()
+
// Build module-info.json. Only in builds with HasDeviceProduct(), as we need a named
// device to have a TARGET_OUT folder.
if ctx.Config().HasDeviceProduct() {
diff --git a/android/makevars.go b/android/makevars.go
index 3a60bbb63..45fd0d065 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -266,6 +266,11 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
dists = append(dists, mctx.dists...)
}
+ singletonDists := getSingletonDists(ctx.Config())
+ singletonDists.lock.Lock()
+ dists = append(dists, singletonDists.dists...)
+ singletonDists.lock.Unlock()
+
ctx.VisitAllModules(func(m Module) {
if provider, ok := m.(ModuleMakeVarsProvider); ok && m.Enabled(ctx) {
mctx := &makeVarsContext{
diff --git a/android/makevars_test.go b/android/makevars_test.go
index 5e4499fbb..95e4b59c2 100644
--- a/android/makevars_test.go
+++ b/android/makevars_test.go
@@ -9,6 +9,8 @@ func TestDistFilesInGenerateAndroidBuildActions(t *testing.T) {
result := GroupFixturePreparers(
FixtureRegisterWithContext(func(ctx RegistrationContext) {
ctx.RegisterModuleType("my_module_type", newDistFileModule)
+ ctx.RegisterParallelSingletonType("my_singleton", newDistFileSingleton)
+ ctx.RegisterParallelSingletonModuleType("my_singleton_module", newDistFileSingletonModule)
}),
FixtureModifyConfig(SetKatiEnabledForTests),
PrepareForTestWithMakevars,
@@ -16,12 +18,27 @@ func TestDistFilesInGenerateAndroidBuildActions(t *testing.T) {
my_module_type {
name: "foo",
}
+ my_singleton_module {
+ name: "bar"
+ }
`)
lateContents := string(result.SingletonForTests("makevars").Singleton().(*makeVarsSingleton).lateForTesting)
matched, err := regexp.MatchString(`call dist-for-goals,my_goal,.*/my_file.txt:my_file.txt\)`, lateContents)
if err != nil || !matched {
- t.Fatalf("Expected a dist, but got: %s", lateContents)
+ t.Fatalf("Expected a dist of my_file.txt, but got: %s", lateContents)
+ }
+ matched, err = regexp.MatchString(`call dist-for-goals,my_singleton_goal,.*/my_singleton_file.txt:my_singleton_file.txt\)`, lateContents)
+ if err != nil || !matched {
+ t.Fatalf("Expected a dist of my_singleton_file.txt, but got: %s", lateContents)
+ }
+ matched, err = regexp.MatchString(`call dist-for-goals,my_singleton_module_module_goal,.*/my_singleton_module_module_file.txt:my_singleton_module_module_file.txt\)`, lateContents)
+ if err != nil || !matched {
+ t.Fatalf("Expected a dist of my_singleton_module_module_file.txt, but got: %s", lateContents)
+ }
+ matched, err = regexp.MatchString(`call dist-for-goals,my_singleton_module_singleton_goal,.*/my_singleton_module_singleton_file.txt:my_singleton_module_singleton_file.txt\)`, lateContents)
+ if err != nil || !matched {
+ t.Fatalf("Expected a dist of my_singleton_module_singleton_file.txt, but got: %s", lateContents)
}
}
@@ -40,3 +57,40 @@ func (m *distFileModule) GenerateAndroidBuildActions(ctx ModuleContext) {
WriteFileRule(ctx, out, "Hello, world!")
ctx.DistForGoal("my_goal", out)
}
+
+type distFileSingleton struct {
+}
+
+func newDistFileSingleton() Singleton {
+ return &distFileSingleton{}
+}
+
+func (d *distFileSingleton) GenerateBuildActions(ctx SingletonContext) {
+ out := PathForOutput(ctx, "my_singleton_file.txt")
+ WriteFileRule(ctx, out, "Hello, world!")
+ ctx.DistForGoal("my_singleton_goal", out)
+}
+
+type distFileSingletonModule struct {
+ SingletonModuleBase
+}
+
+func newDistFileSingletonModule() SingletonModule {
+ sm := &distFileSingletonModule{}
+ InitAndroidSingletonModule(sm)
+ return sm
+}
+
+// GenerateAndroidBuildActions implements SingletonModule.
+func (d *distFileSingletonModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ out := PathForModuleOut(ctx, "my_singleton_module_module_file.txt")
+ WriteFileRule(ctx, out, "Hello, world!")
+ ctx.DistForGoal("my_singleton_module_module_goal", out)
+}
+
+// GenerateSingletonBuildActions implements SingletonModule.
+func (d *distFileSingletonModule) GenerateSingletonBuildActions(ctx SingletonContext) {
+ out := PathForOutput(ctx, "my_singleton_module_singleton_file.txt")
+ WriteFileRule(ctx, out, "Hello, world!")
+ ctx.DistForGoal("my_singleton_module_singleton_goal", out)
+}
diff --git a/android/singleton.go b/android/singleton.go
index 0754b0ccb..df2204591 100644
--- a/android/singleton.go
+++ b/android/singleton.go
@@ -15,6 +15,9 @@
package android
import (
+ "slices"
+ "sync"
+
"github.com/google/blueprint"
)
@@ -97,6 +100,24 @@ type SingletonContext interface {
// HasMutatorFinished returns true if the given mutator has finished running.
// It will panic if given an invalid mutator name.
HasMutatorFinished(mutatorName string) bool
+
+ // DistForGoals creates a rule to copy one or more Paths to the artifacts
+ // directory on the build server when any of the specified goals are built.
+ DistForGoal(goal string, paths ...Path)
+
+ // DistForGoalWithFilename creates a rule to copy a Path to the artifacts
+ // directory on the build server with the given filename when the specified
+ // goal is built.
+ DistForGoalWithFilename(goal string, path Path, filename string)
+
+ // DistForGoals creates a rule to copy one or more Paths to the artifacts
+ // directory on the build server when any of the specified goals are built.
+ DistForGoals(goals []string, paths ...Path)
+
+ // DistForGoalsWithFilename creates a rule to copy a Path to the artifacts
+ // directory on the build server with the given filename when any of the
+ // specified goals are built.
+ DistForGoalsWithFilename(goals []string, path Path, filename string)
}
type singletonAdaptor struct {
@@ -118,6 +139,13 @@ func (s *singletonAdaptor) GenerateBuildActions(ctx blueprint.SingletonContext)
s.buildParams = sctx.buildParams
s.ruleParams = sctx.ruleParams
+
+ if len(sctx.dists) > 0 {
+ dists := getSingletonDists(sctx.Config())
+ dists.lock.Lock()
+ defer dists.lock.Unlock()
+ dists.dists = append(dists.dists, sctx.dists...)
+ }
}
func (s *singletonAdaptor) BuildParamsForTests() []BuildParams {
@@ -128,6 +156,19 @@ func (s *singletonAdaptor) RuleParamsForTests() map[blueprint.Rule]blueprint.Rul
return s.ruleParams
}
+var singletonDistsKey = NewOnceKey("singletonDistsKey")
+
+type singletonDistsAndLock struct {
+ dists []dist
+ lock sync.Mutex
+}
+
+func getSingletonDists(config Config) *singletonDistsAndLock {
+ return config.Once(singletonDistsKey, func() interface{} {
+ return &singletonDistsAndLock{}
+ }).(*singletonDistsAndLock)
+}
+
type Singleton interface {
GenerateBuildActions(SingletonContext)
}
@@ -137,6 +178,7 @@ type singletonContextAdaptor struct {
buildParams []BuildParams
ruleParams map[blueprint.Rule]blueprint.RuleParams
+ dists []dist
}
func (s *singletonContextAdaptor) blueprintSingletonContext() blueprint.SingletonContext {
@@ -315,3 +357,31 @@ func (s *singletonContextAdaptor) OtherModulePropertyErrorf(module Module, prope
func (s *singletonContextAdaptor) HasMutatorFinished(mutatorName string) bool {
return s.blueprintSingletonContext().HasMutatorFinished(mutatorName)
}
+func (s *singletonContextAdaptor) DistForGoal(goal string, paths ...Path) {
+ s.DistForGoals([]string{goal}, paths...)
+}
+
+func (s *singletonContextAdaptor) DistForGoalWithFilename(goal string, path Path, filename string) {
+ s.DistForGoalsWithFilename([]string{goal}, path, filename)
+}
+
+func (s *singletonContextAdaptor) DistForGoals(goals []string, paths ...Path) {
+ var copies distCopies
+ for _, path := range paths {
+ copies = append(copies, distCopy{
+ from: path,
+ dest: path.Base(),
+ })
+ }
+ s.dists = append(s.dists, dist{
+ goals: slices.Clone(goals),
+ paths: copies,
+ })
+}
+
+func (s *singletonContextAdaptor) DistForGoalsWithFilename(goals []string, path Path, filename string) {
+ s.dists = append(s.dists, dist{
+ goals: slices.Clone(goals),
+ paths: distCopies{{from: path, dest: filename}},
+ })
+}