Wrap PackageContext and SingletonContext

am: 0875c52de7

Change-Id: Ibffbf49a34a1ca042cc21f79f8aacfe62695e87e
This commit is contained in:
Colin Cross 2017-11-29 05:18:07 +00:00 committed by android-build-merger
commit a0a0b7fd90
21 changed files with 479 additions and 243 deletions

View File

@ -56,6 +56,7 @@ bootstrap_go_package {
"android/prebuilt.go", "android/prebuilt.go",
"android/proto.go", "android/proto.go",
"android/register.go", "android/register.go",
"android/singleton.go",
"android/testing.go", "android/testing.go",
"android/util.go", "android/util.go",
"android/variable.go", "android/variable.go",

View File

@ -53,13 +53,13 @@ type AndroidMkData struct {
type AndroidMkExtraFunc func(w io.Writer, outputFile Path) type AndroidMkExtraFunc func(w io.Writer, outputFile Path)
func AndroidMkSingleton() blueprint.Singleton { func AndroidMkSingleton() Singleton {
return &androidMkSingleton{} return &androidMkSingleton{}
} }
type androidMkSingleton struct{} type androidMkSingleton struct{}
func (c *androidMkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) { func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) {
config := ctx.Config().(Config) config := ctx.Config().(Config)
if !config.EmbeddedInMake() { if !config.EmbeddedInMake() {
@ -68,10 +68,8 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext
var androidMkModulesList []Module var androidMkModulesList []Module
ctx.VisitAllModules(func(module blueprint.Module) { ctx.VisitAllModules(func(module Module) {
if amod, ok := module.(Module); ok { androidMkModulesList = append(androidMkModulesList, module)
androidMkModulesList = append(androidMkModulesList, amod)
}
}) })
sort.Sort(AndroidModulesByName{androidMkModulesList, ctx}) sort.Sort(AndroidModulesByName{androidMkModulesList, ctx})
@ -86,14 +84,13 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext
ctx.Errorf(err.Error()) ctx.Errorf(err.Error())
} }
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, BuildParams{
Rule: blueprint.Phony, Rule: blueprint.Phony,
Outputs: []string{transMk.String()}, Output: transMk,
Optional: true,
}) })
} }
func translateAndroidMk(ctx blueprint.SingletonContext, mkFile string, mods []Module) error { func translateAndroidMk(ctx SingletonContext, mkFile string, mods []Module) error {
buf := &bytes.Buffer{} buf := &bytes.Buffer{}
fmt.Fprintln(buf, "LOCAL_MODULE_MAKEFILE := $(lastword $(MAKEFILE_LIST))") fmt.Fprintln(buf, "LOCAL_MODULE_MAKEFILE := $(lastword $(MAKEFILE_LIST))")
@ -145,7 +142,7 @@ func translateAndroidMk(ctx blueprint.SingletonContext, mkFile string, mods []Mo
return ioutil.WriteFile(mkFile, buf.Bytes(), 0666) return ioutil.WriteFile(mkFile, buf.Bytes(), 0666)
} }
func translateAndroidMkModule(ctx blueprint.SingletonContext, w io.Writer, mod blueprint.Module) error { func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.Module) error {
provider, ok := mod.(AndroidMkDataProvider) provider, ok := mod.(AndroidMkDataProvider)
if !ok { if !ok {
return nil return nil

View File

@ -16,22 +16,19 @@ package android
import ( import (
"encoding/json" "encoding/json"
"path/filepath"
"github.com/google/blueprint"
) )
func init() { func init() {
RegisterSingletonType("api_levels", ApiLevelsSingleton) RegisterSingletonType("api_levels", ApiLevelsSingleton)
} }
func ApiLevelsSingleton() blueprint.Singleton { func ApiLevelsSingleton() Singleton {
return &apiLevelsSingleton{} return &apiLevelsSingleton{}
} }
type apiLevelsSingleton struct{} type apiLevelsSingleton struct{}
func createApiLevelsJson(ctx blueprint.SingletonContext, file string, func createApiLevelsJson(ctx SingletonContext, file WritablePath,
apiLevelsMap map[string]int) { apiLevelsMap map[string]int) {
jsonStr, err := json.Marshal(apiLevelsMap) jsonStr, err := json.Marshal(apiLevelsMap)
@ -39,21 +36,21 @@ func createApiLevelsJson(ctx blueprint.SingletonContext, file string,
ctx.Errorf(err.Error()) ctx.Errorf(err.Error())
} }
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, BuildParams{
Rule: WriteFile, Rule: WriteFile,
Description: "generate " + filepath.Base(file), Description: "generate " + file.Base(),
Outputs: []string{file}, Output: file,
Args: map[string]string{ Args: map[string]string{
"content": string(jsonStr[:]), "content": string(jsonStr[:]),
}, },
}) })
} }
func GetApiLevelsJson(ctx PathContext) Path { func GetApiLevelsJson(ctx PathContext) WritablePath {
return PathForOutput(ctx, "api_levels.json") return PathForOutput(ctx, "api_levels.json")
} }
func (a *apiLevelsSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) { func (a *apiLevelsSingleton) GenerateBuildActions(ctx SingletonContext) {
baseApiLevel := 9000 baseApiLevel := 9000
apiLevelsMap := map[string]int{ apiLevelsMap := map[string]int{
"G": 9, "G": 9,
@ -74,5 +71,5 @@ func (a *apiLevelsSingleton) GenerateBuildActions(ctx blueprint.SingletonContext
} }
apiLevelsJson := GetApiLevelsJson(ctx) apiLevelsJson := GetApiLevelsJson(ctx)
createApiLevelsJson(ctx, apiLevelsJson.String(), apiLevelsMap) createApiLevelsJson(ctx, apiLevelsJson, apiLevelsMap)
} }

View File

@ -21,7 +21,6 @@ import (
"os" "os"
"strconv" "strconv"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools" "github.com/google/blueprint/proptools"
) )
@ -66,7 +65,7 @@ type MakeVarsContext interface {
type MakeVarsProvider func(ctx MakeVarsContext) type MakeVarsProvider func(ctx MakeVarsContext)
func RegisterMakeVarsProvider(pctx blueprint.PackageContext, provider MakeVarsProvider) { func RegisterMakeVarsProvider(pctx PackageContext, provider MakeVarsProvider) {
makeVarsProviders = append(makeVarsProviders, makeVarsProvider{pctx, provider}) makeVarsProviders = append(makeVarsProviders, makeVarsProvider{pctx, provider})
} }
@ -76,14 +75,14 @@ func init() {
RegisterSingletonType("makevars", makeVarsSingletonFunc) RegisterSingletonType("makevars", makeVarsSingletonFunc)
} }
func makeVarsSingletonFunc() blueprint.Singleton { func makeVarsSingletonFunc() Singleton {
return &makeVarsSingleton{} return &makeVarsSingleton{}
} }
type makeVarsSingleton struct{} type makeVarsSingleton struct{}
type makeVarsProvider struct { type makeVarsProvider struct {
pctx blueprint.PackageContext pctx PackageContext
call MakeVarsProvider call MakeVarsProvider
} }
@ -91,8 +90,8 @@ var makeVarsProviders []makeVarsProvider
type makeVarsContext struct { type makeVarsContext struct {
config Config config Config
ctx blueprint.SingletonContext ctx SingletonContext
pctx blueprint.PackageContext pctx PackageContext
vars []makeVarsVariable vars []makeVarsVariable
} }
@ -105,7 +104,7 @@ type makeVarsVariable struct {
strict bool strict bool
} }
func (s *makeVarsSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) { func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) {
config := ctx.Config().(Config) config := ctx.Config().(Config)
if !config.EmbeddedInMake() { if !config.EmbeddedInMake() {

View File

@ -17,6 +17,7 @@ package android
import ( import (
"fmt" "fmt"
"path/filepath" "path/filepath"
"sort"
"strings" "strings"
"github.com/google/blueprint" "github.com/google/blueprint"
@ -78,7 +79,7 @@ type ModuleContext interface {
blueprint.BaseModuleContext blueprint.BaseModuleContext
// Deprecated: use ModuleContext.Build instead. // Deprecated: use ModuleContext.Build instead.
ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) ModuleBuild(pctx PackageContext, params ModuleBuildParams)
ExpandSources(srcFiles, excludes []string) Paths ExpandSources(srcFiles, excludes []string) Paths
ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths ExpandSourcesSubDir(srcFiles, excludes []string, subDir string) Paths
@ -115,15 +116,15 @@ type ModuleContext interface {
VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
WalkDeps(visit func(Module, Module) bool) WalkDeps(visit func(Module, Module) bool)
Variable(pctx blueprint.PackageContext, name, value string) Variable(pctx PackageContext, name, value string)
Rule(pctx blueprint.PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule Rule(pctx PackageContext, name string, params blueprint.RuleParams, argNames ...string) blueprint.Rule
// Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string, // Similar to blueprint.ModuleContext.Build, but takes Paths instead of []string,
// and performs more verification. // and performs more verification.
Build(pctx blueprint.PackageContext, params BuildParams) Build(pctx PackageContext, params BuildParams)
PrimaryModule() blueprint.Module PrimaryModule() Module
FinalModule() blueprint.Module FinalModule() Module
VisitAllModuleVariants(visit func(blueprint.Module)) VisitAllModuleVariants(visit func(Module))
GetMissingDependencies() []string GetMissingDependencies() []string
} }
@ -325,8 +326,8 @@ type ModuleBase struct {
// Used by buildTargetSingleton to create checkbuild and per-directory build targets // Used by buildTargetSingleton to create checkbuild and per-directory build targets
// Only set on the final variant of each module // Only set on the final variant of each module
installTarget string installTarget WritablePath
checkbuildTarget string checkbuildTarget WritablePath
blueprintDir string blueprintDir string
hooks hooks hooks hooks
@ -464,36 +465,35 @@ func (p *ModuleBase) InstallInSanitizerDir() bool {
return false return false
} }
func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) { func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) {
allInstalledFiles := Paths{} allInstalledFiles := Paths{}
allCheckbuildFiles := Paths{} allCheckbuildFiles := Paths{}
ctx.VisitAllModuleVariants(func(module blueprint.Module) { ctx.VisitAllModuleVariants(func(module Module) {
a := module.(Module).base() a := module.base()
allInstalledFiles = append(allInstalledFiles, a.installFiles...) allInstalledFiles = append(allInstalledFiles, a.installFiles...)
allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...) allCheckbuildFiles = append(allCheckbuildFiles, a.checkbuildFiles...)
}) })
deps := []string{} var deps Paths
if len(allInstalledFiles) > 0 { if len(allInstalledFiles) > 0 {
name := ctx.ModuleName() + "-install" name := PathForPhony(ctx, ctx.ModuleName()+"-install")
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, BuildParams{
Rule: blueprint.Phony, Rule: blueprint.Phony,
Outputs: []string{name}, Output: name,
Implicits: allInstalledFiles.Strings(), Implicits: allInstalledFiles,
Optional: ctx.Config().(Config).EmbeddedInMake(), Default: !ctx.Config().(Config).EmbeddedInMake(),
}) })
deps = append(deps, name) deps = append(deps, name)
a.installTarget = name a.installTarget = name
} }
if len(allCheckbuildFiles) > 0 { if len(allCheckbuildFiles) > 0 {
name := ctx.ModuleName() + "-checkbuild" name := PathForPhony(ctx, ctx.ModuleName()+"-checkbuild")
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, BuildParams{
Rule: blueprint.Phony, Rule: blueprint.Phony,
Outputs: []string{name}, Output: name,
Implicits: allCheckbuildFiles.Strings(), Implicits: allCheckbuildFiles,
Optional: true,
}) })
deps = append(deps, name) deps = append(deps, name)
a.checkbuildTarget = name a.checkbuildTarget = name
@ -505,11 +505,10 @@ func (a *ModuleBase) generateModuleTarget(ctx blueprint.ModuleContext) {
suffix = "-soong" suffix = "-soong"
} }
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, BuildParams{
Rule: blueprint.Phony, Rule: blueprint.Phony,
Outputs: []string{ctx.ModuleName() + suffix}, Output: PathForPhony(ctx, ctx.ModuleName()+suffix),
Implicits: deps, Implicits: deps,
Optional: true,
}) })
a.blueprintDir = ctx.ModuleDir() a.blueprintDir = ctx.ModuleDir()
@ -525,23 +524,23 @@ func (a *ModuleBase) androidBaseContextFactory(ctx blueprint.BaseModuleContext)
} }
} }
func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) { func (a *ModuleBase) GenerateBuildActions(blueprintCtx blueprint.ModuleContext) {
androidCtx := &androidModuleContext{ ctx := &androidModuleContext{
module: a.module, module: a.module,
ModuleContext: ctx, ModuleContext: blueprintCtx,
androidBaseContextImpl: a.androidBaseContextFactory(ctx), androidBaseContextImpl: a.androidBaseContextFactory(blueprintCtx),
installDeps: a.computeInstallDeps(ctx), installDeps: a.computeInstallDeps(blueprintCtx),
installFiles: a.installFiles, installFiles: a.installFiles,
missingDeps: ctx.GetMissingDependencies(), missingDeps: blueprintCtx.GetMissingDependencies(),
} }
desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " " desc := "//" + ctx.ModuleDir() + ":" + ctx.ModuleName() + " "
var suffix []string var suffix []string
if androidCtx.Os().Class != Device && androidCtx.Os().Class != Generic { if ctx.Os().Class != Device && ctx.Os().Class != Generic {
suffix = append(suffix, androidCtx.Os().String()) suffix = append(suffix, ctx.Os().String())
} }
if !androidCtx.PrimaryArch() { if !ctx.PrimaryArch() {
suffix = append(suffix, androidCtx.Arch().ArchType.String()) suffix = append(suffix, ctx.Arch().ArchType.String())
} }
ctx.Variable(pctx, "moduleDesc", desc) ctx.Variable(pctx, "moduleDesc", desc)
@ -553,13 +552,13 @@ func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
ctx.Variable(pctx, "moduleDescSuffix", s) ctx.Variable(pctx, "moduleDescSuffix", s)
if a.Enabled() { if a.Enabled() {
a.module.GenerateAndroidBuildActions(androidCtx) a.module.GenerateAndroidBuildActions(ctx)
if ctx.Failed() { if ctx.Failed() {
return return
} }
a.installFiles = append(a.installFiles, androidCtx.installFiles...) a.installFiles = append(a.installFiles, ctx.installFiles...)
a.checkbuildFiles = append(a.checkbuildFiles, androidCtx.checkbuildFiles...) a.checkbuildFiles = append(a.checkbuildFiles, ctx.checkbuildFiles...)
} }
if a == ctx.FinalModule().(Module).base() { if a == ctx.FinalModule().(Module).base() {
@ -569,7 +568,7 @@ func (a *ModuleBase) GenerateBuildActions(ctx blueprint.ModuleContext) {
} }
} }
a.buildParams = androidCtx.buildParams a.buildParams = ctx.buildParams
} }
type androidBaseContextImpl struct { type androidBaseContextImpl struct {
@ -594,7 +593,7 @@ type androidModuleContext struct {
} }
func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) { func (a *androidModuleContext) ninjaError(desc string, outputs []string, err error) {
a.ModuleContext.Build(pctx, blueprint.BuildParams{ a.ModuleContext.Build(pctx.PackageContext, blueprint.BuildParams{
Rule: ErrorRule, Rule: ErrorRule,
Description: desc, Description: desc,
Outputs: outputs, Outputs: outputs,
@ -606,17 +605,14 @@ func (a *androidModuleContext) ninjaError(desc string, outputs []string, err err
return return
} }
func (a *androidModuleContext) ModuleBuild(pctx blueprint.PackageContext, params ModuleBuildParams) { func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) {
a.Build(pctx, BuildParams(params)) a.Build(pctx, BuildParams(params))
} }
func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params BuildParams) { func convertBuildParams(params BuildParams) blueprint.BuildParams {
if a.config.captureBuild {
a.buildParams = append(a.buildParams, params)
}
bparams := blueprint.BuildParams{ bparams := blueprint.BuildParams{
Rule: params.Rule, Rule: params.Rule,
Description: params.Description,
Deps: params.Deps, Deps: params.Deps,
Outputs: params.Outputs.Strings(), Outputs: params.Outputs.Strings(),
ImplicitOutputs: params.ImplicitOutputs.Strings(), ImplicitOutputs: params.ImplicitOutputs.Strings(),
@ -627,10 +623,6 @@ func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params Build
Optional: !params.Default, Optional: !params.Default,
} }
if params.Description != "" {
bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
}
if params.Depfile != nil { if params.Depfile != nil {
bparams.Depfile = params.Depfile.String() bparams.Depfile = params.Depfile.String()
} }
@ -647,6 +639,30 @@ func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params Build
bparams.Implicits = append(bparams.Implicits, params.Implicit.String()) bparams.Implicits = append(bparams.Implicits, params.Implicit.String())
} }
return bparams
}
func (a *androidModuleContext) Variable(pctx PackageContext, name, value string) {
a.ModuleContext.Variable(pctx.PackageContext, name, value)
}
func (a *androidModuleContext) Rule(pctx PackageContext, name string, params blueprint.RuleParams,
argNames ...string) blueprint.Rule {
return a.ModuleContext.Rule(pctx.PackageContext, name, params, argNames...)
}
func (a *androidModuleContext) Build(pctx PackageContext, params BuildParams) {
if a.config.captureBuild {
a.buildParams = append(a.buildParams, params)
}
bparams := convertBuildParams(params)
if bparams.Description != "" {
bparams.Description = "${moduleDesc}" + params.Description + "${moduleDescSuffix}"
}
if a.missingDeps != nil { if a.missingDeps != nil {
a.ninjaError(bparams.Description, bparams.Outputs, a.ninjaError(bparams.Description, bparams.Outputs,
fmt.Errorf("module %s missing dependencies: %s\n", fmt.Errorf("module %s missing dependencies: %s\n",
@ -654,7 +670,7 @@ func (a *androidModuleContext) Build(pctx blueprint.PackageContext, params Build
return return
} }
a.ModuleContext.Build(pctx, bparams) a.ModuleContext.Build(pctx.PackageContext, bparams)
} }
func (a *androidModuleContext) GetMissingDependencies() []string { func (a *androidModuleContext) GetMissingDependencies() []string {
@ -751,6 +767,20 @@ func (a *androidModuleContext) WalkDeps(visit func(Module, Module) bool) {
}) })
} }
func (a *androidModuleContext) VisitAllModuleVariants(visit func(Module)) {
a.ModuleContext.VisitAllModuleVariants(func(module blueprint.Module) {
visit(module.(Module))
})
}
func (a *androidModuleContext) PrimaryModule() Module {
return a.ModuleContext.PrimaryModule().(Module)
}
func (a *androidModuleContext) FinalModule() Module {
return a.ModuleContext.FinalModule().(Module)
}
func (a *androidBaseContextImpl) Target() Target { func (a *androidBaseContextImpl) Target() Target {
return a.target return a.target
} }
@ -1027,7 +1057,7 @@ func init() {
RegisterSingletonType("buildtarget", BuildTargetSingleton) RegisterSingletonType("buildtarget", BuildTargetSingleton)
} }
func BuildTargetSingleton() blueprint.Singleton { func BuildTargetSingleton() Singleton {
return &buildTargetSingleton{} return &buildTargetSingleton{}
} }
@ -1038,29 +1068,28 @@ func parentDir(dir string) string {
type buildTargetSingleton struct{} type buildTargetSingleton struct{}
func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) { func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) {
checkbuildDeps := []string{} var checkbuildDeps Paths
mmTarget := func(dir string) string { mmTarget := func(dir string) WritablePath {
return "MODULES-IN-" + strings.Replace(filepath.Clean(dir), "/", "-", -1) return PathForPhony(ctx,
"MODULES-IN-"+strings.Replace(filepath.Clean(dir), "/", "-", -1))
} }
modulesInDir := make(map[string][]string) modulesInDir := make(map[string]Paths)
ctx.VisitAllModules(func(module blueprint.Module) { ctx.VisitAllModules(func(module Module) {
if a, ok := module.(Module); ok { blueprintDir := module.base().blueprintDir
blueprintDir := a.base().blueprintDir installTarget := module.base().installTarget
installTarget := a.base().installTarget checkbuildTarget := module.base().checkbuildTarget
checkbuildTarget := a.base().checkbuildTarget
if checkbuildTarget != "" { if checkbuildTarget != nil {
checkbuildDeps = append(checkbuildDeps, checkbuildTarget) checkbuildDeps = append(checkbuildDeps, checkbuildTarget)
modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget) modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], checkbuildTarget)
} }
if installTarget != "" { if installTarget != nil {
modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget) modulesInDir[blueprintDir] = append(modulesInDir[blueprintDir], installTarget)
}
} }
}) })
@ -1070,11 +1099,10 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonConte
} }
// Create a top-level checkbuild target that depends on all modules // Create a top-level checkbuild target that depends on all modules
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, BuildParams{
Rule: blueprint.Phony, Rule: blueprint.Phony,
Outputs: []string{"checkbuild" + suffix}, Output: PathForPhony(ctx, "checkbuild"+suffix),
Implicits: checkbuildDeps, Implicits: checkbuildDeps,
Optional: true,
}) })
// Make will generate the MODULES-IN-* targets // Make will generate the MODULES-IN-* targets
@ -1082,6 +1110,15 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonConte
return return
} }
sortedKeys := func(m map[string]Paths) []string {
s := make([]string, 0, len(m))
for k := range m {
s = append(s, k)
}
sort.Strings(s)
return s
}
// Ensure ancestor directories are in modulesInDir // Ensure ancestor directories are in modulesInDir
dirs := sortedKeys(modulesInDir) dirs := sortedKeys(modulesInDir)
for _, dir := range dirs { for _, dir := range dirs {
@ -1108,28 +1145,26 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonConte
// depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp // depends on the MODULES-IN-* targets of all of its subdirectories that contain Android.bp
// files. // files.
for _, dir := range dirs { for _, dir := range dirs {
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, BuildParams{
Rule: blueprint.Phony, Rule: blueprint.Phony,
Outputs: []string{mmTarget(dir)}, Output: mmTarget(dir),
Implicits: modulesInDir[dir], Implicits: modulesInDir[dir],
// HACK: checkbuild should be an optional build, but force it // HACK: checkbuild should be an optional build, but force it
// enabled for now in standalone builds // enabled for now in standalone builds
Optional: ctx.Config().(Config).EmbeddedInMake(), Default: !ctx.Config().(Config).EmbeddedInMake(),
}) })
} }
// Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild. // Create (host|host-cross|target)-<OS> phony rules to build a reduced checkbuild.
osDeps := map[OsType]Paths{} osDeps := map[OsType]Paths{}
ctx.VisitAllModules(func(module blueprint.Module) { ctx.VisitAllModules(func(module Module) {
if a, ok := module.(Module); ok { if module.Enabled() {
if a.Enabled() { os := module.Target().Os
os := a.Target().Os osDeps[os] = append(osDeps[os], module.base().checkbuildFiles...)
osDeps[os] = append(osDeps[os], a.base().checkbuildFiles...)
}
} }
}) })
osClass := make(map[string][]string) osClass := make(map[string]Paths)
for os, deps := range osDeps { for os, deps := range osDeps {
var className string var className string
@ -1144,25 +1179,23 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx blueprint.SingletonConte
continue continue
} }
name := className + "-" + os.Name name := PathForPhony(ctx, className+"-"+os.Name)
osClass[className] = append(osClass[className], name) osClass[className] = append(osClass[className], name)
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, BuildParams{
Rule: blueprint.Phony, Rule: blueprint.Phony,
Outputs: []string{name}, Output: name,
Implicits: deps.Strings(), Implicits: deps,
Optional: true,
}) })
} }
// Wrap those into host|host-cross|target phony rules // Wrap those into host|host-cross|target phony rules
osClasses := sortedKeys(osClass) osClasses := sortedKeys(osClass)
for _, class := range osClasses { for _, class := range osClasses {
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, BuildParams{
Rule: blueprint.Phony, Rule: blueprint.Phony,
Outputs: []string{class}, Output: PathForPhony(ctx, class),
Implicits: osClass[class], Implicits: osClass[class],
Optional: true,
}) })
} }
} }

View File

@ -22,14 +22,14 @@ import (
"github.com/google/blueprint/pathtools" "github.com/google/blueprint/pathtools"
) )
// AndroidPackageContext is a wrapper for blueprint.PackageContext that adds // PackageContext is a wrapper for blueprint.PackageContext that adds
// some android-specific helper functions. // some android-specific helper functions.
type AndroidPackageContext struct { type PackageContext struct {
blueprint.PackageContext blueprint.PackageContext
} }
func NewPackageContext(pkgPath string) AndroidPackageContext { func NewPackageContext(pkgPath string) PackageContext {
return AndroidPackageContext{blueprint.NewPackageContext(pkgPath)} return PackageContext{blueprint.NewPackageContext(pkgPath)}
} }
// configErrorWrapper can be used with Path functions when a Context is not // configErrorWrapper can be used with Path functions when a Context is not
@ -39,7 +39,7 @@ func NewPackageContext(pkgPath string) AndroidPackageContext {
// The most common use here will be with VariableFunc, where only a config is // The most common use here will be with VariableFunc, where only a config is
// provided, and an error should be returned. // provided, and an error should be returned.
type configErrorWrapper struct { type configErrorWrapper struct {
pctx AndroidPackageContext pctx PackageContext
config Config config Config
errors []error errors []error
} }
@ -61,13 +61,43 @@ func (e *configErrorWrapper) Fs() pathtools.FileSystem {
return nil return nil
} }
// VariableFunc wraps blueprint.PackageContext.VariableFunc, converting the interface{} config
// argument to a Config.
func (p PackageContext) VariableFunc(name string,
f func(Config) (string, error)) blueprint.Variable {
return p.PackageContext.VariableFunc(name, func(config interface{}) (string, error) {
return f(config.(Config))
})
}
// PoolFunc wraps blueprint.PackageContext.PoolFunc, converting the interface{} config
// argument to a Config.
func (p PackageContext) PoolFunc(name string,
f func(Config) (blueprint.PoolParams, error)) blueprint.Pool {
return p.PackageContext.PoolFunc(name, func(config interface{}) (blueprint.PoolParams, error) {
return f(config.(Config))
})
}
// RuleFunc wraps blueprint.PackageContext.RuleFunc, converting the interface{} config
// argument to a Config.
func (p PackageContext) RuleFunc(name string,
f func(Config) (blueprint.RuleParams, error), argNames ...string) blueprint.Rule {
return p.PackageContext.RuleFunc(name, func(config interface{}) (blueprint.RuleParams, error) {
return f(config.(Config))
}, argNames...)
}
// SourcePathVariable returns a Variable whose value is the source directory // SourcePathVariable returns a Variable whose value is the source directory
// appended with the supplied path. It may only be called during a Go package's // appended with the supplied path. It may only be called during a Go package's
// initialization - either from the init() function or as part of a // initialization - either from the init() function or as part of a
// package-scoped variable's initialization. // package-scoped variable's initialization.
func (p AndroidPackageContext) SourcePathVariable(name, path string) blueprint.Variable { func (p PackageContext) SourcePathVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) { return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}} ctx := &configErrorWrapper{p, config, []error{}}
p := safePathForSource(ctx, path) p := safePathForSource(ctx, path)
if len(ctx.errors) > 0 { if len(ctx.errors) > 0 {
return "", ctx.errors[0] return "", ctx.errors[0]
@ -80,9 +110,9 @@ func (p AndroidPackageContext) SourcePathVariable(name, path string) blueprint.V
// appended with the supplied paths, joined with separator. It may only be // appended with the supplied paths, joined with separator. It may only be
// called during a Go package's initialization - either from the init() // called during a Go package's initialization - either from the init()
// function or as part of a package-scoped variable's initialization. // function or as part of a package-scoped variable's initialization.
func (p AndroidPackageContext) SourcePathsVariable(name, separator string, paths ...string) blueprint.Variable { func (p PackageContext) SourcePathsVariable(name, separator string, paths ...string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) { return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}} ctx := &configErrorWrapper{p, config, []error{}}
var ret []string var ret []string
for _, path := range paths { for _, path := range paths {
p := safePathForSource(ctx, path) p := safePathForSource(ctx, path)
@ -100,14 +130,14 @@ func (p AndroidPackageContext) SourcePathsVariable(name, separator string, paths
// The environment variable is not required to point to a path inside the source tree. // The environment variable is not required to point to a path inside the source tree.
// It may only be called during a Go package's initialization - either from the init() function or // It may only be called during a Go package's initialization - either from the init() function or
// as part of a package-scoped variable's initialization. // as part of a package-scoped variable's initialization.
func (p AndroidPackageContext) SourcePathVariableWithEnvOverride(name, path, env string) blueprint.Variable { func (p PackageContext) SourcePathVariableWithEnvOverride(name, path, env string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) { return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}} ctx := &configErrorWrapper{p, config, []error{}}
p := safePathForSource(ctx, path) p := safePathForSource(ctx, path)
if len(ctx.errors) > 0 { if len(ctx.errors) > 0 {
return "", ctx.errors[0] return "", ctx.errors[0]
} }
return config.(Config).GetenvWithDefault(env, p.String()), nil return config.GetenvWithDefault(env, p.String()), nil
}) })
} }
@ -115,8 +145,8 @@ func (p AndroidPackageContext) SourcePathVariableWithEnvOverride(name, path, env
// in the bin directory for host targets. It may only be called during a Go // in the bin directory for host targets. It may only be called during a Go
// package's initialization - either from the init() function or as part of a // package's initialization - either from the init() function or as part of a
// package-scoped variable's initialization. // package-scoped variable's initialization.
func (p AndroidPackageContext) HostBinToolVariable(name, path string) blueprint.Variable { func (p PackageContext) HostBinToolVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) { return p.VariableFunc(name, func(config Config) (string, error) {
po, err := p.HostBinToolPath(config, path) po, err := p.HostBinToolPath(config, path)
if err != nil { if err != nil {
return "", err return "", err
@ -125,8 +155,8 @@ func (p AndroidPackageContext) HostBinToolVariable(name, path string) blueprint.
}) })
} }
func (p AndroidPackageContext) HostBinToolPath(config interface{}, path string) (Path, error) { func (p PackageContext) HostBinToolPath(config Config, path string) (Path, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}} ctx := &configErrorWrapper{p, config, []error{}}
pa := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "bin", path) pa := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "bin", path)
if len(ctx.errors) > 0 { if len(ctx.errors) > 0 {
return nil, ctx.errors[0] return nil, ctx.errors[0]
@ -138,9 +168,9 @@ func (p AndroidPackageContext) HostBinToolPath(config interface{}, path string)
// tool in the frameworks directory for host targets. It may only be called // tool in the frameworks directory for host targets. It may only be called
// during a Go package's initialization - either from the init() function or as // during a Go package's initialization - either from the init() function or as
// part of a package-scoped variable's initialization. // part of a package-scoped variable's initialization.
func (p AndroidPackageContext) HostJavaToolVariable(name, path string) blueprint.Variable { func (p PackageContext) HostJavaToolVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) { return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}} ctx := &configErrorWrapper{p, config, []error{}}
p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "framework", path) p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "framework", path)
if len(ctx.errors) > 0 { if len(ctx.errors) > 0 {
return "", ctx.errors[0] return "", ctx.errors[0]
@ -149,8 +179,8 @@ func (p AndroidPackageContext) HostJavaToolVariable(name, path string) blueprint
}) })
} }
func (p AndroidPackageContext) HostJavaToolPath(config interface{}, path string) (Path, error) { func (p PackageContext) HostJavaToolPath(config Config, path string) (Path, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}} ctx := &configErrorWrapper{p, config, []error{}}
pa := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "framework", path) pa := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "framework", path)
if len(ctx.errors) > 0 { if len(ctx.errors) > 0 {
return nil, ctx.errors[0] return nil, ctx.errors[0]
@ -162,9 +192,9 @@ func (p AndroidPackageContext) HostJavaToolPath(config interface{}, path string)
// directory appended with the supplied path. It may only be called during a Go // directory appended with the supplied path. It may only be called during a Go
// package's initialization - either from the init() function or as part of a // package's initialization - either from the init() function or as part of a
// package-scoped variable's initialization. // package-scoped variable's initialization.
func (p AndroidPackageContext) IntermediatesPathVariable(name, path string) blueprint.Variable { func (p PackageContext) IntermediatesPathVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) { return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}} ctx := &configErrorWrapper{p, config, []error{}}
p := PathForIntermediates(ctx, path) p := PathForIntermediates(ctx, path)
if len(ctx.errors) > 0 { if len(ctx.errors) > 0 {
return "", ctx.errors[0] return "", ctx.errors[0]
@ -177,11 +207,11 @@ func (p AndroidPackageContext) IntermediatesPathVariable(name, path string) blue
// list of present source paths prefixed with the supplied prefix. It may only // list of present source paths prefixed with the supplied prefix. It may only
// be called during a Go package's initialization - either from the init() // be called during a Go package's initialization - either from the init()
// function or as part of a package-scoped variable's initialization. // function or as part of a package-scoped variable's initialization.
func (p AndroidPackageContext) PrefixedExistentPathsForSourcesVariable( func (p PackageContext) PrefixedExistentPathsForSourcesVariable(
name, prefix string, paths []string) blueprint.Variable { name, prefix string, paths []string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) { return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}} ctx := &configErrorWrapper{p, config, []error{}}
paths := ExistentPathsForSources(ctx, "", paths) paths := ExistentPathsForSources(ctx, "", paths)
if len(ctx.errors) > 0 { if len(ctx.errors) > 0 {
return "", ctx.errors[0] return "", ctx.errors[0]
@ -196,7 +226,7 @@ type RuleParams struct {
} }
// AndroidStaticRule wraps blueprint.StaticRule and provides a default Pool if none is specified // AndroidStaticRule wraps blueprint.StaticRule and provides a default Pool if none is specified
func (p AndroidPackageContext) AndroidStaticRule(name string, params blueprint.RuleParams, func (p PackageContext) AndroidStaticRule(name string, params blueprint.RuleParams,
argNames ...string) blueprint.Rule { argNames ...string) blueprint.Rule {
return p.AndroidRuleFunc(name, func(Config) (blueprint.RuleParams, error) { return p.AndroidRuleFunc(name, func(Config) (blueprint.RuleParams, error) {
return params, nil return params, nil
@ -204,16 +234,16 @@ func (p AndroidPackageContext) AndroidStaticRule(name string, params blueprint.R
} }
// AndroidGomaStaticRule wraps blueprint.StaticRule but uses goma's parallelism if goma is enabled // AndroidGomaStaticRule wraps blueprint.StaticRule but uses goma's parallelism if goma is enabled
func (p AndroidPackageContext) AndroidGomaStaticRule(name string, params blueprint.RuleParams, func (p PackageContext) AndroidGomaStaticRule(name string, params blueprint.RuleParams,
argNames ...string) blueprint.Rule { argNames ...string) blueprint.Rule {
return p.StaticRule(name, params, argNames...) return p.StaticRule(name, params, argNames...)
} }
func (p AndroidPackageContext) AndroidRuleFunc(name string, func (p PackageContext) AndroidRuleFunc(name string,
f func(Config) (blueprint.RuleParams, error), argNames ...string) blueprint.Rule { f func(Config) (blueprint.RuleParams, error), argNames ...string) blueprint.Rule {
return p.PackageContext.RuleFunc(name, func(config interface{}) (blueprint.RuleParams, error) { return p.RuleFunc(name, func(config Config) (blueprint.RuleParams, error) {
params, err := f(config.(Config)) params, err := f(config)
if config.(Config).UseGoma() && params.Pool == nil { if config.UseGoma() && params.Pool == nil {
// When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the // When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the
// local parallelism value // local parallelism value
params.Pool = localPool params.Pool = localPool

View File

@ -449,6 +449,10 @@ func (p basePath) Rel() string {
return p.path return p.path
} }
func (p basePath) String() string {
return p.path
}
// SourcePath is a Path representing a file path rooted from SrcDir // SourcePath is a Path representing a file path rooted from SrcDir
type SourcePath struct { type SourcePath struct {
basePath basePath
@ -885,6 +889,13 @@ func validatePath(ctx PathContext, pathComponents ...string) string {
return validateSafePath(ctx, pathComponents...) return validateSafePath(ctx, pathComponents...)
} }
func PathForPhony(ctx PathContext, phony string) WritablePath {
if strings.ContainsAny(phony, "$/") {
reportPathError(ctx, "Phony target contains invalid character ($ or /): %s", phony)
}
return OutputPath{basePath{phony, pathConfig(ctx), ""}}
}
type testPath struct { type testPath struct {
basePath basePath
} }

View File

@ -44,7 +44,7 @@ var mutators []*mutator
type ModuleFactory func() Module type ModuleFactory func() Module
// ModuleFactoryAdaptor Wraps a ModuleFactory into a blueprint.ModuleFactory by converting an Module // ModuleFactoryAdaptor wraps a ModuleFactory into a blueprint.ModuleFactory by converting a Module
// into a blueprint.Module and a list of property structs // into a blueprint.Module and a list of property structs
func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory { func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory {
return func() (blueprint.Module, []interface{}) { return func() (blueprint.Module, []interface{}) {
@ -53,16 +53,27 @@ func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory {
} }
} }
type SingletonFactory func() Singleton
// SingletonFactoryAdaptor wraps a SingletonFactory into a blueprint.SingletonFactory by converting
// a Singleton into a blueprint.Singleton
func SingletonFactoryAdaptor(factory SingletonFactory) blueprint.SingletonFactory {
return func() blueprint.Singleton {
singleton := factory()
return singletonAdaptor{singleton}
}
}
func RegisterModuleType(name string, factory ModuleFactory) { func RegisterModuleType(name string, factory ModuleFactory) {
moduleTypes = append(moduleTypes, moduleType{name, ModuleFactoryAdaptor(factory)}) moduleTypes = append(moduleTypes, moduleType{name, ModuleFactoryAdaptor(factory)})
} }
func RegisterSingletonType(name string, factory blueprint.SingletonFactory) { func RegisterSingletonType(name string, factory SingletonFactory) {
singletons = append(singletons, singleton{name, factory}) singletons = append(singletons, singleton{name, SingletonFactoryAdaptor(factory)})
} }
func RegisterPreSingletonType(name string, factory blueprint.SingletonFactory) { func RegisterPreSingletonType(name string, factory SingletonFactory) {
preSingletons = append(preSingletons, singleton{name, factory}) preSingletons = append(preSingletons, singleton{name, SingletonFactoryAdaptor(factory)})
} }
type Context struct { type Context struct {

162
android/singleton.go Normal file
View File

@ -0,0 +1,162 @@
// Copyright 2017 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 (
"github.com/google/blueprint"
"github.com/google/blueprint/pathtools"
)
// SingletonContext
type SingletonContext interface {
// TODO(ccross): make this return an android.Config
Config() interface{}
ModuleName(module blueprint.Module) string
ModuleDir(module blueprint.Module) string
ModuleSubDir(module blueprint.Module) string
ModuleType(module blueprint.Module) string
BlueprintFile(module blueprint.Module) string
ModuleErrorf(module blueprint.Module, format string, args ...interface{})
Errorf(format string, args ...interface{})
Failed() bool
Variable(pctx PackageContext, name, value string)
Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) blueprint.Rule
Build(pctx PackageContext, params BuildParams)
RequireNinjaVersion(major, minor, micro int)
// SetNinjaBuildDir sets the value of the top-level "builddir" Ninja variable
// that controls where Ninja stores its build log files. This value can be
// set at most one time for a single build, later calls are ignored.
SetNinjaBuildDir(pctx PackageContext, value string)
// Eval takes a string with embedded ninja variables, and returns a string
// with all of the variables recursively expanded. Any variables references
// are expanded in the scope of the PackageContext.
Eval(pctx PackageContext, ninjaStr string) (string, error)
VisitAllModules(visit func(Module))
VisitAllModulesIf(pred func(Module) bool, visit func(Module))
VisitDepsDepthFirst(module Module, visit func(Module))
VisitDepsDepthFirstIf(module Module, pred func(Module) bool,
visit func(Module))
VisitAllModuleVariants(module Module, visit func(Module))
PrimaryModule(module Module) Module
FinalModule(module Module) Module
AddNinjaFileDeps(deps ...string)
// GlobWithDeps returns a list of files that match the specified pattern but do not match any
// of the patterns in excludes. It also adds efficient dependencies to rerun the primary
// builder whenever a file matching the pattern as added or removed, without rerunning if a
// file that does not match the pattern is added to a searched directory.
GlobWithDeps(pattern string, excludes []string) ([]string, error)
Fs() pathtools.FileSystem
}
type singletonAdaptor struct {
Singleton
}
func (s singletonAdaptor) GenerateBuildActions(ctx blueprint.SingletonContext) {
s.Singleton.GenerateBuildActions(singletonContextAdaptor{ctx})
}
type Singleton interface {
GenerateBuildActions(SingletonContext)
}
type singletonContextAdaptor struct {
blueprint.SingletonContext
}
func (s singletonContextAdaptor) Variable(pctx PackageContext, name, value string) {
s.SingletonContext.Variable(pctx.PackageContext, name, value)
}
func (s singletonContextAdaptor) Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) blueprint.Rule {
return s.SingletonContext.Rule(pctx.PackageContext, name, params.RuleParams, argNames...)
}
func (s singletonContextAdaptor) Build(pctx PackageContext, params BuildParams) {
bparams := convertBuildParams(params)
s.SingletonContext.Build(pctx.PackageContext, bparams)
}
func (s singletonContextAdaptor) SetNinjaBuildDir(pctx PackageContext, value string) {
s.SingletonContext.SetNinjaBuildDir(pctx.PackageContext, value)
}
func (s singletonContextAdaptor) Eval(pctx PackageContext, ninjaStr string) (string, error) {
return s.SingletonContext.Eval(pctx.PackageContext, ninjaStr)
}
// visitAdaptor wraps a visit function that takes an android.Module parameter into
// a function that takes an blueprint.Module parameter and only calls the visit function if the
// blueprint.Module is an android.Module.
func visitAdaptor(visit func(Module)) func(blueprint.Module) {
return func(module blueprint.Module) {
if aModule, ok := module.(Module); ok {
visit(aModule)
}
}
}
// predAdaptor wraps a pred function that takes an android.Module parameter
// into a function that takes an blueprint.Module parameter and only calls the visit function if the
// blueprint.Module is an android.Module, otherwise returns false.
func predAdaptor(pred func(Module) bool) func(blueprint.Module) bool {
return func(module blueprint.Module) bool {
if aModule, ok := module.(Module); ok {
return pred(aModule)
} else {
return false
}
}
}
func (s singletonContextAdaptor) VisitAllModules(visit func(Module)) {
s.SingletonContext.VisitAllModules(visitAdaptor(visit))
}
func (s singletonContextAdaptor) VisitAllModulesIf(pred func(Module) bool, visit func(Module)) {
s.SingletonContext.VisitAllModulesIf(predAdaptor(pred), visitAdaptor(visit))
}
func (s singletonContextAdaptor) VisitDepsDepthFirst(module Module, visit func(Module)) {
s.SingletonContext.VisitDepsDepthFirst(module, visitAdaptor(visit))
}
func (s singletonContextAdaptor) VisitDepsDepthFirstIf(module Module, pred func(Module) bool, visit func(Module)) {
s.SingletonContext.VisitDepsDepthFirstIf(module, predAdaptor(pred), visitAdaptor(visit))
}
func (s singletonContextAdaptor) VisitAllModuleVariants(module Module, visit func(Module)) {
s.SingletonContext.VisitAllModuleVariants(module, visitAdaptor(visit))
}
func (s singletonContextAdaptor) PrimaryModule(module Module) Module {
return s.SingletonContext.PrimaryModule(module).(Module)
}
func (s singletonContextAdaptor) FinalModule(module Module) Module {
return s.SingletonContext.FinalModule(module).(Module)
}

View File

@ -318,7 +318,7 @@ func (c *stubDecorator) AndroidMk(ctx AndroidMkContext, ret *android.AndroidMkDa
ret.Class = "SHARED_LIBRARIES" ret.Class = "SHARED_LIBRARIES"
ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) { ret.Extra = append(ret.Extra, func(w io.Writer, outputFile android.Path) {
path, file := filepath.Split(c.installPath) path, file := filepath.Split(c.installPath.String())
stem := strings.TrimSuffix(file, filepath.Ext(file)) stem := strings.TrimSuffix(file, filepath.Ext(file))
fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=") fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+outputFile.Ext()) fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+outputFile.Ext())

View File

@ -23,8 +23,6 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/google/blueprint"
) )
// This singleton generates CMakeLists.txt files. It does so for each blueprint Android.bp resulting in a cc.Module // This singleton generates CMakeLists.txt files. It does so for each blueprint Android.bp resulting in a cc.Module
@ -35,7 +33,7 @@ func init() {
android.RegisterSingletonType("cmakelists_generator", cMakeListsGeneratorSingleton) android.RegisterSingletonType("cmakelists_generator", cMakeListsGeneratorSingleton)
} }
func cMakeListsGeneratorSingleton() blueprint.Singleton { func cMakeListsGeneratorSingleton() android.Singleton {
return &cmakelistsGeneratorSingleton{} return &cmakelistsGeneratorSingleton{}
} }
@ -57,14 +55,14 @@ const (
// This is done to ease investigating bug reports. // This is done to ease investigating bug reports.
var outputDebugInfo = false var outputDebugInfo = false
func (c *cmakelistsGeneratorSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) { func (c *cmakelistsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) {
if getEnvVariable(envVariableGenerateCMakeLists, ctx) != envVariableTrue { if getEnvVariable(envVariableGenerateCMakeLists, ctx) != envVariableTrue {
return return
} }
outputDebugInfo = (getEnvVariable(envVariableGenerateDebugInfo, ctx) == envVariableTrue) outputDebugInfo = (getEnvVariable(envVariableGenerateDebugInfo, ctx) == envVariableTrue)
ctx.VisitAllModules(func(module blueprint.Module) { ctx.VisitAllModules(func(module android.Module) {
if ccModule, ok := module.(*Module); ok { if ccModule, ok := module.(*Module); ok {
if compiledModule, ok := ccModule.compiler.(CompiledInterface); ok { if compiledModule, ok := ccModule.compiler.(CompiledInterface); ok {
generateCLionProject(compiledModule, ctx, ccModule) generateCLionProject(compiledModule, ctx, ccModule)
@ -81,7 +79,7 @@ func (c *cmakelistsGeneratorSingleton) GenerateBuildActions(ctx blueprint.Single
return return
} }
func getEnvVariable(name string, ctx blueprint.SingletonContext) string { func getEnvVariable(name string, ctx android.SingletonContext) string {
// Using android.Config.Getenv instead of os.getEnv to guarantee soong will // Using android.Config.Getenv instead of os.getEnv to guarantee soong will
// re-run in case this environment variable changes. // re-run in case this environment variable changes.
return ctx.Config().(android.Config).Getenv(name) return ctx.Config().(android.Config).Getenv(name)
@ -116,7 +114,7 @@ func linkAggregateCMakeListsFiles(path string, info os.FileInfo, err error) erro
return nil return nil
} }
func generateCLionProject(compiledModule CompiledInterface, ctx blueprint.SingletonContext, ccModule *Module) { func generateCLionProject(compiledModule CompiledInterface, ctx android.SingletonContext, ccModule *Module) {
srcs := compiledModule.Srcs() srcs := compiledModule.Srcs()
if len(srcs) == 0 { if len(srcs) == 0 {
return return
@ -287,7 +285,7 @@ func categorizeParameter(parameter string) parameterType {
return flag return flag
} }
func parseCompilerParameters(params []string, ctx blueprint.SingletonContext, f *os.File) compilerParameters { func parseCompilerParameters(params []string, ctx android.SingletonContext, f *os.File) compilerParameters {
var compilerParameters = makeCompilerParameters() var compilerParameters = makeCompilerParameters()
for i, str := range params { for i, str := range params {
@ -388,7 +386,7 @@ func concatenateParams(c1 *compilerParameters, c2 compilerParameters) {
c1.flags = append(c1.flags, c2.flags...) c1.flags = append(c1.flags, c2.flags...)
} }
func evalVariable(ctx blueprint.SingletonContext, str string) (string, error) { func evalVariable(ctx android.SingletonContext, str string) (string, error) {
evaluated, err := ctx.Eval(pctx, str) evaluated, err := ctx.Eval(pctx, str)
if err == nil { if err == nil {
return evaluated, nil return evaluated, nil
@ -396,7 +394,7 @@ func evalVariable(ctx blueprint.SingletonContext, str string) (string, error) {
return "", err return "", err
} }
func getCMakeListsForModule(module *Module, ctx blueprint.SingletonContext) string { func getCMakeListsForModule(module *Module, ctx android.SingletonContext) string {
return filepath.Join(getAndroidSrcRootDirectory(ctx), return filepath.Join(getAndroidSrcRootDirectory(ctx),
cLionOutputProjectsDirectory, cLionOutputProjectsDirectory,
path.Dir(ctx.BlueprintFile(module)), path.Dir(ctx.BlueprintFile(module)),
@ -406,7 +404,7 @@ func getCMakeListsForModule(module *Module, ctx blueprint.SingletonContext) stri
cMakeListsFilename) cMakeListsFilename)
} }
func getAndroidSrcRootDirectory(ctx blueprint.SingletonContext) string { func getAndroidSrcRootDirectory(ctx android.SingletonContext) string {
srcPath, _ := filepath.Abs(android.PathForSource(ctx).String()) srcPath, _ := filepath.Abs(android.PathForSource(ctx).String())
return srcPath return srcPath
} }

View File

@ -216,14 +216,14 @@ func init() {
[]string{"libnativehelper/include_deprecated"}) []string{"libnativehelper/include_deprecated"})
pctx.SourcePathVariable("ClangDefaultBase", ClangDefaultBase) pctx.SourcePathVariable("ClangDefaultBase", ClangDefaultBase)
pctx.VariableFunc("ClangBase", func(config interface{}) (string, error) { pctx.VariableFunc("ClangBase", func(config android.Config) (string, error) {
if override := config.(android.Config).Getenv("LLVM_PREBUILTS_BASE"); override != "" { if override := config.Getenv("LLVM_PREBUILTS_BASE"); override != "" {
return override, nil return override, nil
} }
return "${ClangDefaultBase}", nil return "${ClangDefaultBase}", nil
}) })
pctx.VariableFunc("ClangVersion", func(config interface{}) (string, error) { pctx.VariableFunc("ClangVersion", func(config android.Config) (string, error) {
if override := config.(android.Config).Getenv("LLVM_PREBUILTS_VERSION"); override != "" { if override := config.Getenv("LLVM_PREBUILTS_VERSION"); override != "" {
return override, nil return override, nil
} }
return ClangDefaultVersion, nil return ClangDefaultVersion, nil
@ -231,8 +231,8 @@ func init() {
pctx.StaticVariable("ClangPath", "${ClangBase}/${HostPrebuiltTag}/${ClangVersion}") pctx.StaticVariable("ClangPath", "${ClangBase}/${HostPrebuiltTag}/${ClangVersion}")
pctx.StaticVariable("ClangBin", "${ClangPath}/bin") pctx.StaticVariable("ClangBin", "${ClangPath}/bin")
pctx.VariableFunc("ClangShortVersion", func(config interface{}) (string, error) { pctx.VariableFunc("ClangShortVersion", func(config android.Config) (string, error) {
if override := config.(android.Config).Getenv("LLVM_RELEASE_VERSION"); override != "" { if override := config.Getenv("LLVM_RELEASE_VERSION"); override != "" {
return override, nil return override, nil
} }
return ClangDefaultShortVersion, nil return ClangDefaultShortVersion, nil
@ -258,8 +258,8 @@ func init() {
"frameworks/rs/script_api/include", "frameworks/rs/script_api/include",
}) })
pctx.VariableFunc("CcWrapper", func(config interface{}) (string, error) { pctx.VariableFunc("CcWrapper", func(config android.Config) (string, error) {
if override := config.(android.Config).Getenv("CC_WRAPPER"); override != "" { if override := config.Getenv("CC_WRAPPER"); override != "" {
return override + " ", nil return override + " ", nil
} }
return "", nil return "", nil

View File

@ -25,8 +25,8 @@ func init() {
// Global tidy checks include only google*, performance*, // Global tidy checks include only google*, performance*,
// and misc-macro-parentheses, but not google-readability* // and misc-macro-parentheses, but not google-readability*
// or google-runtime-references. // or google-runtime-references.
pctx.VariableFunc("TidyDefaultGlobalChecks", func(config interface{}) (string, error) { pctx.VariableFunc("TidyDefaultGlobalChecks", func(config android.Config) (string, error) {
if override := config.(android.Config).Getenv("DEFAULT_GLOBAL_TIDY_CHECKS"); override != "" { if override := config.Getenv("DEFAULT_GLOBAL_TIDY_CHECKS"); override != "" {
return override, nil return override, nil
} }
return strings.Join([]string{ return strings.Join([]string{
@ -41,8 +41,8 @@ func init() {
// There are too many clang-tidy warnings in external and vendor projects. // There are too many clang-tidy warnings in external and vendor projects.
// Enable only some google checks for these projects. // Enable only some google checks for these projects.
pctx.VariableFunc("TidyExternalVendorChecks", func(config interface{}) (string, error) { pctx.VariableFunc("TidyExternalVendorChecks", func(config android.Config) (string, error) {
if override := config.(android.Config).Getenv("DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS"); override != "" { if override := config.Getenv("DEFAULT_EXTERNAL_VENDOR_TIDY_CHECKS"); override != "" {
return override, nil return override, nil
} }
return strings.Join([]string{ return strings.Join([]string{

View File

@ -107,25 +107,25 @@ const (
) )
func init() { func init() {
pctx.VariableFunc("macSdkPath", func(config interface{}) (string, error) { pctx.VariableFunc("macSdkPath", func(config android.Config) (string, error) {
xcodeselect := config.(android.Config).HostSystemTool("xcode-select") xcodeselect := config.HostSystemTool("xcode-select")
bytes, err := exec.Command(xcodeselect, "--print-path").Output() bytes, err := exec.Command(xcodeselect, "--print-path").Output()
return strings.TrimSpace(string(bytes)), err return strings.TrimSpace(string(bytes)), err
}) })
pctx.VariableFunc("macSdkRoot", func(config interface{}) (string, error) { pctx.VariableFunc("macSdkRoot", func(config android.Config) (string, error) {
return xcrunSdk(config.(android.Config), "--show-sdk-path") return xcrunSdk(config, "--show-sdk-path")
}) })
pctx.StaticVariable("macMinVersion", "10.8") pctx.StaticVariable("macMinVersion", "10.8")
pctx.VariableFunc("MacArPath", func(config interface{}) (string, error) { pctx.VariableFunc("MacArPath", func(config android.Config) (string, error) {
return xcrun(config.(android.Config), "--find", "ar") return xcrun(config, "--find", "ar")
}) })
pctx.VariableFunc("MacStripPath", func(config interface{}) (string, error) { pctx.VariableFunc("MacStripPath", func(config android.Config) (string, error) {
return xcrun(config.(android.Config), "--find", "strip") return xcrun(config, "--find", "strip")
}) })
pctx.VariableFunc("MacToolPath", func(config interface{}) (string, error) { pctx.VariableFunc("MacToolPath", func(config android.Config) (string, error) {
path, err := xcrun(config.(android.Config), "--find", "ld") path, err := xcrun(config, "--find", "ld")
return filepath.Dir(path), err return filepath.Dir(path), err
}) })

View File

@ -85,9 +85,6 @@ type LibraryMutatedProperties struct {
VariantIsShared bool `blueprint:"mutated"` VariantIsShared bool `blueprint:"mutated"`
// This variant is static // This variant is static
VariantIsStatic bool `blueprint:"mutated"` VariantIsStatic bool `blueprint:"mutated"`
// Location of the static library in the sysroot. Empty if the library is
// not included in the NDK.
NdkSysrootPath string `blueprint:"mutated"`
} }
type FlagExporterProperties struct { type FlagExporterProperties struct {
@ -246,6 +243,10 @@ type libraryDecorator struct {
// Source Abi Diff // Source Abi Diff
sAbiDiff android.OptionalPath sAbiDiff android.OptionalPath
// Location of the static library in the sysroot. Empty if the library is
// not included in the NDK.
ndkSysrootPath android.Path
// Decorated interafaces // Decorated interafaces
*baseCompiler *baseCompiler
*baseLinker *baseLinker
@ -742,7 +743,7 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
Input: file, Input: file,
}) })
library.MutatedProperties.NdkSysrootPath = installPath.String() library.ndkSysrootPath = installPath
} }
} }

View File

@ -74,7 +74,7 @@ type headerModule struct {
properties headerProperies properties headerProperies
installPaths []string installPaths android.Paths
licensePath android.ModuleSrcPath licensePath android.ModuleSrcPath
} }
@ -139,7 +139,7 @@ func (m *headerModule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
"expected header install path (%q) not equal to actual install path %q", "expected header install path (%q) not equal to actual install path %q",
installPath, installedPath)) installPath, installedPath))
} }
m.installPaths = append(m.installPaths, installPath.String()) m.installPaths = append(m.installPaths, installPath)
} }
if len(m.installPaths) == 0 { if len(m.installPaths) == 0 {
@ -186,7 +186,7 @@ type preprocessedHeaderModule struct {
properties preprocessedHeaderProperies properties preprocessedHeaderProperies
installPaths []string installPaths android.Paths
licensePath android.ModuleSrcPath licensePath android.ModuleSrcPath
} }
@ -208,7 +208,7 @@ func (m *preprocessedHeaderModule) GenerateAndroidBuildActions(ctx android.Modul
installDir := getHeaderInstallDir(ctx, header, String(m.properties.From), String(m.properties.To)) installDir := getHeaderInstallDir(ctx, header, String(m.properties.From), String(m.properties.To))
installPath := installDir.Join(ctx, header.Base()) installPath := installDir.Join(ctx, header.Base())
installPaths = append(installPaths, installPath) installPaths = append(installPaths, installPath)
m.installPaths = append(m.installPaths, installPath.String()) m.installPaths = append(m.installPaths, installPath)
} }
if len(m.installPaths) == 0 { if len(m.installPaths) == 0 {

View File

@ -98,7 +98,7 @@ type stubDecorator struct {
properties libraryProperties properties libraryProperties
versionScriptPath android.ModuleGenPath versionScriptPath android.ModuleGenPath
installPath string installPath android.Path
} }
// OMG GO // OMG GO
@ -344,7 +344,7 @@ func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) {
installDir := getNdkInstallBase(ctx).Join(ctx, fmt.Sprintf( installDir := getNdkInstallBase(ctx).Join(ctx, fmt.Sprintf(
"platforms/android-%s/arch-%s/usr/%s", apiLevel, arch, libDir)) "platforms/android-%s/arch-%s/usr/%s", apiLevel, arch, libDir))
stub.installPath = ctx.InstallFile(installDir, path.Base(), path).String() stub.installPath = ctx.InstallFile(installDir, path.Base(), path)
} }
func newStubLibrary() *Module { func newStubLibrary() *Module {

View File

@ -53,8 +53,6 @@ package cc
// TODO(danalbert): Write `ndk_static_library` rule. // TODO(danalbert): Write `ndk_static_library` rule.
import ( import (
"github.com/google/blueprint"
"android/soong/android" "android/soong/android"
) )
@ -76,32 +74,32 @@ func getNdkSysrootBase(ctx android.PathContext) android.OutputPath {
return getNdkInstallBase(ctx).Join(ctx, "sysroot") return getNdkInstallBase(ctx).Join(ctx, "sysroot")
} }
func getNdkSysrootTimestampFile(ctx android.PathContext) android.Path { func getNdkSysrootTimestampFile(ctx android.PathContext) android.WritablePath {
return android.PathForOutput(ctx, "ndk.timestamp") return android.PathForOutput(ctx, "ndk.timestamp")
} }
func NdkSingleton() blueprint.Singleton { func NdkSingleton() android.Singleton {
return &ndkSingleton{} return &ndkSingleton{}
} }
type ndkSingleton struct{} type ndkSingleton struct{}
func (n *ndkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) { func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
installPaths := []string{} var installPaths android.Paths
licensePaths := []string{} var licensePaths android.Paths
ctx.VisitAllModules(func(module blueprint.Module) { ctx.VisitAllModules(func(module android.Module) {
if m, ok := module.(android.Module); ok && !m.Enabled() { if m, ok := module.(android.Module); ok && !m.Enabled() {
return return
} }
if m, ok := module.(*headerModule); ok { if m, ok := module.(*headerModule); ok {
installPaths = append(installPaths, m.installPaths...) installPaths = append(installPaths, m.installPaths...)
licensePaths = append(licensePaths, m.licensePath.String()) licensePaths = append(licensePaths, m.licensePath)
} }
if m, ok := module.(*preprocessedHeaderModule); ok { if m, ok := module.(*preprocessedHeaderModule); ok {
installPaths = append(installPaths, m.installPaths...) installPaths = append(installPaths, m.installPaths...)
licensePaths = append(licensePaths, m.licensePath.String()) licensePaths = append(licensePaths, m.licensePath)
} }
if m, ok := module.(*Module); ok { if m, ok := module.(*Module); ok {
@ -110,30 +108,28 @@ func (n *ndkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
} }
if library, ok := m.linker.(*libraryDecorator); ok { if library, ok := m.linker.(*libraryDecorator); ok {
if library.MutatedProperties.NdkSysrootPath != "" { if library.ndkSysrootPath != nil {
installPaths = append(installPaths, library.MutatedProperties.NdkSysrootPath) installPaths = append(installPaths, library.ndkSysrootPath)
} }
} }
} }
}) })
combinedLicense := getNdkInstallBase(ctx).Join(ctx, "NOTICE") combinedLicense := getNdkInstallBase(ctx).Join(ctx, "NOTICE")
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: android.Cat, Rule: android.Cat,
Description: "combine licenses", Description: "combine licenses",
Outputs: []string{combinedLicense.String()}, Output: combinedLicense,
Inputs: licensePaths, Inputs: licensePaths,
Optional: true,
}) })
depPaths := append(installPaths, combinedLicense.String()) depPaths := append(installPaths, combinedLicense)
// There's a dummy "ndk" rule defined in ndk/Android.mk that depends on // There's a dummy "ndk" rule defined in ndk/Android.mk that depends on
// this. `m ndk` will build the sysroots. // this. `m ndk` will build the sysroots.
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: android.Touch, Rule: android.Touch,
Outputs: []string{getNdkSysrootTimestampFile(ctx).String()}, Output: getNdkSysrootTimestampFile(ctx),
Implicits: depPaths, Implicits: depPaths,
Optional: true,
}) })
} }

View File

@ -64,9 +64,9 @@ func init() {
pctx.VariableConfigMethod("hostPrebuiltTag", android.Config.PrebuiltOS) pctx.VariableConfigMethod("hostPrebuiltTag", android.Config.PrebuiltOS)
pctx.VariableFunc("JavaHome", func(config interface{}) (string, error) { pctx.VariableFunc("JavaHome", func(config android.Config) (string, error) {
// This is set up and guaranteed by soong_ui // This is set up and guaranteed by soong_ui
return config.(android.Config).Getenv("ANDROID_JAVA_HOME"), nil return config.Getenv("ANDROID_JAVA_HOME"), nil
}) })
pctx.SourcePathVariable("JavaToolchain", "${JavaHome}/bin") pctx.SourcePathVariable("JavaToolchain", "${JavaHome}/bin")
@ -85,9 +85,9 @@ func init() {
pctx.HostBinToolVariable("SoongZipCmd", "soong_zip") pctx.HostBinToolVariable("SoongZipCmd", "soong_zip")
pctx.HostBinToolVariable("MergeZipsCmd", "merge_zips") pctx.HostBinToolVariable("MergeZipsCmd", "merge_zips")
pctx.HostBinToolVariable("Zip2ZipCmd", "zip2zip") pctx.HostBinToolVariable("Zip2ZipCmd", "zip2zip")
pctx.VariableFunc("DxCmd", func(config interface{}) (string, error) { pctx.VariableFunc("DxCmd", func(config android.Config) (string, error) {
if config.(android.Config).IsEnvFalse("USE_D8") { if config.IsEnvFalse("USE_D8") {
if config.(android.Config).UnbundledBuild() || config.(android.Config).IsPdkBuild() { if config.UnbundledBuild() || config.IsPdkBuild() {
return "prebuilts/build-tools/common/bin/dx", nil return "prebuilts/build-tools/common/bin/dx", nil
} else { } else {
path, err := pctx.HostBinToolPath(config, "dx") path, err := pctx.HostBinToolPath(config, "dx")
@ -104,9 +104,9 @@ func init() {
return path.String(), nil return path.String(), nil
} }
}) })
pctx.VariableFunc("TurbineJar", func(config interface{}) (string, error) { pctx.VariableFunc("TurbineJar", func(config android.Config) (string, error) {
turbine := "turbine.jar" turbine := "turbine.jar"
if config.(android.Config).UnbundledBuild() { if config.UnbundledBuild() {
return "prebuilts/build-tools/common/framework/" + turbine, nil return "prebuilts/build-tools/common/framework/" + turbine, nil
} else { } else {
path, err := pctx.HostJavaToolPath(config, turbine) path, err := pctx.HostJavaToolPath(config, turbine)
@ -122,8 +122,8 @@ func init() {
pctx.HostBinToolVariable("SoongJavacWrapper", "soong_javac_wrapper") pctx.HostBinToolVariable("SoongJavacWrapper", "soong_javac_wrapper")
pctx.VariableFunc("JavacWrapper", func(config interface{}) (string, error) { pctx.VariableFunc("JavacWrapper", func(config android.Config) (string, error) {
if override := config.(android.Config).Getenv("JAVAC_WRAPPER"); override != "" { if override := config.Getenv("JAVAC_WRAPPER"); override != "" {
return override + " ", nil return override + " ", nil
} }
return "", nil return "", nil

View File

@ -14,6 +14,8 @@
package config package config
import "android/soong/android"
var ( var (
// These will be filled out by external/error_prone/soong/error_prone.go if it is available // These will be filled out by external/error_prone/soong/error_prone.go if it is available
ErrorProneJavacJar string ErrorProneJavacJar string
@ -25,7 +27,7 @@ var (
// Wrapper that grabs value of val late so it can be initialized by a later module's init function // Wrapper that grabs value of val late so it can be initialized by a later module's init function
func errorProneVar(name string, val *string) { func errorProneVar(name string, val *string) {
pctx.VariableFunc(name, func(config interface{}) (string, error) { pctx.VariableFunc(name, func(config android.Config) (string, error) {
return *val, nil return *val, nil
}) })
} }

View File

@ -28,8 +28,6 @@ func init() {
pctx.HostBinToolVariable("aidlCmd", "aidl") pctx.HostBinToolVariable("aidlCmd", "aidl")
pctx.SourcePathVariable("logtagsCmd", "build/tools/java-event-log-tags.py") pctx.SourcePathVariable("logtagsCmd", "build/tools/java-event-log-tags.py")
pctx.SourcePathVariable("mergeLogtagsCmd", "build/tools/merge-event-log-tags.py") pctx.SourcePathVariable("mergeLogtagsCmd", "build/tools/merge-event-log-tags.py")
pctx.IntermediatesPathVariable("allLogtagsFile", "all-event-log-tags.txt")
} }
var ( var (
@ -117,7 +115,7 @@ func (j *Module) genSources(ctx android.ModuleContext, srcFiles android.Paths,
return outSrcFiles return outSrcFiles
} }
func LogtagsSingleton() blueprint.Singleton { func LogtagsSingleton() android.Singleton {
return &logtagsSingleton{} return &logtagsSingleton{}
} }
@ -127,18 +125,18 @@ type logtagsProducer interface {
type logtagsSingleton struct{} type logtagsSingleton struct{}
func (l *logtagsSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) { func (l *logtagsSingleton) GenerateBuildActions(ctx android.SingletonContext) {
var allLogtags android.Paths var allLogtags android.Paths
ctx.VisitAllModules(func(module blueprint.Module) { ctx.VisitAllModules(func(module android.Module) {
if logtags, ok := module.(logtagsProducer); ok { if logtags, ok := module.(logtagsProducer); ok {
allLogtags = append(allLogtags, logtags.logtags()...) allLogtags = append(allLogtags, logtags.logtags()...)
} }
}) })
ctx.Build(pctx, blueprint.BuildParams{ ctx.Build(pctx, android.BuildParams{
Rule: mergeLogtags, Rule: mergeLogtags,
Description: "merge logtags", Description: "merge logtags",
Outputs: []string{"$allLogtagsFile"}, Output: android.PathForIntermediates(ctx, "all-event-log-tags.txt"),
Inputs: allLogtags.Strings(), Inputs: allLogtags,
}) })
} }