From 0875c52de753b858b74a9ac285626536bee9cb57 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Tue, 28 Nov 2017 17:34:01 -0800 Subject: [PATCH] Wrap PackageContext and SingletonContext Wrap blueprint.PackageContext so that the *Func methods can provide an android.Config instead of an interface{}. The modified signatures means that every method in ModuleContext and SingletonContext that takes a blueprint.PackageContext now needs to be wrapped to take an android.PackageContext. SingletonContext wasn't previously wrapped at all, but as long as it is, wrap everything like ModuleContext does. This requires updating every Singleton to use the android-specific methods. Test: builds, all Soong tests pass Change-Id: I4f22085ebca7def6c5cde49e8210b59d994ba625 --- Android.bp | 1 + android/androidmk.go | 21 ++-- android/api_levels.go | 19 ++-- android/makevars.go | 13 +-- android/module.go | 215 ++++++++++++++++++++--------------- android/package_ctx.go | 102 +++++++++++------ android/paths.go | 11 ++ android/register.go | 21 +++- android/singleton.go | 162 ++++++++++++++++++++++++++ cc/androidmk.go | 2 +- cc/cmakelists.go | 20 ++-- cc/config/global.go | 16 +-- cc/config/tidy.go | 8 +- cc/config/x86_darwin_host.go | 20 ++-- cc/library.go | 9 +- cc/ndk_headers.go | 8 +- cc/ndk_library.go | 4 +- cc/ndk_sysroot.go | 34 +++--- java/config/config.go | 18 +-- java/config/error_prone.go | 4 +- java/gen.go | 14 +-- 21 files changed, 479 insertions(+), 243 deletions(-) create mode 100644 android/singleton.go 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, }) }