diff --git a/android/androidmk.go b/android/androidmk.go index aff43fab2..d88ba8fa5 100644 --- a/android/androidmk.go +++ b/android/androidmk.go @@ -60,9 +60,7 @@ func AndroidMkSingleton() Singleton { type androidMkSingleton struct{} func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) { - config := ctx.Config().(Config) - - if !config.EmbeddedInMake() { + if !ctx.Config().EmbeddedInMake() { return } @@ -74,7 +72,7 @@ func (c *androidMkSingleton) GenerateBuildActions(ctx SingletonContext) { sort.Sort(AndroidModulesByName{androidMkModulesList, ctx}) - transMk := PathForOutput(ctx, "Android"+String(config.ProductVariables.Make_suffix)+".mk") + transMk := PathForOutput(ctx, "Android"+String(ctx.Config().ProductVariables.Make_suffix)+".mk") if ctx.Failed() { return } @@ -184,8 +182,7 @@ func translateAndroidMkModule(ctx SingletonContext, w io.Writer, mod blueprint.M } - config := ctx.Config().(Config) - if amod.Arch().ArchType != config.Targets[amod.Os().Class][0].Arch.ArchType { + if amod.Arch().ArchType != ctx.Config().Targets[amod.Os().Class][0].Arch.ArchType { prefix = "2ND_" + prefix } } diff --git a/android/api_levels.go b/android/api_levels.go index bdfbc43c8..a51911787 100644 --- a/android/api_levels.go +++ b/android/api_levels.go @@ -66,7 +66,7 @@ func (a *apiLevelsSingleton) GenerateBuildActions(ctx SingletonContext) { "N-MR1": 25, "O": 26, } - for i, codename := range ctx.Config().(Config).PlatformVersionCombinedCodenames() { + for i, codename := range ctx.Config().PlatformVersionCombinedCodenames() { apiLevelsMap[codename] = baseApiLevel + i } diff --git a/android/env.go b/android/env.go index c03431b20..469dfffed 100644 --- a/android/env.go +++ b/android/env.go @@ -48,7 +48,7 @@ func EnvSingleton() Singleton { type envSingleton struct{} func (c *envSingleton) GenerateBuildActions(ctx SingletonContext) { - envDeps := ctx.Config().(Config).EnvDeps() + envDeps := ctx.Config().EnvDeps() envFile := PathForOutput(ctx, ".soong.environment") if ctx.Failed() { diff --git a/android/makevars.go b/android/makevars.go index d323613e1..00a20f5aa 100644 --- a/android/makevars.go +++ b/android/makevars.go @@ -105,13 +105,11 @@ type makeVarsVariable struct { } func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { - config := ctx.Config().(Config) - - if !config.EmbeddedInMake() { + if !ctx.Config().EmbeddedInMake() { return } - outFile := PathForOutput(ctx, "make_vars"+proptools.String(config.ProductVariables.Make_suffix)+".mk").String() + outFile := PathForOutput(ctx, "make_vars"+proptools.String(ctx.Config().ProductVariables.Make_suffix)+".mk").String() if ctx.Failed() { return @@ -120,7 +118,7 @@ func (s *makeVarsSingleton) GenerateBuildActions(ctx SingletonContext) { vars := []makeVarsVariable{} for _, provider := range makeVarsProviders { mctx := &makeVarsContext{ - config: config, + config: ctx.Config(), ctx: ctx, pctx: provider.pctx, } diff --git a/android/module.go b/android/module.go index 0eb48203e..476929a59 100644 --- a/android/module.go +++ b/android/module.go @@ -19,6 +19,7 @@ import ( "path/filepath" "sort" "strings" + "text/scanner" "github.com/google/blueprint" "github.com/google/blueprint/pathtools" @@ -70,13 +71,36 @@ type androidBaseContext interface { } type BaseContext interface { - blueprint.BaseModuleContext + BaseModuleContext androidBaseContext } +// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns +// a Config instead of an interface{}. +type BaseModuleContext interface { + ModuleName() string + ModuleDir() string + Config() Config + + ContainsProperty(name string) bool + Errorf(pos scanner.Position, fmt string, args ...interface{}) + ModuleErrorf(fmt string, args ...interface{}) + PropertyErrorf(property, fmt string, args ...interface{}) + Failed() bool + + // 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 + AddNinjaFileDeps(deps ...string) +} + type ModuleContext interface { androidBaseContext - blueprint.BaseModuleContext + BaseModuleContext // Deprecated: use ModuleContext.Build instead. ModuleBuild(pctx PackageContext, params ModuleBuildParams) @@ -482,7 +506,7 @@ func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) { Rule: blueprint.Phony, Output: name, Implicits: allInstalledFiles, - Default: !ctx.Config().(Config).EmbeddedInMake(), + Default: !ctx.Config().EmbeddedInMake(), }) deps = append(deps, name) a.installTarget = name @@ -501,7 +525,7 @@ func (a *ModuleBase) generateModuleTarget(ctx ModuleContext) { if len(deps) > 0 { suffix := "" - if ctx.Config().(Config).EmbeddedInMake() { + if ctx.Config().EmbeddedInMake() { suffix = "-soong" } @@ -605,6 +629,10 @@ func (a *androidModuleContext) ninjaError(desc string, outputs []string, err err return } +func (a *androidModuleContext) Config() Config { + return a.ModuleContext.Config().(Config) +} + func (a *androidModuleContext) ModuleBuild(pctx PackageContext, params ModuleBuildParams) { a.Build(pctx, BuildParams(params)) } @@ -1094,7 +1122,7 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { }) suffix := "" - if ctx.Config().(Config).EmbeddedInMake() { + if ctx.Config().EmbeddedInMake() { suffix = "-soong" } @@ -1106,7 +1134,7 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { }) // Make will generate the MODULES-IN-* targets - if ctx.Config().(Config).EmbeddedInMake() { + if ctx.Config().EmbeddedInMake() { return } @@ -1151,7 +1179,7 @@ func (c *buildTargetSingleton) GenerateBuildActions(ctx SingletonContext) { Implicits: modulesInDir[dir], // HACK: checkbuild should be an optional build, but force it // enabled for now in standalone builds - Default: !ctx.Config().(Config).EmbeddedInMake(), + Default: !ctx.Config().EmbeddedInMake(), }) } diff --git a/android/mutator.go b/android/mutator.go index cc3f1f3b5..db3eaa376 100644 --- a/android/mutator.go +++ b/android/mutator.go @@ -108,7 +108,7 @@ func PostDepsMutators(f RegisterMutatorFunc) { type AndroidTopDownMutator func(TopDownMutatorContext) type TopDownMutatorContext interface { - blueprint.BaseModuleContext + BaseModuleContext androidBaseContext OtherModuleExists(name string) bool @@ -139,8 +139,22 @@ type androidTopDownMutatorContext struct { type AndroidBottomUpMutator func(BottomUpMutatorContext) type BottomUpMutatorContext interface { - blueprint.BottomUpMutatorContext + BaseModuleContext androidBaseContext + + OtherModuleExists(name string) bool + Rename(name string) + Module() blueprint.Module + + AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) + AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) + CreateVariations(...string) []blueprint.Module + CreateLocalVariations(...string) []blueprint.Module + SetDependencyVariation(string) + AddVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) + AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) + AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) + ReplaceDependencies(string) } type androidBottomUpMutatorContext struct { @@ -193,6 +207,14 @@ func depsMutator(ctx BottomUpMutatorContext) { } } +func (a *androidTopDownMutatorContext) Config() Config { + return a.config +} + +func (a *androidBottomUpMutatorContext) Config() Config { + return a.config +} + func (a *androidTopDownMutatorContext) Module() Module { module, _ := a.TopDownMutatorContext.Module().(Module) return module diff --git a/android/package_ctx.go b/android/package_ctx.go index 1626f766c..b40e0a9c2 100644 --- a/android/package_ctx.go +++ b/android/package_ctx.go @@ -47,7 +47,7 @@ type configErrorWrapper struct { var _ PathContext = &configErrorWrapper{} var _ errorfContext = &configErrorWrapper{} -func (e *configErrorWrapper) Config() interface{} { +func (e *configErrorWrapper) Config() Config { return e.config } func (e *configErrorWrapper) Errorf(format string, args ...interface{}) { diff --git a/android/paths.go b/android/paths.go index 71049eeb1..cdc039942 100644 --- a/android/paths.go +++ b/android/paths.go @@ -29,7 +29,7 @@ import ( // Path methods. type PathContext interface { Fs() pathtools.FileSystem - Config() interface{} + Config() Config AddNinjaFileDeps(deps ...string) } @@ -37,8 +37,8 @@ type PathGlobContext interface { GlobWithDeps(globPattern string, excludes []string) ([]string, error) } -var _ PathContext = blueprint.SingletonContext(nil) -var _ PathContext = blueprint.ModuleContext(nil) +var _ PathContext = SingletonContext(nil) +var _ PathContext = ModuleContext(nil) type ModuleInstallPathContext interface { PathContext @@ -67,15 +67,6 @@ type moduleErrorf interface { var _ moduleErrorf = blueprint.ModuleContext(nil) -// pathConfig returns the android Config interface associated to the context. -// Panics if the context isn't affiliated with an android build. -func pathConfig(ctx PathContext) Config { - if ret, ok := ctx.Config().(Config); ok { - return ret - } - panic("Paths may only be used on Soong builds") -} - // reportPathError will register an error with the attached context. It // attempts ctx.ModuleErrorf for a better error message first, then falls // back to ctx.Errorf. @@ -197,7 +188,7 @@ type Paths []Path // PathsForSource returns Paths rooted from SrcDir func PathsForSource(ctx PathContext, paths []string) Paths { - if pathConfig(ctx).AllowMissingDependencies() { + if ctx.Config().AllowMissingDependencies() { if modCtx, ok := ctx.(ModuleContext); ok { ret := make(Paths, 0, len(paths)) intermediates := pathForModule(modCtx).withRel("missing") @@ -476,14 +467,14 @@ var _ Path = SourcePath{} // code that is embedding ninja variables in paths func safePathForSource(ctx PathContext, path string) SourcePath { p := validateSafePath(ctx, path) - ret := SourcePath{basePath{p, pathConfig(ctx), ""}} + ret := SourcePath{basePath{p, ctx.Config(), ""}} abs, err := filepath.Abs(ret.String()) if err != nil { reportPathError(ctx, "%s", err.Error()) return ret } - buildroot, err := filepath.Abs(pathConfig(ctx).buildDir) + buildroot, err := filepath.Abs(ctx.Config().buildDir) if err != nil { reportPathError(ctx, "%s", err.Error()) return ret @@ -501,14 +492,14 @@ func safePathForSource(ctx PathContext, path string) SourcePath { // On error, it will return a usable, but invalid SourcePath, and report a ModuleError. func PathForSource(ctx PathContext, pathComponents ...string) SourcePath { p := validatePath(ctx, pathComponents...) - ret := SourcePath{basePath{p, pathConfig(ctx), ""}} + ret := SourcePath{basePath{p, ctx.Config(), ""}} abs, err := filepath.Abs(ret.String()) if err != nil { reportPathError(ctx, "%s", err.Error()) return ret } - buildroot, err := filepath.Abs(pathConfig(ctx).buildDir) + buildroot, err := filepath.Abs(ctx.Config().buildDir) if err != nil { reportPathError(ctx, "%s", err.Error()) return ret @@ -536,14 +527,14 @@ func ExistentPathForSource(ctx PathContext, intermediates string, pathComponents } p := validatePath(ctx, pathComponents...) - path := SourcePath{basePath{p, pathConfig(ctx), ""}} + path := SourcePath{basePath{p, ctx.Config(), ""}} abs, err := filepath.Abs(path.String()) if err != nil { reportPathError(ctx, "%s", err.Error()) return OptionalPath{} } - buildroot, err := filepath.Abs(pathConfig(ctx).buildDir) + buildroot, err := filepath.Abs(ctx.Config().buildDir) if err != nil { reportPathError(ctx, "%s", err.Error()) return OptionalPath{} @@ -652,7 +643,7 @@ var _ Path = OutputPath{} // On error, it will return a usable, but invalid OutputPath, and report a ModuleError. func PathForOutput(ctx PathContext, pathComponents ...string) OutputPath { path := validatePath(ctx, pathComponents...) - return OutputPath{basePath{path, pathConfig(ctx), ""}} + return OutputPath{basePath{path, ctx.Config(), ""}} } func (p OutputPath) writablePath() {} @@ -905,7 +896,7 @@ 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), ""}} + return OutputPath{basePath{phony, ctx.Config(), ""}} } type testPath struct { diff --git a/android/paths_test.go b/android/paths_test.go index 82ae4dcf7..1e4ba538c 100644 --- a/android/paths_test.go +++ b/android/paths_test.go @@ -194,7 +194,7 @@ func (moduleInstallPathContextImpl) Fs() pathtools.FileSystem { return pathtools.MockFs(nil) } -func (m moduleInstallPathContextImpl) Config() interface{} { +func (m moduleInstallPathContextImpl) Config() Config { return m.androidBaseContextImpl.config } diff --git a/android/singleton.go b/android/singleton.go index f2f575ff3..87910fdab 100644 --- a/android/singleton.go +++ b/android/singleton.go @@ -21,8 +21,7 @@ import ( // SingletonContext type SingletonContext interface { - // TODO(ccross): make this return an android.Config - Config() interface{} + Config() Config ModuleName(module blueprint.Module) string ModuleDir(module blueprint.Module) string @@ -87,6 +86,10 @@ type singletonContextAdaptor struct { blueprint.SingletonContext } +func (s singletonContextAdaptor) Config() Config { + return s.SingletonContext.Config().(Config) +} + func (s singletonContextAdaptor) Variable(pctx PackageContext, name, value string) { s.SingletonContext.Variable(pctx.PackageContext, name, value) } diff --git a/android/variable.go b/android/variable.go index 13b5abf26..c8a672e31 100644 --- a/android/variable.go +++ b/android/variable.go @@ -258,7 +258,7 @@ func variableMutator(mctx BottomUpMutatorContext) { property := "product_variables." + proptools.PropertyNameForField(name) // Check that the variable was set for the product - val := reflect.ValueOf(mctx.Config().(Config).ProductVariables).FieldByName(name) + val := reflect.ValueOf(mctx.Config().ProductVariables).FieldByName(name) if !val.IsValid() || val.Kind() != reflect.Ptr || val.IsNil() { continue } diff --git a/cc/cmakelists.go b/cc/cmakelists.go index 9b3218283..c25578e2c 100644 --- a/cc/cmakelists.go +++ b/cc/cmakelists.go @@ -82,7 +82,7 @@ func (c *cmakelistsGeneratorSingleton) GenerateBuildActions(ctx android.Singleto 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) + return ctx.Config().Getenv(name) } func exists(path string) bool { diff --git a/java/app.go b/java/app.go index fd1fe33ff..1560be676 100644 --- a/java/app.go +++ b/java/app.go @@ -338,7 +338,7 @@ type overlaySingleton struct{} func (overlaySingleton) GenerateBuildActions(ctx android.SingletonContext) { var overlayData []overlayGlobResult - for _, overlay := range ctx.Config().(android.Config).ResourceOverlays() { + for _, overlay := range ctx.Config().ResourceOverlays() { var result overlayGlobResult result.dir = overlay files, err := ctx.GlobWithDeps(filepath.Join(overlay, "**/*"), aaptIgnoreFilenames) @@ -359,7 +359,7 @@ func (overlaySingleton) GenerateBuildActions(ctx android.SingletonContext) { overlayData = append(overlayData, result) } - ctx.Config().(android.Config).Once(overlayDataKey, func() interface{} { + ctx.Config().Once(overlayDataKey, func() interface{} { return overlayData }) }