Support filegroups

filegroup is a module that contains 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".

Test: m -j
Change-Id: I3d6fc4819c0b4225b474e0ad42f0d947f55a5961
This commit is contained in:
Colin Cross
2016-12-13 15:23:47 -08:00
parent 35e3972068
commit 068e0feace
7 changed files with 114 additions and 3 deletions

View File

@@ -159,6 +159,7 @@ bootstrap_go_package {
"soong-android", "soong-android",
], ],
srcs: [ srcs: [
"genrule/filegroup.go",
"genrule/genrule.go", "genrule/genrule.go",
], ],
pluginFor: ["soong_build"], pluginFor: ["soong_build"],

View File

@@ -8,7 +8,9 @@ declarative descriptions of modules to build.
By design, Android.bp files are very simple. There are no conditionals or By design, Android.bp files are very simple. There are no conditionals or
control flow statements - any complexity is handled in build logic written in control flow statements - any complexity is handled in build logic written in
Go. Go. The syntax and semantics of Android.bp files are intentionally similar
to [Bazel BUILD files](https://www.bazel.io/versions/master/docs/be/overview.html)
when possible.
### Modules ### Modules

View File

@@ -711,6 +711,38 @@ func findStringInSlice(str string, slice []string) int {
return -1 return -1
} }
func SrcIsModule(s string) string {
if len(s) > 1 && s[0] == ':' {
return s[1:]
}
return ""
}
type sourceDependencyTag struct {
blueprint.BaseDependencyTag
}
var SourceDepTag sourceDependencyTag
// Returns a list of modules that must be depended on to satisfy filegroup or generated sources
// modules listed in srcFiles using ":module" syntax
func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) {
var deps []string
for _, s := range srcFiles {
if m := SrcIsModule(s); m != "" {
deps = append(deps, m)
}
}
ctx.AddDependency(ctx.Module(), SourceDepTag, deps...)
}
type SourceFileProducer interface {
Srcs() Paths
}
// Returns a list of paths expanded from globs and modules referenced using ":module" syntax.
// ExpandSourceDeps must have already been called during the dependency resolution phase.
func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths { func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Paths {
prefix := PathForModuleSrc(ctx).String() prefix := PathForModuleSrc(ctx).String()
for i, e := range excludes { for i, e := range excludes {
@@ -724,7 +756,14 @@ func (ctx *androidModuleContext) ExpandSources(srcFiles, excludes []string) Path
globbedSrcFiles := make(Paths, 0, len(srcFiles)) globbedSrcFiles := make(Paths, 0, len(srcFiles))
for _, s := range srcFiles { for _, s := range srcFiles {
if pathtools.IsGlob(s) { if m := SrcIsModule(s); m != "" {
module := ctx.GetDirectDepWithTag(m, SourceDepTag)
if srcProducer, ok := module.(SourceFileProducer); ok {
globbedSrcFiles = append(globbedSrcFiles, srcProducer.Srcs()...)
} else {
ctx.ModuleErrorf("srcs dependency %q is not a source file producing module", m)
}
} else if pathtools.IsGlob(s) {
globbedSrcFiles = append(globbedSrcFiles, ctx.Glob(filepath.Join(prefix, s), excludes)...) globbedSrcFiles = append(globbedSrcFiles, ctx.Glob(filepath.Join(prefix, s), excludes)...)
} else { } else {
globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s)) globbedSrcFiles = append(globbedSrcFiles, PathForModuleSrc(ctx, s))

View File

@@ -833,7 +833,7 @@ func (c *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
cc, _ := m.(*Module) cc, _ := m.(*Module)
if cc == nil { if cc == nil {
switch tag { switch tag {
case android.DefaultsDepTag: case android.DefaultsDepTag, android.SourceDepTag:
case genSourceDepTag: case genSourceDepTag:
if genRule, ok := m.(genrule.SourceFileGenerator); ok { if genRule, ok := m.(genrule.SourceFileGenerator); ok {
depPaths.GeneratedSources = append(depPaths.GeneratedSources, depPaths.GeneratedSources = append(depPaths.GeneratedSources,

View File

@@ -29,6 +29,8 @@ import (
type BaseCompilerProperties struct { type BaseCompilerProperties struct {
// list of source files used to compile the C/C++ module. May be .c, .cpp, or .S files. // list of source files used to compile the C/C++ module. May be .c, .cpp, or .S files.
// srcs may reference the outputs of other modules that produce source files like genrule
// or filegroup using the syntax ":module".
Srcs []string `android:"arch_variant"` Srcs []string `android:"arch_variant"`
// list of source files that should not be used to build the C/C++ module. // list of source files that should not be used to build the C/C++ module.
@@ -133,6 +135,8 @@ func (compiler *baseCompiler) compilerDeps(ctx DepsContext, deps Deps) Deps {
deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...) deps.GeneratedSources = append(deps.GeneratedSources, compiler.Properties.Generated_sources...)
deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...) deps.GeneratedHeaders = append(deps.GeneratedHeaders, compiler.Properties.Generated_headers...)
android.ExtractSourcesDeps(ctx, compiler.Properties.Srcs)
if compiler.hasSrcExt(".proto") { if compiler.hasSrcExt(".proto") {
deps = protoDeps(ctx, deps, &compiler.Proto) deps = protoDeps(ctx, deps, &compiler.Proto)
} }

61
genrule/filegroup.go Normal file
View File

@@ -0,0 +1,61 @@
// 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 genrule
import (
"github.com/google/blueprint"
"android/soong/android"
)
func init() {
android.RegisterModuleType("filegroup", fileGroupFactory)
}
type fileGroupProperties struct {
// srcs lists files that will be included in this filegroup
Srcs []string
Exclude_srcs []string
}
type fileGroup struct {
android.ModuleBase
properties fileGroupProperties
srcs android.Paths
}
var _ android.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() (blueprint.Module, []interface{}) {
module := &fileGroup{}
return android.InitAndroidModule(module, &module.properties)
}
func (fg *fileGroup) DepsMutator(ctx android.BottomUpMutatorContext) {
android.ExtractSourcesDeps(ctx, fg.properties.Srcs)
}
func (fg *fileGroup) GenerateAndroidBuildActions(ctx android.ModuleContext) {
fg.srcs = ctx.ExpandSources(fg.properties.Srcs, fg.properties.Exclude_srcs)
}
func (fg *fileGroup) Srcs() android.Paths {
return fg.srcs
}

View File

@@ -96,6 +96,10 @@ func (g *generator) GeneratedSourceFiles() android.Paths {
return g.outputFiles return g.outputFiles
} }
func (g *generator) Srcs() android.Paths {
return g.outputFiles
}
func (g *generator) GeneratedHeaderDirs() android.Paths { func (g *generator) GeneratedHeaderDirs() android.Paths {
return g.exportedIncludeDirs return g.exportedIncludeDirs
} }