Allow calling ctx.DistForGoal from GenerateAndroidBuildActions
Right now you have to dist files in either the AndroidMk stuff,
or in MakeVars providers. Allow calling it from
GenerateAndroidBuildActions so that we can further remove our reliance
on make.
Bug: 395184523
Test: m nothing --no-skip-soong-tests
Change-Id: I6ad12fa89896b86c333fc2d23eaf4f77466e42a3
diff --git a/android/Android.bp b/android/Android.bp
index d27a8fa..75027b1 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -141,6 +141,7 @@
"license_kind_test.go",
"license_test.go",
"licenses_test.go",
+ "makevars_test.go",
"module_test.go",
"mutator_test.go",
"namespace_test.go",
diff --git a/android/androidmk.go b/android/androidmk.go
index 2153c27..db1b9e7 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -768,7 +768,7 @@
pctx: provider.pctx,
}
provider.call(mctx)
- if contribution := getMakeVarsDistContributions(mctx); contribution != nil {
+ if contribution := distsToDistContributions(mctx.dists); contribution != nil {
allDistContributions = append(allDistContributions, *contribution)
}
}
@@ -851,24 +851,24 @@
}
}
-func getMakeVarsDistContributions(mctx *makeVarsContext) *distContributions {
- if len(mctx.dists) == 0 {
+func distsToDistContributions(dists []dist) *distContributions {
+ if len(dists) == 0 {
return nil
}
copyGoals := []*copiesForGoals{}
- for _, dist := range mctx.dists {
+ for _, dist := range dists {
for _, goal := range dist.goals {
- copy := &copiesForGoals{}
- copy.goals = goal
- copy.copies = dist.paths
- copyGoals = append(copyGoals, copy)
+ copyGoals = append(copyGoals, &copiesForGoals{
+ goals: goal,
+ copies: dist.paths,
+ })
}
}
- contribution := &distContributions{}
- contribution.copiesForGoals = copyGoals
- return contribution
+ return &distContributions{
+ copiesForGoals: copyGoals,
+ }
}
// getSoongOnlyDataFromMods gathers data from the given modules needed in soong-only builds.
@@ -877,6 +877,12 @@
var allDistContributions []distContributions
var moduleInfoJSONs []*ModuleInfoJSON
for _, mod := range mods {
+ if distInfo, ok := OtherModuleProvider(ctx, mod, DistProvider); ok {
+ if contribution := distsToDistContributions(distInfo.Dists); contribution != nil {
+ allDistContributions = append(allDistContributions, *contribution)
+ }
+ }
+
if amod, ok := mod.(Module); ok && shouldSkipAndroidMkProcessing(ctx, amod.base()) {
continue
}
@@ -946,7 +952,7 @@
continue
}
x.MakeVars(mctx)
- if contribution := getMakeVarsDistContributions(mctx); contribution != nil {
+ if contribution := distsToDistContributions(mctx.dists); contribution != nil {
allDistContributions = append(allDistContributions, *contribution)
}
}
@@ -957,7 +963,7 @@
pctx: pctx,
}
x.MakeVars(mctx)
- if contribution := getMakeVarsDistContributions(mctx); contribution != nil {
+ if contribution := distsToDistContributions(mctx.dists); contribution != nil {
allDistContributions = append(allDistContributions, *contribution)
}
}
diff --git a/android/makevars.go b/android/makevars.go
index c8eb5e4..3a60bbb 100644
--- a/android/makevars.go
+++ b/android/makevars.go
@@ -185,6 +185,7 @@
type makeVarsSingleton struct {
varsForTesting []makeVarsVariable
installsForTesting []byte
+ lateForTesting []byte
}
type makeVarsProvider struct {
@@ -285,6 +286,10 @@
katiVintfManifestInstalls = append(katiVintfManifestInstalls, info.KatiVintfInstalls...)
katiSymlinks = append(katiSymlinks, info.KatiSymlinks...)
}
+
+ if distInfo, ok := OtherModuleProvider(ctx, m, DistProvider); ok {
+ dists = append(dists, distInfo.Dists...)
+ }
})
compareKatiInstalls := func(a, b katiInstall) int {
@@ -354,6 +359,7 @@
if ctx.Config().RunningInsideUnitTest() {
s.varsForTesting = vars
s.installsForTesting = installsBytes
+ s.lateForTesting = lateOutBytes
}
}
diff --git a/android/makevars_test.go b/android/makevars_test.go
new file mode 100644
index 0000000..5e4499f
--- /dev/null
+++ b/android/makevars_test.go
@@ -0,0 +1,42 @@
+package android
+
+import (
+ "regexp"
+ "testing"
+)
+
+func TestDistFilesInGenerateAndroidBuildActions(t *testing.T) {
+ result := GroupFixturePreparers(
+ FixtureRegisterWithContext(func(ctx RegistrationContext) {
+ ctx.RegisterModuleType("my_module_type", newDistFileModule)
+ }),
+ FixtureModifyConfig(SetKatiEnabledForTests),
+ PrepareForTestWithMakevars,
+ ).RunTestWithBp(t, `
+ my_module_type {
+ name: "foo",
+ }
+ `)
+
+ 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)
+ }
+}
+
+type distFileModule struct {
+ ModuleBase
+}
+
+func newDistFileModule() Module {
+ m := &distFileModule{}
+ InitAndroidModule(m)
+ return m
+}
+
+func (m *distFileModule) GenerateAndroidBuildActions(ctx ModuleContext) {
+ out := PathForModuleOut(ctx, "my_file.txt")
+ WriteFileRule(ctx, out, "Hello, world!")
+ ctx.DistForGoal("my_goal", out)
+}
diff --git a/android/module.go b/android/module.go
index 39a1654..80275a3 100644
--- a/android/module.go
+++ b/android/module.go
@@ -1925,6 +1925,12 @@
var HostToolProviderInfoProvider = blueprint.NewProvider[HostToolProviderInfo]()
+type DistInfo struct {
+ Dists []dist
+}
+
+var DistProvider = blueprint.NewProvider[DistInfo]()
+
type SourceFileGenerator interface {
GeneratedSourceFiles() Paths
GeneratedHeaderDirs() Paths
@@ -2222,6 +2228,13 @@
Phonies: ctx.phonies,
})
}
+
+ if len(ctx.dists) > 0 {
+ SetProvider(ctx, DistProvider, DistInfo{
+ Dists: ctx.dists,
+ })
+ }
+
buildComplianceMetadataProvider(ctx, m)
commonData := CommonModuleInfo{
diff --git a/android/module_context.go b/android/module_context.go
index d3c5370..1851e7c 100644
--- a/android/module_context.go
+++ b/android/module_context.go
@@ -255,6 +255,24 @@
setContainersInfo(info ContainersInfo)
setAconfigPaths(paths Paths)
+
+ // 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 moduleContext struct {
@@ -312,6 +330,8 @@
// complianceMetadataInfo is for different module types to dump metadata.
// See android.ModuleContext interface.
complianceMetadataInfo *ComplianceMetadataInfo
+
+ dists []dist
}
var _ ModuleContext = &moduleContext{}
@@ -959,3 +979,32 @@
func (m *moduleContext) setContainersInfo(info ContainersInfo) {
m.containersInfo = info
}
+
+func (c *moduleContext) DistForGoal(goal string, paths ...Path) {
+ c.DistForGoals([]string{goal}, paths...)
+}
+
+func (c *moduleContext) DistForGoalWithFilename(goal string, path Path, filename string) {
+ c.DistForGoalsWithFilename([]string{goal}, path, filename)
+}
+
+func (c *moduleContext) DistForGoals(goals []string, paths ...Path) {
+ var copies distCopies
+ for _, path := range paths {
+ copies = append(copies, distCopy{
+ from: path,
+ dest: path.Base(),
+ })
+ }
+ c.dists = append(c.dists, dist{
+ goals: slices.Clone(goals),
+ paths: copies,
+ })
+}
+
+func (c *moduleContext) DistForGoalsWithFilename(goals []string, path Path, filename string) {
+ c.dists = append(c.dists, dist{
+ goals: slices.Clone(goals),
+ paths: distCopies{{from: path, dest: filename}},
+ })
+}