Repository: incubator-mynewt-newt Updated Branches: refs/heads/develop 05d40c264 -> 0694075af
add feature_blacklist and feature_whitelist, to control where features are present. these can only be set in tlps (bsp, app, target). automatically add definitions for FEATURE_* when a feature is enabled. Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/0694075a Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/0694075a Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/0694075a Branch: refs/heads/develop Commit: 0694075af78ff84964b35835680a385255c15fc2 Parents: 05d40c2 Author: Sterling Hughes <[email protected]> Authored: Tue Aug 2 15:16:42 2016 -0700 Committer: Sterling Hughes <[email protected]> Committed: Tue Aug 2 15:16:42 2016 -0700 ---------------------------------------------------------------------- newt/builder/build.go | 77 +++++++++++++++++++++++++++++++++++---- newt/builder/buildpackage.go | 26 +++++++------ newt/builder/buildutil.go | 4 +- newt/pkg/localpackage.go | 16 ++++++++ newt/pkg/package.go | 7 +--- 5 files changed, 105 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0694075a/newt/builder/build.go ---------------------------------------------------------------------- diff --git a/newt/builder/build.go b/newt/builder/build.go index b3dd222..3d54f0e 100644 --- a/newt/builder/build.go +++ b/newt/builder/build.go @@ -23,6 +23,8 @@ import ( "fmt" "os" "path/filepath" + "regexp" + "strings" log "github.com/Sirupsen/logrus" @@ -42,6 +44,9 @@ type Builder struct { compilerPkg *pkg.LocalPackage compilerInfo *toolchain.CompilerInfo + featureWhiteList []map[string]interface{} + featureBlackList []map[string]interface{} + target *target.Target } @@ -65,10 +70,22 @@ func (b *Builder) Init(target *target.Target) error { return nil } -func (b *Builder) Features() map[string]bool { +func (b *Builder) AllFeatures() map[string]bool { return b.features } +func (b *Builder) Features(pkg pkg.Package) map[string]bool { + featureList := map[string]bool{} + + for fname, _ := range b.features { + if b.CheckValidFeature(pkg, fname) { + featureList[fname] = true + } + } + + return featureList +} + func (b *Builder) AddFeature(feature string) { b.features[feature] = true } @@ -319,6 +336,9 @@ func (b *Builder) PrepBuild() error { return nil } + b.featureBlackList = []map[string]interface{}{} + b.featureWhiteList = []map[string]interface{}{} + // Collect the seed packages. bspPkg := b.target.Bsp() if bspPkg == nil { @@ -330,6 +350,9 @@ func (b *Builder) PrepBuild() error { } } + b.featureBlackList = append(b.featureBlackList, bspPkg.FeatureBlackList()) + b.featureWhiteList = append(b.featureWhiteList, bspPkg.FeatureWhiteList()) + b.Bsp = pkg.NewBspPackage(bspPkg) compilerPkg := b.resolveCompiler() if compilerPkg == nil { @@ -355,6 +378,9 @@ func (b *Builder) PrepBuild() error { b.appPkg = appBpkg } + b.featureBlackList = append(b.featureBlackList, appBpkg.FeatureBlackList()) + b.featureWhiteList = append(b.featureWhiteList, appBpkg.FeatureWhiteList()) + bspBpkg := b.Packages[bspPkg] if bspBpkg == nil { bspBpkg = b.AddPackage(bspPkg) @@ -362,6 +388,9 @@ func (b *Builder) PrepBuild() error { targetBpkg := b.AddPackage(b.target.Package()) + b.featureBlackList = append(b.featureBlackList, targetBpkg.FeatureBlackList()) + b.featureWhiteList = append(b.featureWhiteList, targetBpkg.FeatureWhiteList()) + // Populate the full set of packages to be built and resolve the feature // set. if err := b.loadDeps(); err != nil { @@ -400,11 +429,6 @@ func (b *Builder) PrepBuild() error { return err } - // For every feature defined, generate a define and append it to cflags - for fname, _ := range b.Features() { - targetCi.Cflags = append(targetCi.Cflags, - fmt.Sprintf("-DFEATURE_%s", fname)) - } baseCi.AddCompilerInfo(targetCi) // App flags. @@ -440,7 +464,7 @@ func (b *Builder) PrepBuild() error { // Read the BSP configuration. These settings are necessary for the link // step. - if err := b.Bsp.Reload(b.Features()); err != nil { + if err := b.Bsp.Reload(b.Features(b.Bsp)); err != nil { return err } @@ -450,6 +474,45 @@ func (b *Builder) PrepBuild() error { return nil } +func (b *Builder) matchFeature(flist []map[string]interface{}, + pkg pkg.Package, featureName string) bool { + + fullName := "" + if pkg != nil { + fullName = pkg.FullName() + } + + for _, matchList := range flist { + for pkgDesc, featureDesc := range matchList { + re, _ := regexp.Compile(pkgDesc) + if re.MatchString(fullName) { + if strings.Compare(featureDesc.(string), featureName) == 0 { + return true + } + } + } + } + + return false +} + +func (b *Builder) CheckValidFeature(pkg pkg.Package, + feature string) bool { + + // If the feature is not in the blacklist, automatically valid + if match := b.matchFeature(b.featureBlackList, pkg, feature); !match { + return true + } + + // If it is in the blacklist, check if its in the whitelist + // if not, override the feature definition. + if match := b.matchFeature(b.featureWhiteList, pkg, feature); match { + return true + } else { + return false + } +} + func (b *Builder) Build() error { if err := b.target.Validate(true); err != nil { return err http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0694075a/newt/builder/buildpackage.go ---------------------------------------------------------------------- diff --git a/newt/builder/buildpackage.go b/newt/builder/buildpackage.go index 03d11e3..287c769 100644 --- a/newt/builder/buildpackage.go +++ b/newt/builder/buildpackage.go @@ -139,16 +139,20 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) (*toolchain.CompilerInfo, err } ci := toolchain.NewCompilerInfo() - ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(), + ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg), "pkg.cflags") - ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(), + ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg), "pkg.lflags") - ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(), + ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg), "pkg.aflags") + for fname, _ := range b.Features(bpkg) { + ci.Cflags = append(ci.Cflags, fmt.Sprintf("-DFEATURE_%s", fname)) + } + ci.IgnoreFiles = []*regexp.Regexp{} ignPats := newtutil.GetStringSliceFeatures(bpkg.Viper, - b.Features(), "pkg.ign_files") + b.Features(bpkg), "pkg.ign_files") for _, str := range ignPats { re, err := regexp.Compile(str) if err != nil { @@ -160,7 +164,7 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) (*toolchain.CompilerInfo, err ci.IgnoreDirs = []*regexp.Regexp{} ignPats = newtutil.GetStringSliceFeatures(bpkg.Viper, - b.Features(), "pkg.ign_dirs") + b.Features(bpkg), "pkg.ign_dirs") for _, str := range ignPats { re, err := regexp.Compile(str) if err != nil { @@ -171,7 +175,7 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) (*toolchain.CompilerInfo, err } bpkg.SourceDirectories = newtutil.GetStringSliceFeatures(bpkg.Viper, - b.Features(), "pkg.src_dirs") + b.Features(bpkg), "pkg.src_dirs") includePaths, err := bpkg.recursiveIncludePaths(b) if err != nil { @@ -184,7 +188,7 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) (*toolchain.CompilerInfo, err } func (bpkg *BuildPackage) loadFeatures(b *Builder) (map[string]bool, bool) { - features := b.Features() + features := b.AllFeatures() foundNewFeature := false @@ -200,7 +204,7 @@ func (bpkg *BuildPackage) loadFeatures(b *Builder) (map[string]bool, bool) { } } - return b.Features(), foundNewFeature + return b.Features(bpkg), foundNewFeature } // Searches for a package which can satisfy bpkg's API requirement. If such a @@ -266,7 +270,7 @@ func (bpkg *BuildPackage) loadDeps(b *Builder, // Determine if this package supports any APIs that we haven't seen // yet. If so, another full iteration is required. - apis := newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(), + apis := newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg), "pkg.apis") for _, api := range apis { newApi := b.AddApi(api, bpkg) @@ -289,7 +293,7 @@ func (bpkg *BuildPackage) satisfyApis(b *Builder) bool { // Determine if any of the package's API requirements can now be satisfied. // If so, another full iteration is required. - reqApis := newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(), + reqApis := newtutil.GetStringSliceFeatures(bpkg.Viper, b.Features(bpkg), "pkg.req_apis") for _, reqApi := range reqApis { reqStatus, ok := bpkg.reqApiMap[reqApi] @@ -360,7 +364,7 @@ func (bpkg *BuildPackage) privateIncludeDirs(b *Builder) []string { incls = append(incls, srcDir) incls = append(incls, srcDir+"/arch/"+b.Bsp.Arch) - if b.Features()["TEST"] { + if b.Features(bpkg)["TEST"] { testSrcDir := srcDir + "/test" incls = append(incls, testSrcDir) incls = append(incls, testSrcDir+"/arch/"+b.Bsp.Arch) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0694075a/newt/builder/buildutil.go ---------------------------------------------------------------------- diff --git a/newt/builder/buildutil.go b/newt/builder/buildutil.go index cd7ec85..c90251f 100644 --- a/newt/builder/buildutil.go +++ b/newt/builder/buildutil.go @@ -75,8 +75,8 @@ func (b *Builder) TestExePath(pkgName string) string { func (b *Builder) FeatureString() string { var buffer bytes.Buffer - features := make([]string, 0, len(b.Features())) - for f, _ := range b.Features() { + features := make([]string, 0, len(b.Features(nil))) + for f, _ := range b.Features(nil) { features = append(features, f) } sort.Strings(features) http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0694075a/newt/pkg/localpackage.go ---------------------------------------------------------------------- diff --git a/newt/pkg/localpackage.go b/newt/pkg/localpackage.go index b776f9d..78207b5 100644 --- a/newt/pkg/localpackage.go +++ b/newt/pkg/localpackage.go @@ -65,6 +65,11 @@ type LocalPackage struct { // APIs that this package requires reqApis []string + // This is only used for top-level packages, but make no distinction + // and always read it in. + featureBlackList map[string]interface{} + featureWhiteList map[string]interface{} + // Pointer to pkg.yml configuration structure Viper *viper.Viper @@ -309,6 +314,9 @@ func (pkg *LocalPackage) Load() error { } } + pkg.featureBlackList = v.GetStringMap("pkg.feature_blacklist") + pkg.featureWhiteList = v.GetStringMap("pkg.feature_whitelist") + // Read the package description from the file pkg.desc, err = pkg.readDesc(v) if err != nil { @@ -320,6 +328,14 @@ func (pkg *LocalPackage) Load() error { return nil } +func (pkg *LocalPackage) FeatureBlackList() map[string]interface{} { + return pkg.featureBlackList +} + +func (pkg *LocalPackage) FeatureWhiteList() map[string]interface{} { + return pkg.featureWhiteList +} + func (pkg *LocalPackage) Clone(newRepo *repo.Repo, newName string) *LocalPackage { http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0694075a/newt/pkg/package.go ---------------------------------------------------------------------- diff --git a/newt/pkg/package.go b/newt/pkg/package.go index 7a37632..4fa988c 100644 --- a/newt/pkg/package.go +++ b/newt/pkg/package.go @@ -20,10 +20,7 @@ package pkg -import ( - "mynewt.apache.org/newt/newt/interfaces" - "mynewt.apache.org/newt/newt/repo" -) +import "mynewt.apache.org/newt/newt/interfaces" const PACKAGE_FILE_NAME = "pkg.yml" @@ -60,7 +57,7 @@ var PackageTypeNames = map[interfaces.PackageType]string{ // case. type Package interface { // The repository this package belongs to - Repo() *repo.Repo + Repo() interfaces.RepoInterface // The name of this package Name() string // The full name of this package, including repo
