diff --git a/Android.bp b/Android.bp index d32c9572a..886d63d45 100644 --- a/Android.bp +++ b/Android.bp @@ -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", diff --git a/android/androidmk.go b/android/androidmk.go index 19d5ea696..aff43fab2 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -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 diff --git a/android/api_levels.go b/android/api_levels.go index 2c4ae1a07..bdfbc43c8 100644 --- a/android/api_levels.go +++ b/android/api_levels.go @@ -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) } diff --git a/android/makevars.go b/android/makevars.go index 024e01527..d323613e1 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -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() { diff --git a/android/module.go b/android/module.go index 66859fa56..0eb48203e 100644 --- a/android/module.go +++ b/android/module.go @@ -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)- 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, }) } } diff --git a/android/package_ctx.go b/android/package_ctx.go index d32e82b29..1626f766c 100644 --- a/android/package_ctx.go +++ b/android/package_ctx.go @@ -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 diff --git a/android/paths.go b/android/paths.go index 4adaa2d83..b2ee62756 100644 --- a/android/paths.go +++ b/android/paths.go @@ -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 } diff --git a/android/register.go b/android/register.go index 81a266d77..78ae481c1 100644 --- a/android/register.go +++ b/android/register.go @@ -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 { diff --git a/android/singleton.go b/android/singleton.go new file mode 100644 index 000000000..f2f575ff3 --- /dev/null +++ b/android/singleton.go @@ -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) +} diff --git a/cc/androidmk.go b/cc/androidmk.go index 065d0aa9b..44e977fa3 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -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()) diff --git a/cc/cmakelists.go b/cc/cmakelists.go index 13a2e8e19..9b3218283 100644 --- a/cc/cmakelists.go +++ b/cc/cmakelists.go @@ -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 } diff --git a/cc/config/global.go b/cc/config/global.go index 4322436b5..8881b4b31 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -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 diff --git a/cc/config/tidy.go b/cc/config/tidy.go index a2fa5a2e8..76a5f9ee9 100644 --- a/cc/config/tidy.go +++ b/cc/config/tidy.go @@ -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{ diff --git a/cc/config/x86_darwin_host.go b/cc/config/x86_darwin_host.go index 8d805c993..dbaa6fa6a 100644 --- a/cc/config/x86_darwin_host.go +++ b/cc/config/x86_darwin_host.go @@ -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 }) diff --git a/cc/library.go b/cc/library.go index 192496ad9..cf106173d 100644 --- a/cc/library.go +++ b/cc/library.go @@ -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 } } diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go index bfbf0f548..d7c2a0619 100644 --- a/cc/ndk_headers.go +++ b/cc/ndk_headers.go @@ -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 { diff --git a/cc/ndk_library.go b/cc/ndk_library.go index 96a90fbe2..e69128c41 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -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 { diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go index e21396588..4324458ef 100644 --- a/cc/ndk_sysroot.go +++ b/cc/ndk_sysroot.go @@ -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, }) } diff --git a/java/config/config.go b/java/config/config.go index 49481be30..466563f50 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -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 diff --git a/java/config/error_prone.go b/java/config/error_prone.go index 31cbf2c9e..862217f77 100644 --- a/java/config/error_prone.go +++ b/java/config/error_prone.go @@ -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 }) } diff --git a/java/gen.go b/java/gen.go index b5973ec77..7a0dcac5a 100644 --- a/java/gen.go +++ b/java/gen.go @@ -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, }) }