Fix few issues with filegroups
Bug: http://b/64121881
Bug: http://b/78188880
- Allow filegroup's properties to be extended by a LoadHook
- Support a filegroup (':module') in a prebuilt's 'Srcs' property to
export files from a different path as the prebuilt's sources.
This change also includes a refactoring that moves genrule/filegroup.go
to android/filegroup.go so that FileGroupFactory is visible in
prebuilt_test.go.
Test: Test
https://android-review.googlesource.com/c/platform/development/+/469159
in clang-tools branch on Linux, Darwin. Test regular build in
aosp/master.
Change-Id: I3ff6215ab2e62955f039fd1086c31f1bd50ebcf6
diff --git a/android/filegroup.go b/android/filegroup.go
new file mode 100644
index 0000000..b284ce0
--- /dev/null
+++ b/android/filegroup.go
@@ -0,0 +1,94 @@
+// Copyright 2016 Google Inc. All rights reserved.
+//
+// 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 android
+
+import (
+ "io"
+ "strings"
+ "text/template"
+)
+
+func init() {
+ RegisterModuleType("filegroup", FileGroupFactory)
+}
+
+type fileGroupProperties struct {
+ // srcs lists files that will be included in this filegroup
+ Srcs []string
+
+ Exclude_srcs []string
+
+ // The base path to the files. May be used by other modules to determine which portion
+ // of the path to use. For example, when a filegroup is used as data in a cc_test rule,
+ // the base path is stripped off the path and the remaining path is used as the
+ // installation directory.
+ Path *string
+
+ // Create a make variable with the specified name that contains the list of files in the
+ // filegroup, relative to the root of the source tree.
+ Export_to_make_var *string
+}
+
+type fileGroup struct {
+ ModuleBase
+ properties fileGroupProperties
+ srcs Paths
+}
+
+var _ SourceFileProducer = (*fileGroup)(nil)
+
+// filegroup modules contain a list of files, and can be used to export files across package
+// boundaries. filegroups (and genrules) can be referenced from srcs properties of other modules
+// using the syntax ":module".
+func FileGroupFactory() Module {
+ module := &fileGroup{}
+ module.AddProperties(&module.properties)
+ InitAndroidModule(module)
+ return module
+}
+
+func (fg *fileGroup) DepsMutator(ctx BottomUpMutatorContext) {
+ ExtractSourcesDeps(ctx, fg.properties.Srcs)
+ ExtractSourcesDeps(ctx, fg.properties.Exclude_srcs)
+}
+
+func (fg *fileGroup) GenerateAndroidBuildActions(ctx ModuleContext) {
+ fg.srcs = ctx.ExpandSourcesSubDir(fg.properties.Srcs, fg.properties.Exclude_srcs, String(fg.properties.Path))
+}
+
+func (fg *fileGroup) Srcs() Paths {
+ return append(Paths{}, fg.srcs...)
+}
+
+var androidMkTemplate = template.Must(template.New("filegroup").Parse(`
+ifdef {{.makeVar}}
+ $(error variable {{.makeVar}} set by soong module is already set in make)
+endif
+{{.makeVar}} := {{.value}}
+.KATI_READONLY := {{.makeVar}}
+`))
+
+func (fg *fileGroup) AndroidMk() AndroidMkData {
+ return AndroidMkData{
+ Custom: func(w io.Writer, name, prefix, moduleDir string, data AndroidMkData) {
+ if makeVar := String(fg.properties.Export_to_make_var); makeVar != "" {
+ androidMkTemplate.Execute(w, map[string]string{
+ "makeVar": makeVar,
+ "value": strings.Join(fg.srcs.Strings(), " "),
+ })
+ }
+ },
+ }
+}
diff --git a/android/module.go b/android/module.go
index a011f57..3bd256a 100644
--- a/android/module.go
+++ b/android/module.go
@@ -323,6 +323,7 @@
&base.nameProperties,
&base.commonProperties,
&base.variableProperties)
+ base.customizableProperties = m.GetProperties()
}
func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
diff --git a/android/prebuilt.go b/android/prebuilt.go
index 9356aab..47c5cf5 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -59,7 +59,9 @@
return nil
}
- return PathForModuleSrc(ctx, (*p.srcs)[0])
+ // Return the singleton source after expanding any filegroup in the
+ // sources.
+ return ctx.ExpandSource((*p.srcs)[0], "")
}
func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) {
@@ -79,7 +81,7 @@
func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
- ctx.BottomUp("prebuilt_replace", PrebuiltReplaceMutator).Parallel()
+ ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel()
}
// prebuiltMutator ensures that there is always a module with an undecorated name, and marks
@@ -119,10 +121,12 @@
}
}
-// PrebuiltReplaceMutator replaces dependencies on the source module with dependencies on the
-// prebuilt when both modules exist and the prebuilt should be used. When the prebuilt should not
-// be used, disable installing it.
-func PrebuiltReplaceMutator(ctx BottomUpMutatorContext) {
+// PrebuiltPostDepsMutator does two operations. It replace dependencies on the
+// source module with dependencies on the prebuilt when both modules exist and
+// the prebuilt should be used. When the prebuilt should not be used, disable
+// installing it. Secondly, it also adds a sourcegroup to any filegroups found
+// in the prebuilt's 'Srcs' property.
+func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) {
if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
p := m.Prebuilt()
name := m.base().BaseModuleName()
@@ -133,6 +137,9 @@
} else {
m.SkipInstall()
}
+ if len(*p.srcs) > 0 {
+ ExtractSourceDeps(ctx, &(*p.srcs)[0])
+ }
}
}
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 69ce16a..cd1ffae 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -109,6 +109,19 @@
}`,
prebuilt: false,
},
+ {
+ name: "prebuilt file from filegroup preferred",
+ modules: `
+ filegroup {
+ name: "fg",
+ }
+ prebuilt {
+ name: "bar",
+ prefer: true,
+ srcs: [":fg"],
+ }`,
+ prebuilt: true,
+ },
}
func TestPrebuilts(t *testing.T) {
@@ -125,6 +138,7 @@
ctx := NewTestContext()
ctx.PreArchMutators(RegisterPrebuiltsPreArchMutators)
ctx.PostDepsMutators(RegisterPrebuiltsPostDepsMutators)
+ ctx.RegisterModuleType("filegroup", ModuleFactoryAdaptor(FileGroupFactory))
ctx.RegisterModuleType("prebuilt", ModuleFactoryAdaptor(newPrebuiltModule))
ctx.RegisterModuleType("source", ModuleFactoryAdaptor(newSourceModule))
ctx.Register()