Wrap PackageContext and SingletonContext am: 0875c52de7

am: a0a0b7fd90

Change-Id: Idae0e7a1a217626a834e2b1c73ab75244f334d06
This commit is contained in:
Colin Cross 2017-11-29 05:22:09 +00:00 committed by android-build-merger
commit a0b69a22a9
21 changed files with 479 additions and 243 deletions

View file

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

View file

@ -53,13 +53,13 @@ type AndroidMkData struct {
type AndroidMkExtraFunc func(w io.Writer, outputFile Path)
func AndroidMkSingleton() blueprint.Singleton {
func AndroidMkSingleton() Singleton {
return &androidMkSingleton{}
}
type androidMkSingleton struct{}
func (c *androidMkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) {
config := ctx.Config().(Config)
if !config.EmbeddedInMake() {
@ -68,10 +68,8 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext
var androidMkModulesList []Module
ctx.VisitAllModules(func(module blueprint.Module) {
if amod, ok := module.(Module); ok {
androidMkModulesList = append(androidMkModulesList, amod)
}
ctx.VisitAllModules(func(module Module) {
androidMkModulesList = append(androidMkModulesList, module)
})
sort.Sort(AndroidModulesByName{androidMkModulesList, ctx})
@ -86,14 +84,13 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext
ctx.Errorf(err.Error())
}
ctx.Build(pctx, blueprint.BuildParams{
Rule: blueprint.Phony,
Outputs: []string{transMk.String()},
Optional: true,
ctx.Build(pctx, BuildParams{
Rule: blueprint.Phony,
Output: transMk,
})
}
func translateAndroidMk(ctx blueprint.SingletonContext, mkFile string, mods []Module) error {
func translateAndroidMk(ctx SingletonContext, mkFile string, mods []Module) error {
buf := &bytes.Buffer{}
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)
}
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)
if !ok {
return nil

View file

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

View file

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

View file

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

View file

@ -22,14 +22,14 @@ import (
"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.
type AndroidPackageContext struct {
type PackageContext struct {
blueprint.PackageContext
}
func NewPackageContext(pkgPath string) AndroidPackageContext {
return AndroidPackageContext{blueprint.NewPackageContext(pkgPath)}
func NewPackageContext(pkgPath string) PackageContext {
return PackageContext{blueprint.NewPackageContext(pkgPath)}
}
// 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
// provided, and an error should be returned.
type configErrorWrapper struct {
pctx AndroidPackageContext
pctx PackageContext
config Config
errors []error
}
@ -61,13 +61,43 @@ func (e *configErrorWrapper) Fs() pathtools.FileSystem {
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
// 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-scoped variable's initialization.
func (p AndroidPackageContext) SourcePathVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}}
func (p PackageContext) SourcePathVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config, []error{}}
p := safePathForSource(ctx, path)
if len(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
// called during a Go package's initialization - either from the init()
// function or as part of a package-scoped variable's initialization.
func (p AndroidPackageContext) SourcePathsVariable(name, separator string, paths ...string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}}
func (p PackageContext) SourcePathsVariable(name, separator string, paths ...string) blueprint.Variable {
return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config, []error{}}
var ret []string
for _, path := range paths {
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.
// 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.
func (p AndroidPackageContext) SourcePathVariableWithEnvOverride(name, path, env string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}}
func (p PackageContext) SourcePathVariableWithEnvOverride(name, path, env string) blueprint.Variable {
return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config, []error{}}
p := safePathForSource(ctx, path)
if len(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
// package's initialization - either from the init() function or as part of a
// package-scoped variable's initialization.
func (p AndroidPackageContext) HostBinToolVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) {
func (p PackageContext) HostBinToolVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config Config) (string, error) {
po, err := p.HostBinToolPath(config, path)
if err != nil {
return "", err
@ -125,8 +155,8 @@ func (p AndroidPackageContext) HostBinToolVariable(name, path string) blueprint.
})
}
func (p AndroidPackageContext) HostBinToolPath(config interface{}, path string) (Path, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}}
func (p PackageContext) HostBinToolPath(config Config, path string) (Path, error) {
ctx := &configErrorWrapper{p, config, []error{}}
pa := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "bin", path)
if len(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
// during a Go package's initialization - either from the init() function or as
// part of a package-scoped variable's initialization.
func (p AndroidPackageContext) HostJavaToolVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}}
func (p PackageContext) HostJavaToolVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config, []error{}}
p := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "framework", path)
if len(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) {
ctx := &configErrorWrapper{p, config.(Config), []error{}}
func (p PackageContext) HostJavaToolPath(config Config, path string) (Path, error) {
ctx := &configErrorWrapper{p, config, []error{}}
pa := PathForOutput(ctx, "host", ctx.config.PrebuiltOS(), "framework", path)
if len(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
// package's initialization - either from the init() function or as part of a
// package-scoped variable's initialization.
func (p AndroidPackageContext) IntermediatesPathVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config interface{}) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}}
func (p PackageContext) IntermediatesPathVariable(name, path string) blueprint.Variable {
return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config, []error{}}
p := PathForIntermediates(ctx, path)
if len(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
// be called during a Go package's initialization - either from the init()
// 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 {
return p.VariableFunc(name, func(config interface{}) (string, error) {
ctx := &configErrorWrapper{p, config.(Config), []error{}}
return p.VariableFunc(name, func(config Config) (string, error) {
ctx := &configErrorWrapper{p, config, []error{}}
paths := ExistentPathsForSources(ctx, "", paths)
if len(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
func (p AndroidPackageContext) AndroidStaticRule(name string, params blueprint.RuleParams,
func (p PackageContext) AndroidStaticRule(name string, params blueprint.RuleParams,
argNames ...string) blueprint.Rule {
return p.AndroidRuleFunc(name, func(Config) (blueprint.RuleParams, error) {
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
func (p AndroidPackageContext) AndroidGomaStaticRule(name string, params blueprint.RuleParams,
func (p PackageContext) AndroidGomaStaticRule(name string, params blueprint.RuleParams,
argNames ...string) blueprint.Rule {
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 {
return p.PackageContext.RuleFunc(name, func(config interface{}) (blueprint.RuleParams, error) {
params, err := f(config.(Config))
if config.(Config).UseGoma() && params.Pool == nil {
return p.RuleFunc(name, func(config Config) (blueprint.RuleParams, error) {
params, err := f(config)
if config.UseGoma() && params.Pool == nil {
// When USE_GOMA=true is set and the rule is not supported by goma, restrict jobs to the
// local parallelism value
params.Pool = localPool

View file

@ -449,6 +449,10 @@ func (p basePath) Rel() string {
return p.path
}
func (p basePath) String() string {
return p.path
}
// SourcePath is a Path representing a file path rooted from SrcDir
type SourcePath struct {
basePath
@ -885,6 +889,13 @@ func validatePath(ctx PathContext, pathComponents ...string) string {
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 {
basePath
}

View file

@ -44,7 +44,7 @@ var mutators []*mutator
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
func ModuleFactoryAdaptor(factory ModuleFactory) blueprint.ModuleFactory {
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) {
moduleTypes = append(moduleTypes, moduleType{name, ModuleFactoryAdaptor(factory)})
}
func RegisterSingletonType(name string, factory blueprint.SingletonFactory) {
singletons = append(singletons, singleton{name, factory})
func RegisterSingletonType(name string, factory SingletonFactory) {
singletons = append(singletons, singleton{name, SingletonFactoryAdaptor(factory)})
}
func RegisterPreSingletonType(name string, factory blueprint.SingletonFactory) {
preSingletons = append(preSingletons, singleton{name, factory})
func RegisterPreSingletonType(name string, factory SingletonFactory) {
preSingletons = append(preSingletons, singleton{name, SingletonFactoryAdaptor(factory)})
}
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.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))
fmt.Fprintln(w, "LOCAL_SYSTEM_SHARED_LIBRARIES :=")
fmt.Fprintln(w, "LOCAL_MODULE_SUFFIX := "+outputFile.Ext())

View file

@ -23,8 +23,6 @@ import (
"path"
"path/filepath"
"strings"
"github.com/google/blueprint"
)
// 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)
}
func cMakeListsGeneratorSingleton() blueprint.Singleton {
func cMakeListsGeneratorSingleton() android.Singleton {
return &cmakelistsGeneratorSingleton{}
}
@ -57,14 +55,14 @@ const (
// This is done to ease investigating bug reports.
var outputDebugInfo = false
func (c *cmakelistsGeneratorSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
func (c *cmakelistsGeneratorSingleton) GenerateBuildActions(ctx android.SingletonContext) {
if getEnvVariable(envVariableGenerateCMakeLists, ctx) != envVariableTrue {
return
}
outputDebugInfo = (getEnvVariable(envVariableGenerateDebugInfo, ctx) == envVariableTrue)
ctx.VisitAllModules(func(module blueprint.Module) {
ctx.VisitAllModules(func(module android.Module) {
if ccModule, ok := module.(*Module); ok {
if compiledModule, ok := ccModule.compiler.(CompiledInterface); ok {
generateCLionProject(compiledModule, ctx, ccModule)
@ -81,7 +79,7 @@ func (c *cmakelistsGeneratorSingleton) GenerateBuildActions(ctx blueprint.Single
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
// re-run in case this environment variable changes.
return ctx.Config().(android.Config).Getenv(name)
@ -116,7 +114,7 @@ func linkAggregateCMakeListsFiles(path string, info os.FileInfo, err error) erro
return nil
}
func generateCLionProject(compiledModule CompiledInterface, ctx blueprint.SingletonContext, ccModule *Module) {
func generateCLionProject(compiledModule CompiledInterface, ctx android.SingletonContext, ccModule *Module) {
srcs := compiledModule.Srcs()
if len(srcs) == 0 {
return
@ -287,7 +285,7 @@ func categorizeParameter(parameter string) parameterType {
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()
for i, str := range params {
@ -388,7 +386,7 @@ func concatenateParams(c1 *compilerParameters, c2 compilerParameters) {
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)
if err == nil {
return evaluated, nil
@ -396,7 +394,7 @@ func evalVariable(ctx blueprint.SingletonContext, str string) (string, error) {
return "", err
}
func getCMakeListsForModule(module *Module, ctx blueprint.SingletonContext) string {
func getCMakeListsForModule(module *Module, ctx android.SingletonContext) string {
return filepath.Join(getAndroidSrcRootDirectory(ctx),
cLionOutputProjectsDirectory,
path.Dir(ctx.BlueprintFile(module)),
@ -406,7 +404,7 @@ func getCMakeListsForModule(module *Module, ctx blueprint.SingletonContext) stri
cMakeListsFilename)
}
func getAndroidSrcRootDirectory(ctx blueprint.SingletonContext) string {
func getAndroidSrcRootDirectory(ctx android.SingletonContext) string {
srcPath, _ := filepath.Abs(android.PathForSource(ctx).String())
return srcPath
}

View file

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

View file

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

View file

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

View file

@ -85,9 +85,6 @@ type LibraryMutatedProperties struct {
VariantIsShared bool `blueprint:"mutated"`
// This variant is static
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 {
@ -246,6 +243,10 @@ type libraryDecorator struct {
// Source Abi Diff
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
*baseCompiler
*baseLinker
@ -742,7 +743,7 @@ func (library *libraryDecorator) install(ctx ModuleContext, file android.Path) {
Input: file,
})
library.MutatedProperties.NdkSysrootPath = installPath.String()
library.ndkSysrootPath = installPath
}
}

View file

@ -74,7 +74,7 @@ type headerModule struct {
properties headerProperies
installPaths []string
installPaths android.Paths
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",
installPath, installedPath))
}
m.installPaths = append(m.installPaths, installPath.String())
m.installPaths = append(m.installPaths, installPath)
}
if len(m.installPaths) == 0 {
@ -186,7 +186,7 @@ type preprocessedHeaderModule struct {
properties preprocessedHeaderProperies
installPaths []string
installPaths android.Paths
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))
installPath := installDir.Join(ctx, header.Base())
installPaths = append(installPaths, installPath)
m.installPaths = append(m.installPaths, installPath.String())
m.installPaths = append(m.installPaths, installPath)
}
if len(m.installPaths) == 0 {

View file

@ -98,7 +98,7 @@ type stubDecorator struct {
properties libraryProperties
versionScriptPath android.ModuleGenPath
installPath string
installPath android.Path
}
// OMG GO
@ -344,7 +344,7 @@ func (stub *stubDecorator) install(ctx ModuleContext, path android.Path) {
installDir := getNdkInstallBase(ctx).Join(ctx, fmt.Sprintf(
"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 {

View file

@ -53,8 +53,6 @@ package cc
// TODO(danalbert): Write `ndk_static_library` rule.
import (
"github.com/google/blueprint"
"android/soong/android"
)
@ -76,32 +74,32 @@ func getNdkSysrootBase(ctx android.PathContext) android.OutputPath {
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")
}
func NdkSingleton() blueprint.Singleton {
func NdkSingleton() android.Singleton {
return &ndkSingleton{}
}
type ndkSingleton struct{}
func (n *ndkSingleton) GenerateBuildActions(ctx blueprint.SingletonContext) {
installPaths := []string{}
licensePaths := []string{}
ctx.VisitAllModules(func(module blueprint.Module) {
func (n *ndkSingleton) GenerateBuildActions(ctx android.SingletonContext) {
var installPaths android.Paths
var licensePaths android.Paths
ctx.VisitAllModules(func(module android.Module) {
if m, ok := module.(android.Module); ok && !m.Enabled() {
return
}
if m, ok := module.(*headerModule); ok {
installPaths = append(installPaths, m.installPaths...)
licensePaths = append(licensePaths, m.licensePath.String())
licensePaths = append(licensePaths, m.licensePath)
}
if m, ok := module.(*preprocessedHeaderModule); ok {
installPaths = append(installPaths, m.installPaths...)
licensePaths = append(licensePaths, m.licensePath.String())
licensePaths = append(licensePaths, m.licensePath)
}
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.MutatedProperties.NdkSysrootPath != "" {
installPaths = append(installPaths, library.MutatedProperties.NdkSysrootPath)
if library.ndkSysrootPath != nil {
installPaths = append(installPaths, library.ndkSysrootPath)
}
}
}
})
combinedLicense := getNdkInstallBase(ctx).Join(ctx, "NOTICE")
ctx.Build(pctx, blueprint.BuildParams{
ctx.Build(pctx, android.BuildParams{
Rule: android.Cat,
Description: "combine licenses",
Outputs: []string{combinedLicense.String()},
Output: combinedLicense,
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
// this. `m ndk` will build the sysroots.
ctx.Build(pctx, blueprint.BuildParams{
ctx.Build(pctx, android.BuildParams{
Rule: android.Touch,
Outputs: []string{getNdkSysrootTimestampFile(ctx).String()},
Output: getNdkSysrootTimestampFile(ctx),
Implicits: depPaths,
Optional: true,
})
}

View file

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

View file

@ -14,6 +14,8 @@
package config
import "android/soong/android"
var (
// These will be filled out by external/error_prone/soong/error_prone.go if it is available
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
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
})
}

View file

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