Add gensrcs module type

gensrcs allows sources to be generated by a specified command.

Change-Id: I725086fcdcd72bfe6c07fb8903e7b520678a247f
This commit is contained in:
Colin Cross 2015-03-18 13:28:46 -07:00
parent 70a255f3c9
commit 5049f02e60
7 changed files with 200 additions and 15 deletions

View File

@ -18,6 +18,7 @@ bootstrap_go_binary {
"soong-cc",
"soong-common",
"soong-config",
"soong-genrule",
],
srcs: [
"cmd/soong_build/main.go",
@ -85,6 +86,7 @@ bootstrap_go_package {
"blueprint-pathtools",
"soong-common",
"soong-config",
"soong-genrule",
],
srcs: [
"cc/builder.go",
@ -100,6 +102,19 @@ bootstrap_go_package {
],
}
bootstrap_go_package {
name: "soong-genrule",
pkgPath: "android/soong/genrule",
deps: [
"blueprint",
"blueprint-pathtools",
"soong-common",
"soong-config",
],
srcs: [
"genrule/genrule.go",
],
}
//
// androidmk Android.mk to Blueprints translator
//

View File

@ -53,7 +53,7 @@ rule g.bootstrap.link
# Variant:
# Type: bootstrap_go_binary
# Factory: blueprint/bootstrap.newGoBinaryModule
# Defined: build/soong/Blueprints:107:1
# Defined: build/soong/Blueprints:122:1
build .bootstrap/androidmk/obj/androidmk.a: g.bootstrap.gc $
${g.bootstrap.srcDir}/build/soong/androidmk/cmd/androidmk/android.go $
@ -79,7 +79,7 @@ default .bootstrap/bin/androidmk
# Variant:
# Type: bootstrap_go_package
# Factory: blueprint/bootstrap.newGoPackageModule
# Defined: build/soong/Blueprints:120:1
# Defined: build/soong/Blueprints:135:1
build .bootstrap/androidmk-parser/pkg/android/soong/androidmk/parser.a: $
g.bootstrap.gc $
@ -274,7 +274,7 @@ default .bootstrap/bin/minibp
# Variant:
# Type: bootstrap_go_package
# Factory: blueprint/bootstrap.newGoPackageModule
# Defined: build/soong/Blueprints:80:1
# Defined: build/soong/Blueprints:81:1
build .bootstrap/soong-cc/pkg/android/soong/cc.a: g.bootstrap.gc $
${g.bootstrap.srcDir}/build/soong/cc/builder.go $
@ -294,8 +294,9 @@ build .bootstrap/soong-cc/pkg/android/soong/cc.a: g.bootstrap.gc $
.bootstrap/blueprint-bootstrap/pkg/blueprint/bootstrap.a $
.bootstrap/soong-glob/pkg/android/soong/glob.a $
.bootstrap/soong-common/pkg/android/soong/common.a $
.bootstrap/soong-config/pkg/android/soong/config.a
incFlags = -I .bootstrap/blueprint-parser/pkg -I .bootstrap/blueprint-proptools/pkg -I .bootstrap/blueprint/pkg -I .bootstrap/blueprint-pathtools/pkg -I .bootstrap/blueprint-deptools/pkg -I .bootstrap/blueprint-bootstrap/pkg -I .bootstrap/soong-glob/pkg -I .bootstrap/soong-common/pkg -I .bootstrap/soong-config/pkg
.bootstrap/soong-config/pkg/android/soong/config.a $
.bootstrap/soong-genrule/pkg/android/soong/genrule.a
incFlags = -I .bootstrap/blueprint-parser/pkg -I .bootstrap/blueprint-proptools/pkg -I .bootstrap/blueprint/pkg -I .bootstrap/blueprint-pathtools/pkg -I .bootstrap/blueprint-deptools/pkg -I .bootstrap/blueprint-bootstrap/pkg -I .bootstrap/soong-glob/pkg -I .bootstrap/soong-common/pkg -I .bootstrap/soong-config/pkg -I .bootstrap/soong-genrule/pkg
pkgPath = android/soong/cc
default .bootstrap/soong-cc/pkg/android/soong/cc.a
@ -304,7 +305,7 @@ default .bootstrap/soong-cc/pkg/android/soong/cc.a
# Variant:
# Type: bootstrap_go_package
# Factory: blueprint/bootstrap.newGoPackageModule
# Defined: build/soong/Blueprints:49:1
# Defined: build/soong/Blueprints:50:1
build .bootstrap/soong-common/pkg/android/soong/common.a: g.bootstrap.gc $
${g.bootstrap.srcDir}/build/soong/common/arch.go $
@ -330,7 +331,7 @@ default .bootstrap/soong-common/pkg/android/soong/common.a
# Variant:
# Type: bootstrap_go_package
# Factory: blueprint/bootstrap.newGoPackageModule
# Defined: build/soong/Blueprints:67:1
# Defined: build/soong/Blueprints:68:1
build .bootstrap/soong-config/pkg/android/soong/config.a: g.bootstrap.gc $
${g.bootstrap.srcDir}/build/soong/config/config.go | $
@ -347,12 +348,35 @@ build .bootstrap/soong-config/pkg/android/soong/config.a: g.bootstrap.gc $
pkgPath = android/soong/config
default .bootstrap/soong-config/pkg/android/soong/config.a
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Module: soong-genrule
# Variant:
# Type: bootstrap_go_package
# Factory: blueprint/bootstrap.newGoPackageModule
# Defined: build/soong/Blueprints:105:1
build .bootstrap/soong-genrule/pkg/android/soong/genrule.a: g.bootstrap.gc $
${g.bootstrap.srcDir}/build/soong/genrule/genrule.go | $
${g.bootstrap.gcCmd} $
.bootstrap/blueprint-parser/pkg/blueprint/parser.a $
.bootstrap/blueprint-proptools/pkg/blueprint/proptools.a $
.bootstrap/blueprint/pkg/blueprint.a $
.bootstrap/blueprint-pathtools/pkg/blueprint/pathtools.a $
.bootstrap/blueprint-deptools/pkg/blueprint/deptools.a $
.bootstrap/blueprint-bootstrap/pkg/blueprint/bootstrap.a $
.bootstrap/soong-glob/pkg/android/soong/glob.a $
.bootstrap/soong-common/pkg/android/soong/common.a $
.bootstrap/soong-config/pkg/android/soong/config.a
incFlags = -I .bootstrap/blueprint-parser/pkg -I .bootstrap/blueprint-proptools/pkg -I .bootstrap/blueprint/pkg -I .bootstrap/blueprint-pathtools/pkg -I .bootstrap/blueprint-deptools/pkg -I .bootstrap/blueprint-bootstrap/pkg -I .bootstrap/soong-glob/pkg -I .bootstrap/soong-common/pkg -I .bootstrap/soong-config/pkg
pkgPath = android/soong/genrule
default .bootstrap/soong-genrule/pkg/android/soong/genrule.a
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# Module: soong-glob
# Variant:
# Type: bootstrap_go_package
# Factory: blueprint/bootstrap.newGoPackageModule
# Defined: build/soong/Blueprints:38:1
# Defined: build/soong/Blueprints:39:1
build .bootstrap/soong-glob/pkg/android/soong/glob.a: g.bootstrap.gc $
${g.bootstrap.srcDir}/build/soong/glob/glob.go | ${g.bootstrap.gcCmd} $
@ -380,14 +404,15 @@ build .bootstrap/soong_build/obj/soong_build.a: g.bootstrap.gc $
.bootstrap/soong-glob/pkg/android/soong/glob.a $
.bootstrap/soong-common/pkg/android/soong/common.a $
.bootstrap/soong-config/pkg/android/soong/config.a $
.bootstrap/soong-genrule/pkg/android/soong/genrule.a $
.bootstrap/soong-cc/pkg/android/soong/cc.a
incFlags = -I .bootstrap/blueprint-parser/pkg -I .bootstrap/blueprint-proptools/pkg -I .bootstrap/blueprint/pkg -I .bootstrap/blueprint-deptools/pkg -I .bootstrap/blueprint-pathtools/pkg -I .bootstrap/blueprint-bootstrap/pkg -I .bootstrap/soong-glob/pkg -I .bootstrap/soong-common/pkg -I .bootstrap/soong-config/pkg -I .bootstrap/soong-cc/pkg
incFlags = -I .bootstrap/blueprint-parser/pkg -I .bootstrap/blueprint-proptools/pkg -I .bootstrap/blueprint/pkg -I .bootstrap/blueprint-deptools/pkg -I .bootstrap/blueprint-pathtools/pkg -I .bootstrap/blueprint-bootstrap/pkg -I .bootstrap/soong-glob/pkg -I .bootstrap/soong-common/pkg -I .bootstrap/soong-config/pkg -I .bootstrap/soong-genrule/pkg -I .bootstrap/soong-cc/pkg
pkgPath = soong_build
default .bootstrap/soong_build/obj/soong_build.a
build .bootstrap/soong_build/obj/a.out: g.bootstrap.link $
.bootstrap/soong_build/obj/soong_build.a | ${g.bootstrap.linkCmd}
libDirFlags = -L .bootstrap/blueprint-parser/pkg -L .bootstrap/blueprint-proptools/pkg -L .bootstrap/blueprint/pkg -L .bootstrap/blueprint-deptools/pkg -L .bootstrap/blueprint-pathtools/pkg -L .bootstrap/blueprint-bootstrap/pkg -L .bootstrap/soong-glob/pkg -L .bootstrap/soong-common/pkg -L .bootstrap/soong-config/pkg -L .bootstrap/soong-cc/pkg
libDirFlags = -L .bootstrap/blueprint-parser/pkg -L .bootstrap/blueprint-proptools/pkg -L .bootstrap/blueprint/pkg -L .bootstrap/blueprint-deptools/pkg -L .bootstrap/blueprint-pathtools/pkg -L .bootstrap/blueprint-bootstrap/pkg -L .bootstrap/soong-glob/pkg -L .bootstrap/soong-common/pkg -L .bootstrap/soong-config/pkg -L .bootstrap/soong-genrule/pkg -L .bootstrap/soong-cc/pkg
default .bootstrap/soong_build/obj/a.out
build .bootstrap/bin/soong_build: g.bootstrap.cp $
@ -399,7 +424,7 @@ default .bootstrap/bin/soong_build
# Variant:
# Type: bootstrap_go_binary
# Factory: blueprint/bootstrap.newGoBinaryModule
# Defined: build/soong/Blueprints:28:1
# Defined: build/soong/Blueprints:29:1
build .bootstrap/soong_glob/obj/soong_glob.a: g.bootstrap.gc $
${g.bootstrap.srcDir}/build/soong/cmd/soong_glob/soong_glob.go | $

View File

@ -1,3 +1,4 @@
// Copyright 2015 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.
@ -25,6 +26,7 @@ import (
"strings"
"android/soong/common"
"android/soong/genrule"
)
type Config interface {
@ -284,7 +286,7 @@ func newCCBase(base *ccBase, module ccModuleType, hod common.HostOrDeviceSupport
props = append(props, &base.properties, &base.unused)
return common.InitAndroidModule(module, hod, multilib, props...)
return common.InitAndroidArchModule(module, hod, multilib, props...)
}
func (c *ccBase) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
@ -313,6 +315,13 @@ func (c *ccBase) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
return
}
generatedObjFiles := c.compileGeneratedObjs(ctx, flags, deps)
if ctx.Failed() {
return
}
objFiles = append(objFiles, generatedObjFiles...)
c.ccModuleType().compileModule(ctx, flags, deps, objFiles)
if ctx.Failed() {
return
@ -578,6 +587,28 @@ func (c *ccBase) compileObjs(ctx common.AndroidModuleContext, flags ccFlags,
return c.customCompileObjs(ctx, flags, deps, "", c.properties.Srcs)
}
// Compile generated source files from dependencies
func (c *ccBase) compileGeneratedObjs(ctx common.AndroidModuleContext, flags ccFlags,
deps ccDeps) []string {
var srcs []string
if c.properties.SkipCompileObjs {
return nil
}
ctx.VisitDirectDeps(func(module blueprint.Module) {
if gen, ok := module.(genrule.SourceFileGenerator); ok {
srcs = append(srcs, gen.GeneratedSourceFiles()...)
}
})
if len(srcs) == 0 {
return nil
}
return TransformSourceToObj(ctx, "", srcs, ccFlagsToBuilderFlags(flags))
}
func (c *ccBase) outputFile() string {
return ""
}

View File

@ -26,6 +26,7 @@ import (
"android/soong/cc"
"android/soong/common"
"android/soong/config"
"android/soong/genrule"
)
func main() {
@ -50,6 +51,8 @@ func main() {
ctx.RegisterModuleType("cc_library_host_shared", cc.NewCCLibraryHostShared)
ctx.RegisterModuleType("cc_binary_host", cc.NewCCBinaryHost)
ctx.RegisterModuleType("gensrcs", genrule.NewGenSrcs)
// Mutators
ctx.RegisterEarlyMutator("arch", common.ArchMutator)
ctx.RegisterEarlyMutator("link", cc.LinkageMutator)

View File

@ -280,6 +280,10 @@ func ArchMutator(mctx blueprint.EarlyMutatorContext) {
}
}
if len(arches) == 0 {
return
}
archNames := []string{}
for _, arch := range arches {
archNames = append(archNames, arch.String())
@ -300,8 +304,6 @@ func InitArchModule(m AndroidModule, defaultMultilib Multilib,
base.commonProperties.Compile_multilib = string(defaultMultilib)
base.generalProperties = append(base.generalProperties,
&base.commonProperties)
base.generalProperties = append(base.generalProperties,
propertyStructs...)

View File

@ -87,11 +87,23 @@ const (
MultilibFirst Multilib = "first"
)
func InitAndroidModule(m AndroidModule, hod HostOrDeviceSupported, defaultMultilib Multilib,
func InitAndroidModule(m AndroidModule,
propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
base := m.base()
base.module = m
propertyStructs = append(propertyStructs, &base.commonProperties)
return m, propertyStructs
}
func InitAndroidArchModule(m AndroidModule, hod HostOrDeviceSupported, defaultMultilib Multilib,
propertyStructs ...interface{}) (blueprint.Module, []interface{}) {
_, propertyStructs = InitAndroidModule(m, propertyStructs...)
base := m.base()
base.commonProperties.HostOrDeviceSupported = hod
if hod == HostAndDeviceSupported {

97
genrule/genrule.go Normal file
View File

@ -0,0 +1,97 @@
// Copyright 2015 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 (
"path/filepath"
"blueprint"
"blueprint/pathtools"
"android/soong/common"
)
type Config interface {
SrcDir() string
}
var (
pctx = blueprint.NewPackageContext("android/soong/genrule")
)
func init() {
pctx.VariableConfigMethod("srcDir", Config.SrcDir)
}
type SourceFileGenerator interface {
GeneratedSourceFiles() []string
}
type genSrcsProperties struct {
// cmd: command to run on each input file. Available variables for substitution:
// $in: an input file
// $out: the corresponding output file
// $srcDir: the root directory of the source tree
Cmd string
// srcs: list of input files
Srcs []string
// output_extension: extension that will be substituted for each output file
Output_extension string
}
func NewGenSrcs() (blueprint.Module, []interface{}) {
module := &genSrcs{}
return common.InitAndroidModule(module, &module.properties)
}
type genSrcs struct {
common.AndroidModuleBase
properties genSrcsProperties
outputFiles []string
}
func (g *genSrcs) GenerateAndroidBuildActions(ctx common.AndroidModuleContext) {
rule := ctx.Rule(pctx, "genSrcs", blueprint.RuleParams{
Command: g.properties.Cmd,
})
srcFiles := g.properties.Srcs
srcFiles = pathtools.PrefixPaths(srcFiles, common.ModuleSrcDir(ctx))
srcFiles = common.ExpandGlobs(ctx, srcFiles)
g.outputFiles = make([]string, 0, len(srcFiles))
for _, in := range srcFiles {
out := pathtools.ReplaceExtension(in, g.properties.Output_extension)
out = filepath.Join(common.ModuleGenDir(ctx), out)
g.outputFiles = append(g.outputFiles, out)
ctx.Build(pctx, blueprint.BuildParams{
Rule: rule,
Inputs: []string{in},
Outputs: []string{out},
// TODO: visit dependencies to add implicit dependencies on required tools
})
}
}
var _ SourceFileGenerator = (*genSrcs)(nil)
func (g *genSrcs) GeneratedSourceFiles() []string {
return g.outputFiles
}