Repository: incubator-mynewt-newt
Updated Branches:
  refs/heads/develop 10b0ce6bd -> 327dfae4c


newt syscfg / sysinit.


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/0ae71ef1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/0ae71ef1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/0ae71ef1

Branch: refs/heads/develop
Commit: 0ae71ef1a900bba44936069d053f90d8797c8650
Parents: 0baf3a3
Author: Christopher Collins <ccoll...@apache.org>
Authored: Mon Sep 12 20:35:34 2016 -0700
Committer: Christopher Collins <ccoll...@apache.org>
Committed: Mon Sep 12 20:35:34 2016 -0700

----------------------------------------------------------------------
 newt/Godeps/Godeps.json                         |  14 +-
 newt/builder/build.go                           | 270 ++++---
 newt/builder/buildpackage.go                    | 102 +--
 newt/builder/buildutil.go                       |  36 +-
 newt/builder/load.go                            |   3 +-
 newt/builder/targetbuild.go                     |  12 +-
 newt/cli/build_cmds.go                          | 127 ++-
 newt/cli/complete_cmd.go                        |  32 +-
 newt/cli/target_cmds.go                         | 109 ++-
 newt/newt.go                                    |   8 +-
 newt/newtutil/newtutil.go                       |  72 +-
 newt/pkg/localpackage.go                        |  62 +-
 newt/pkg/package.go                             |   5 +-
 newt/pkg/packageutil.go                         |  32 +
 newt/project/project.go                         |   2 -
 newt/syscfg/syscfg.go                           | 801 +++++++++++++++++++
 newt/sysinit/sysinit.go                         | 154 ++++
 newt/toolchain/compiler.go                      |   6 +-
 newt/toolchain/deps.go                          |   8 +
 newt/vendor/mynewt.apache.org/newt/DISCLAIMER   |   8 -
 newt/vendor/mynewt.apache.org/newt/LICENSE      | 244 ------
 newt/vendor/mynewt.apache.org/newt/NOTICE       |   8 -
 newt/vendor/mynewt.apache.org/newt/util/util.go |  21 +
 23 files changed, 1556 insertions(+), 580 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/Godeps/Godeps.json
----------------------------------------------------------------------
diff --git a/newt/Godeps/Godeps.json b/newt/Godeps/Godeps.json
index cf4c345..4dcc675 100644
--- a/newt/Godeps/Godeps.json
+++ b/newt/Godeps/Godeps.json
@@ -1,7 +1,7 @@
 {
        "ImportPath": "mynewt.apache.org/newt/newt",
        "GoVersion": "go1.6",
-       "GodepVersion": "v74",
+       "GodepVersion": "v58",
        "Deps": [
                {
                        "ImportPath": "github.com/Sirupsen/logrus",
@@ -52,18 +52,18 @@
                },
                {
                        "ImportPath": "mynewt.apache.org/newt/util",
-                       "Comment": "mynewt_0_9_0_rc3_tag-91-g904f79b",
-                       "Rev": "904f79b15feeefe76a9e4ecc139c56fd54aa4412"
+                       "Comment": "mynewt_0_9_0_tag-139-g8dddcf6",
+                       "Rev": "8dddcf664861e0904e4c89b2bb4c2d498d4cb3a2"
                },
                {
                        "ImportPath": "mynewt.apache.org/newt/viper",
-                       "Comment": "mynewt_0_9_0_rc3_tag-91-g904f79b",
-                       "Rev": "904f79b15feeefe76a9e4ecc139c56fd54aa4412"
+                       "Comment": "mynewt_0_9_0_tag-139-g8dddcf6",
+                       "Rev": "8dddcf664861e0904e4c89b2bb4c2d498d4cb3a2"
                },
                {
                        "ImportPath": "mynewt.apache.org/newt/yaml",
-                       "Comment": "mynewt_0_9_0_rc3_tag-91-g904f79b",
-                       "Rev": "904f79b15feeefe76a9e4ecc139c56fd54aa4412"
+                       "Comment": "mynewt_0_9_0_tag-139-g8dddcf6",
+                       "Rev": "8dddcf664861e0904e4c89b2bb4c2d498d4cb3a2"
                }
        ]
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/builder/build.go
----------------------------------------------------------------------
diff --git a/newt/builder/build.go b/newt/builder/build.go
index b8cbd39..17b64d1 100644
--- a/newt/builder/build.go
+++ b/newt/builder/build.go
@@ -29,7 +29,10 @@ import (
        log "github.com/Sirupsen/logrus"
 
        "mynewt.apache.org/newt/newt/pkg"
+       "mynewt.apache.org/newt/newt/project"
        "mynewt.apache.org/newt/newt/symbol"
+       "mynewt.apache.org/newt/newt/syscfg"
+       "mynewt.apache.org/newt/newt/sysinit"
        "mynewt.apache.org/newt/newt/target"
        "mynewt.apache.org/newt/newt/toolchain"
        "mynewt.apache.org/newt/util"
@@ -37,58 +40,31 @@ import (
 
 type Builder struct {
        Packages         map[*pkg.LocalPackage]*BuildPackage
-       features         map[string]bool
        apis             map[string]*BuildPackage
        appPkg           *BuildPackage
        BspPkg           *pkg.LocalPackage
        compilerInfo     *toolchain.CompilerInfo
-       featureWhiteList []map[string]interface{}
-       featureBlackList []map[string]interface{}
        target           *TargetBuilder
        linkerScript     string
        buildName        string
        LinkElf          string
-}
-
-func NewBuilder(t *TargetBuilder, buildName string) (*Builder, error) {
-       b := &Builder{}
-
-       b.buildName = buildName
-       /* TODO */
-       b.Init(t)
-
-       return b, nil
-}
+       injectedSettings map[string]string
 
-func (b *Builder) Init(t *TargetBuilder) error {
-
-       b.target = t
-       b.Packages = map[*pkg.LocalPackage]*BuildPackage{}
-       b.features = map[string]bool{}
-       b.apis = map[string]*BuildPackage{}
-       b.LinkElf = ""
-
-       return nil
+       Cfg syscfg.Cfg
 }
 
-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
-               }
+func NewBuilder(t *TargetBuilder, buildName string) (*Builder, error) {
+       b := &Builder{
+               Packages:         map[*pkg.LocalPackage]*BuildPackage{},
+               buildName:        buildName,
+               apis:             map[string]*BuildPackage{},
+               LinkElf:          "",
+               target:           t,
+               injectedSettings: map[string]string{},
+               Cfg:              syscfg.Cfg{},
        }
 
-       return featureList
-}
-
-func (b *Builder) AddFeature(feature string) {
-       b.features[feature] = true
+       return b, nil
 }
 
 func (b *Builder) AddPackage(npkg *pkg.LocalPackage) *BuildPackage {
@@ -122,29 +98,56 @@ func (b *Builder) AddApi(apiString string, bpkg 
*BuildPackage) bool {
        }
 }
 
-func (b *Builder) loadDeps() error {
-       // Circularly resolve dependencies, identities, APIs, and required APIs
-       // until no new ones exist.
+func (b *Builder) ApiNames() []string {
+       apiNames := make([]string, len(b.apis), len(b.apis))
+
+       i := 0
+       for api, _ := range b.apis {
+               apiNames[i] = api
+               i += 1
+       }
+
+       return apiNames
+}
+
+// @return                      changed,err
+func (b *Builder) reloadCfg() (bool, error) {
+       apis := make([]string, len(b.apis))
+       i := 0
+       for api, _ := range b.apis {
+               apis[i] = api
+               i++
+       }
+
+       cfg, err := syscfg.Read(b.sortedLocalPackages(), apis, 
b.injectedSettings)
+       if err != nil {
+               return false, err
+       }
+
+       changed := false
+       for k, v := range cfg {
+               oldval, ok := b.Cfg[k]
+               if !ok || len(oldval.History) != len(v.History) {
+                       b.Cfg = cfg
+                       changed = true
+               }
+       }
+
+       return changed, nil
+}
+
+func (b *Builder) loadDepsOnce() (bool, error) {
+       // Circularly resolve dependencies, APIs, and required APIs until no new
+       // ones exist.
+       newDeps := false
        for {
                reprocess := false
                for _, bpkg := range b.Packages {
-                       newDeps, newFeatures, err := bpkg.Resolve(b)
+                       newDeps, err := bpkg.Resolve(b, b.Cfg)
                        if err != nil {
-                               return err
+                               return false, err
                        }
 
-                       if newFeatures {
-                               // A new supported feature was discovered.  It 
is impossible
-                               // to determine what new dependency and API 
requirements are
-                               // generated as a result.  All packages need to 
be
-                               // reprocessed.
-                               for _, bpkg := range b.Packages {
-                                       bpkg.depsResolved = false
-                                       bpkg.apisSatisfied = false
-                               }
-                               reprocess = true
-                               break
-                       }
                        if newDeps {
                                // The new dependencies need to be processed.  
Iterate again
                                // after this iteration completes.
@@ -157,6 +160,43 @@ func (b *Builder) loadDeps() error {
                }
        }
 
+       return newDeps, nil
+}
+
+func (b *Builder) loadDeps() error {
+       if _, err := b.loadDepsOnce(); err != nil {
+               return err
+       }
+
+       for {
+               cfgChanged, err := b.reloadCfg()
+               if err != nil {
+                       return err
+               }
+               if cfgChanged {
+                       // A new supported feature was discovered.  It is 
impossible
+                       // to determine what new dependency and API 
requirements are
+                       // generated as a result.  All packages need to be
+                       // reprocessed.
+                       for _, bpkg := range b.Packages {
+                               bpkg.depsResolved = false
+                               bpkg.apisSatisfied = false
+                       }
+               }
+
+               newDeps, err := b.loadDepsOnce()
+               if err != nil {
+                       return err
+               }
+
+               if !newDeps && !cfgChanged {
+                       break
+               }
+       }
+
+       // Log the final syscfg.
+       syscfg.Log(b.Cfg)
+
        return nil
 }
 
@@ -233,12 +273,6 @@ func (b *Builder) newCompiler(bpkg *BuildPackage,
                c.AddInfo(ci)
        }
 
-       // Specify all the source yml files as dependencies.  If a yml file has
-       // changed, a full rebuild is required.
-       for _, bp := range b.Packages {
-               c.AddDeps(bp.CfgFilenames()...)
-       }
-
        return c, nil
 }
 
@@ -271,25 +305,10 @@ func (b *Builder) buildPackage(bpkg *BuildPackage) error {
                srcDirs = append(srcDirs, srcDir)
        }
 
-       // Build the package source in two phases:
-       // 1. Non-test code.
-       // 2. Test code (if the "test" feature is enabled).
-       //
-       // This is done in two passes because the structure of
-       // architecture-specific directories is different for normal code and 
test
-       // code, and not easy to generalize into a single operation:
-       //     * src/arch/<target-arch>
-       //     * src/test/arch/<target-arch>
        for _, dir := range srcDirs {
-               if err = buildDir(dir, c, b.target.Bsp.Arch, []string{"test"}); 
err != nil {
+               if err = buildDir(dir, c, b.target.Bsp.Arch, nil); err != nil {
                        return err
                }
-               if b.features["TEST"] {
-                       testSrcDir := dir + "/test"
-                       if err = buildDir(testSrcDir, c, b.target.Bsp.Arch, 
nil); err != nil {
-                               return err
-                       }
-               }
        }
 
        // Create a static library ("archive").
@@ -347,7 +366,7 @@ func (b *Builder) link(elfName string, linkerScript string,
        }
 
        if linkerScript != "" {
-               c.LinkerScript = b.target.Bsp.BasePath() + linkerScript
+               c.LinkerScript = b.target.Bsp.BasePath() + "/" + linkerScript
        }
        err = c.CompileElf(elfName, pkgNames, keepSymbols, b.LinkElf)
        if err != nil {
@@ -363,9 +382,6 @@ func (b *Builder) link(elfName string, linkerScript string,
 func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
        bspPkg *pkg.LocalPackage, targetPkg *pkg.LocalPackage) error {
 
-       b.featureBlackList = []map[string]interface{}{}
-       b.featureWhiteList = []map[string]interface{}{}
-
        // Seed the builder with the app (if present), bsp, and target packages.
 
        b.BspPkg = bspPkg
@@ -377,9 +393,6 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
                        appBpkg = b.AddPackage(appPkg)
                }
                b.appPkg = appBpkg
-
-               b.featureBlackList = append(b.featureBlackList, 
appBpkg.FeatureBlackList())
-               b.featureWhiteList = append(b.featureWhiteList, 
appBpkg.FeatureWhiteList())
        }
 
        bspBpkg := b.Packages[bspPkg]
@@ -388,14 +401,8 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
                bspBpkg = b.AddPackage(bspPkg)
        }
 
-       b.featureBlackList = append(b.featureBlackList, 
bspPkg.FeatureBlackList())
-       b.featureWhiteList = append(b.featureWhiteList, 
bspPkg.FeatureWhiteList())
-
        targetBpkg := b.AddPackage(targetPkg)
 
-       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 {
@@ -428,12 +435,12 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
        baseCi := toolchain.NewCompilerInfo()
 
        // Target flags.
-       log.Debugf("Generating build flags for target %s", 
b.target.target.FullName())
+       log.Debugf("Generating build flags for target %s",
+               b.target.target.FullName())
        targetCi, err := targetBpkg.CompilerInfo(b)
        if err != nil {
                return err
        }
-
        baseCi.AddCompilerInfo(targetCi)
 
        // App flags.
@@ -443,6 +450,7 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
                if err != nil {
                        return err
                }
+
                baseCi.AddCompilerInfo(appCi)
        }
 
@@ -468,6 +476,18 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
        // package being built are calculated.
        b.compilerInfo = baseCi
 
+       lpkgs := b.sortedLocalPackages()
+       if err := syscfg.EnsureWritten(b.Cfg, lpkgs, b.ApiNames(),
+               targetPkg.BasePath()); err != nil {
+               return err
+       }
+
+       if err := sysinit.EnsureWritten(lpkgs, targetPkg.BasePath()); err != 
nil {
+               return err
+       }
+
+       b.compilerInfo = baseCi
+
        return nil
 }
 
@@ -493,29 +513,11 @@ func (b *Builder) matchFeature(flist 
[]map[string]interface{},
        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) AddCompilerInfo(info *toolchain.CompilerInfo) {
        b.compilerInfo.AddCompilerInfo(info)
 }
 
 func (b *Builder) Build() error {
-
        // Build the packages alphabetically to ensure a consistent order.
        bpkgs := b.sortedBuildPackages()
        for _, bpkg := range bpkgs {
@@ -555,32 +557,50 @@ func (b *Builder) TestLink(linkerScript string) error {
        return nil
 }
 
-func (b *Builder) Test(p *pkg.LocalPackage) error {
+func (b *Builder) pkgWithPath(path string) *BuildPackage {
+       for _, p := range b.Packages {
+               if p.BasePath() == path {
+                       return p
+               }
+       }
 
-       // Seed the builder with the package under test.
-       testBpkg := b.AddPackage(p)
+       return nil
+}
 
-       // Define the PKG_TEST symbol while the package under test is being
-       // compiled.  This symbol enables the appropriate main function that
-       // usually comes from an app.
-       testPkgCi, err := testBpkg.CompilerInfo(b)
-       if err != nil {
-               return err
+func (b *Builder) testOwner(p *BuildPackage) *BuildPackage {
+       if p.Type() != pkg.PACKAGE_TYPE_UNITTEST {
+               panic("Expected unittest package; got: " + p.Name())
        }
-       testPkgCi.Cflags = append(testPkgCi.Cflags, "-DMYNEWT_SELFTEST")
 
+       curPath := p.BasePath()
+
+       for {
+               parentPath := filepath.Dir(curPath)
+               if parentPath == project.GetProject().BasePath || parentPath == 
"." {
+                       return nil
+               }
+
+               parentPkg := b.pkgWithPath(parentPath)
+               if parentPkg != nil && parentPkg.Type() != 
pkg.PACKAGE_TYPE_UNITTEST {
+                       log.Debugf("OWNER=%s", parentPkg.Name())
+                       return parentPkg
+               }
+
+               curPath = parentPath
+       }
+}
+
+func (b *Builder) Test(p *pkg.LocalPackage) error {
        // Build the packages alphabetically to ensure a consistent order.
        bpkgs := b.sortedBuildPackages()
        for _, bpkg := range bpkgs {
-               err = b.buildPackage(bpkg)
-               if err != nil {
+               if err := b.buildPackage(bpkg); err != nil {
                        return err
                }
        }
 
        testFilename := b.TestExePath(p.Name())
-       err = b.link(testFilename, "", nil)
-       if err != nil {
+       if err := b.link(testFilename, "", nil); err != nil {
                return err
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/builder/buildpackage.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildpackage.go b/newt/builder/buildpackage.go
index b2d59fe..2cdd75b 100644
--- a/newt/builder/buildpackage.go
+++ b/newt/builder/buildpackage.go
@@ -30,6 +30,7 @@ import (
        "mynewt.apache.org/newt/newt/newtutil"
        "mynewt.apache.org/newt/newt/pkg"
        "mynewt.apache.org/newt/newt/project"
+       "mynewt.apache.org/newt/newt/syscfg"
        "mynewt.apache.org/newt/newt/toolchain"
        "mynewt.apache.org/newt/util"
 )
@@ -139,20 +140,21 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) 
(*toolchain.CompilerInfo, err
        }
 
        ci := toolchain.NewCompilerInfo()
-       ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.Viper, 
b.Features(bpkg),
+       features := syscfg.FeaturesForLpkg(b.Cfg, bpkg.LocalPackage)
+       ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.Viper, features,
                "pkg.cflags")
-       ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.Viper, 
b.Features(bpkg),
+       ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.Viper, features,
                "pkg.lflags")
-       ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.Viper, 
b.Features(bpkg),
+       ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.Viper, features,
                "pkg.aflags")
 
-       for fname, _ := range b.Features(bpkg) {
-               ci.Cflags = append(ci.Cflags, fmt.Sprintf("-DFEATURE_%s", 
fname))
+       for k, _ := range bpkg.InjectedSettings() {
+               ci.Cflags = append(ci.Cflags, syscfg.FeatureToCflag(k))
        }
 
        ci.IgnoreFiles = []*regexp.Regexp{}
        ignPats := newtutil.GetStringSliceFeatures(bpkg.Viper,
-               b.Features(bpkg), "pkg.ign_files")
+               features, "pkg.ign_files")
        for _, str := range ignPats {
                re, err := regexp.Compile(str)
                if err != nil {
@@ -164,7 +166,7 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) 
(*toolchain.CompilerInfo, err
 
        ci.IgnoreDirs = []*regexp.Regexp{}
        ignPats = newtutil.GetStringSliceFeatures(bpkg.Viper,
-               b.Features(bpkg), "pkg.ign_dirs")
+               features, "pkg.ign_dirs")
        for _, str := range ignPats {
                re, err := regexp.Compile(str)
                if err != nil {
@@ -175,38 +177,19 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) 
(*toolchain.CompilerInfo, err
        }
 
        bpkg.SourceDirectories = newtutil.GetStringSliceFeatures(bpkg.Viper,
-               b.Features(bpkg), "pkg.src_dirs")
+               features, "pkg.src_dirs")
 
        includePaths, err := bpkg.recursiveIncludePaths(b)
        if err != nil {
                return nil, err
        }
+
        ci.Includes = append(bpkg.privateIncludeDirs(b), includePaths...)
        bpkg.ci = ci
 
        return bpkg.ci, nil
 }
 
-func (bpkg *BuildPackage) loadFeatures(b *Builder) (map[string]bool, bool) {
-       features := b.AllFeatures()
-
-       foundNewFeature := false
-
-       newFeatures := newtutil.GetStringSliceFeatures(bpkg.Viper, features,
-               "pkg.features")
-       for _, nfeature := range newFeatures {
-               _, ok := features[nfeature]
-               if !ok {
-                       b.AddFeature(nfeature)
-                       foundNewFeature = true
-                       log.Debugf("Detected new feature: %s (%s)", nfeature,
-                               bpkg.Name())
-               }
-       }
-
-       return b.Features(bpkg), foundNewFeature
-}
-
 // Searches for a package which can satisfy bpkg's API requirement.  If such a
 // package is found, bpkg's API requirement is marked as satisfied, and the
 // package is added to bpkg's dependency list.
@@ -270,8 +253,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(bpkg),
-               "pkg.apis")
+       apis := newtutil.GetStringSliceFeatures(bpkg.Viper, features, 
"pkg.apis")
        for _, api := range apis {
                newApi := b.AddApi(api, bpkg)
                if newApi {
@@ -285,7 +267,9 @@ func (bpkg *BuildPackage) loadDeps(b *Builder,
 // @return bool                 true if a new dependency was detected as a
 //                                  result of satisfying an API for this
 //                                  package.
-func (bpkg *BuildPackage) satisfyApis(b *Builder) bool {
+func (bpkg *BuildPackage) satisfyApis(b *Builder,
+       features map[string]bool) bool {
+
        // Assume all this package's APIs are satisfied and that no new
        // dependencies will be detected.
        bpkg.apisSatisfied = true
@@ -293,7 +277,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(bpkg),
+       reqApis := newtutil.GetStringSliceFeatures(bpkg.Viper, features,
                "pkg.req_apis")
        for _, reqApi := range reqApis {
                reqStatus, ok := bpkg.reqApiMap[reqApi]
@@ -364,19 +348,25 @@ func (bpkg *BuildPackage) privateIncludeDirs(b *Builder) 
[]string {
        incls = append(incls, srcDir)
        incls = append(incls, srcDir+"/arch/"+b.target.Bsp.Arch)
 
-       if b.Features(bpkg)["TEST"] {
-               testSrcDir := srcDir + "/test"
-               incls = append(incls, testSrcDir)
-               incls = append(incls, testSrcDir+"/arch/"+b.target.Bsp.Arch)
-       }
-
-       // If pkgType == SDK, include all the items in "ext" directly into the
-       // include path
-       if bpkg.Type() == pkg.PACKAGE_TYPE_SDK {
+       switch bpkg.Type() {
+       case pkg.PACKAGE_TYPE_SDK:
+               // If pkgType == SDK, include all the items in "ext" directly 
into the
+               // include path
                incls = append(incls, b.target.Bsp.BasePath()+"/include/bsp/")
 
                sdkIncls := bpkg.findSdkIncludes()
                incls = append(incls, sdkIncls...)
+
+       case pkg.PACKAGE_TYPE_UNITTEST:
+               // A unittest package gets access to its parent package's 
private
+               // includes.
+               parentPkg := b.testOwner(bpkg)
+               if parentPkg != nil {
+                       parentIncls := parentPkg.privateIncludeDirs(b)
+                       incls = append(incls, parentIncls...)
+               }
+
+       default:
        }
 
        return incls
@@ -396,42 +386,38 @@ func (bpkg *BuildPackage) privateIncludeDirs(b *Builder) 
[]string {
 //
 // @return bool                 true if >=1 dependencies were resolved
 //         bool                 true if >=1 new features were detected
-func (bpkg *BuildPackage) Resolve(b *Builder) (bool, bool, error) {
+func (bpkg *BuildPackage) Resolve(b *Builder,
+       cfg syscfg.Cfg) (bool, error) {
+
        var err error
        newDeps := false
-       newFeatures := false
 
-       if !bpkg.depsResolved {
-               var features map[string]bool
+       features := syscfg.FeaturesForLpkg(cfg, bpkg.LocalPackage)
 
-               features, newFeatures = bpkg.loadFeatures(b)
+       if !bpkg.depsResolved {
                newDeps, err = bpkg.loadDeps(b, features)
                if err != nil {
-                       return false, false, err
+                       return false, err
                }
 
-               bpkg.depsResolved = !newFeatures && !newDeps
-
+               bpkg.depsResolved = !newDeps
        }
 
        if !bpkg.apisSatisfied {
-               newApiDep := bpkg.satisfyApis(b)
+               newApiDep := bpkg.satisfyApis(b, features)
                if newApiDep {
                        newDeps = true
                }
        }
 
-       return newDeps, newFeatures, nil
-}
-
-func (bp *BuildPackage) Init(pkg *pkg.LocalPackage) {
-       bp.LocalPackage = pkg
-       bp.reqApiMap = map[string]reqApiStatus{}
+       return newDeps, nil
 }
 
 func NewBuildPackage(pkg *pkg.LocalPackage) *BuildPackage {
-       bpkg := &BuildPackage{}
-       bpkg.Init(pkg)
+       bpkg := &BuildPackage{
+               LocalPackage: pkg,
+               reqApiMap:    map[string]reqApiStatus{},
+       }
 
        return bpkg
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/builder/buildutil.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildutil.go b/newt/builder/buildutil.go
index ca5a157..f35a1db 100644
--- a/newt/builder/buildutil.go
+++ b/newt/builder/buildutil.go
@@ -23,10 +23,13 @@ import (
        "bytes"
        "path/filepath"
        "sort"
+       "strings"
 
        log "github.com/Sirupsen/logrus"
 
+       "mynewt.apache.org/newt/newt/pkg"
        "mynewt.apache.org/newt/newt/project"
+       "mynewt.apache.org/newt/newt/syscfg"
        "mynewt.apache.org/newt/util"
 )
 
@@ -77,25 +80,27 @@ func (b *Builder) AppBinBasePath() string {
        return b.PkgBinDir(pkgName) + "/" + filepath.Base(pkgName)
 }
 
+func TestTargetName(testPkgName string) string {
+       return strings.Replace(testPkgName, "/", "_", -1)
+}
+
 func (b *Builder) TestExePath(pkgName string) string {
-       return b.PkgBinDir(pkgName) + "/test_" + filepath.Base(pkgName)
+       return b.PkgBinDir(pkgName) + "/" + TestTargetName(pkgName)
 }
 
 func (b *Builder) FeatureString() string {
        var buffer bytes.Buffer
 
-       features := make([]string, 0, len(b.Features(nil)))
-       for f, _ := range b.Features(nil) {
-               features = append(features, f)
+       featureMap := syscfg.Features(b.Cfg)
+       featureSlice := make([]string, 0, len(featureMap))
+       for k, _ := range featureMap {
+               featureSlice = append(featureSlice, k)
        }
-       sort.Strings(features)
+       sort.Strings(featureSlice)
 
-       first := true
-       for _, feature := range features {
-               if !first {
+       for i, feature := range featureSlice {
+               if i != 0 {
                        buffer.WriteString(" ")
-               } else {
-                       first = false
                }
 
                buffer.WriteString(feature)
@@ -168,6 +173,17 @@ func (b *Builder) sortedBuildPackages() []*BuildPackage {
        return sorter.bpkgs
 }
 
+func (b *Builder) sortedLocalPackages() []*pkg.LocalPackage {
+       bpkgs := b.sortedBuildPackages()
+
+       lpkgs := make([]*pkg.LocalPackage, len(bpkgs), len(bpkgs))
+       for i, bpkg := range bpkgs {
+               lpkgs[i] = bpkg.LocalPackage
+       }
+
+       return lpkgs
+}
+
 func (b *Builder) logDepInfo() {
        // Log feature set.
        log.Debugf("Feature set: [" + b.FeatureString() + "]")

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/builder/load.go
----------------------------------------------------------------------
diff --git a/newt/builder/load.go b/newt/builder/load.go
index 0c1a85b..9596532 100644
--- a/newt/builder/load.go
+++ b/newt/builder/load.go
@@ -25,6 +25,7 @@ import (
        "path/filepath"
 
        "mynewt.apache.org/newt/newt/project"
+       "mynewt.apache.org/newt/newt/syscfg"
        "mynewt.apache.org/newt/util"
 )
 
@@ -87,7 +88,7 @@ func (b *Builder) Load(image_slot int, extraJtagCmd string) 
error {
        downloadCmd := fmt.Sprintf("%s %s %s %s", envSettings, downloadScript, 
bspPath,
                binBaseName)
 
-       features := b.Features(nil)
+       features := syscfg.Features(b.Cfg)
 
        if _, ok := features["bootloader"]; ok {
                util.StatusMessage(util.VERBOSITY_DEFAULT,

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/builder/targetbuild.go
----------------------------------------------------------------------
diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go
index 3d9d96b..96b43f0 100644
--- a/newt/builder/targetbuild.go
+++ b/newt/builder/targetbuild.go
@@ -27,6 +27,7 @@ import (
        "mynewt.apache.org/newt/newt/pkg"
        "mynewt.apache.org/newt/newt/project"
        "mynewt.apache.org/newt/newt/symbol"
+       "mynewt.apache.org/newt/newt/syscfg"
        "mynewt.apache.org/newt/newt/target"
        "mynewt.apache.org/newt/newt/toolchain"
        "mynewt.apache.org/newt/util"
@@ -156,7 +157,7 @@ func (t *TargetBuilder) Build() error {
        /* Build the Apps */
        project.ResetDeps(t.AppList)
 
-       if err := t.Bsp.Reload(t.App.Features(t.App.BspPkg)); err != nil {
+       if err := t.Bsp.Reload(syscfg.Features(t.App.Cfg)); err != nil {
                return err
        }
 
@@ -181,7 +182,7 @@ func (t *TargetBuilder) Build() error {
        /* rebuild the loader */
        project.ResetDeps(t.LoaderList)
 
-       if err = t.Bsp.Reload(t.Loader.Features(t.Loader.BspPkg)); err != nil {
+       if err = t.Bsp.Reload(syscfg.Features(t.Loader.Cfg)); err != nil {
                return err
        }
 
@@ -403,10 +404,11 @@ func (t *TargetBuilder) Test(p *pkg.LocalPackage) error {
        // used:
        //     * TEST:      ensures that the test code gets compiled.
        //     * SELFTEST:  indicates that there is no app.
-       t.App.AddFeature("TEST")
-       t.App.AddFeature("SELFTEST")
+       t.App.injectedSettings["TEST"] = "1"
+       p.InjectedSettings()["SELFTEST"] = "1"
 
-       err = t.App.PrepBuild(p, bspPkg, targetPkg)
+       t.App.AddPackage(p)
+       err = t.App.PrepBuild(nil, bspPkg, targetPkg)
 
        if err != nil {
                return err

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/cli/build_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/build_cmds.go b/newt/cli/build_cmds.go
index bc19cf5..a26deb7 100644
--- a/newt/cli/build_cmds.go
+++ b/newt/cli/build_cmds.go
@@ -22,6 +22,7 @@ package cli
 import (
        "fmt"
        "os"
+       "path/filepath"
 
        "github.com/spf13/cobra"
        "mynewt.apache.org/newt/newt/builder"
@@ -33,12 +34,68 @@ import (
 
 const TARGET_TEST_NAME = "unittest"
 
-var extraJtagCmd string
+var testablePkgMap map[*pkg.LocalPackage]struct{}
+
+func testablePkgs() map[*pkg.LocalPackage]struct{} {
+       if testablePkgMap != nil {
+               return testablePkgMap
+       }
+
+       testablePkgMap := map[*pkg.LocalPackage]struct{}{}
+
+       // Create a map of path => lclPkg.
+       proj := project.GetProject()
+       allPkgs := proj.PackagesOfType(-1)
+       pathLpkgMap := make(map[string]*pkg.LocalPackage, len(allPkgs))
+       for _, p := range allPkgs {
+               lpkg := p.(*pkg.LocalPackage)
+               pathLpkgMap[lpkg.BasePath()] = lpkg
+       }
+
+       // Add all unit test packages to the testable package map.
+       testPkgs := proj.PackagesOfType(pkg.PACKAGE_TYPE_UNITTEST)
+       for _, p := range testPkgs {
+               lclPack := p.(*pkg.LocalPackage)
+               testablePkgMap[lclPack] = struct{}{}
+       }
+
+       // Next add first ancestor of each test package.
+       for testPkg, _ := range testablePkgMap {
+               for cur := filepath.Dir(testPkg.BasePath()); cur != 
proj.BasePath; cur = filepath.Dir(cur) {
+                       lpkg := pathLpkgMap[cur]
+                       if lpkg != nil && lpkg.Type() != 
pkg.PACKAGE_TYPE_UNITTEST {
+                               testablePkgMap[lpkg] = struct{}{}
+                               break
+                       }
+               }
+       }
 
-func pkgIsTestable(pack *pkg.LocalPackage) bool {
-       return util.NodeExist(pack.BasePath() + "/src/test")
+       return testablePkgMap
 }
 
+func pkgToUnitTests(pack *pkg.LocalPackage) []*pkg.LocalPackage {
+       // If the user specified a unittest package, just test that one.
+       if pack.Type() == pkg.PACKAGE_TYPE_UNITTEST {
+               return []*pkg.LocalPackage{pack}
+       }
+
+       // Otherwise, return all the package's direct descendants that are unit
+       // test packages.
+       result := []*pkg.LocalPackage{}
+       srcPath := pack.BasePath()
+       for p, _ := range testablePkgs() {
+               if p.Type() == pkg.PACKAGE_TYPE_UNITTEST &&
+                       filepath.Dir(p.BasePath()) == srcPath {
+
+                       result = append(result, p)
+               }
+       }
+
+       return result
+}
+
+var extraJtagCmd string
+
 func buildRunCmd(cmd *cobra.Command, args []string) {
        if err := project.Initialize(); err != nil {
                NewtUsage(cmd, err)
@@ -132,10 +189,17 @@ func cleanRunCmd(cmd *cobra.Command, args []string) {
        }
 }
 
-func testRunCmd(cmd *cobra.Command, args []string) {
-       if err := project.Initialize(); err != nil {
-               NewtUsage(cmd, err)
+func pkgnames(pkgs []*pkg.LocalPackage) string {
+       s := ""
+
+       for _, p := range pkgs {
+               s += p.Name() + " "
        }
+
+       return s
+}
+
+func testRunCmd(cmd *cobra.Command, args []string) {
        if len(args) < 1 {
                NewtUsage(cmd, nil)
        }
@@ -152,26 +216,26 @@ func testRunCmd(cmd *cobra.Command, args []string) {
                                NewtUsage(cmd, err)
                        }
 
-                       if !pkgIsTestable(pack) {
+                       testPkgs := pkgToUnitTests(pack)
+                       if len(testPkgs) == 0 {
                                NewtUsage(nil, util.FmtNewtError("Package %s 
contains no "+
                                        "unit tests", pack.FullName()))
                        }
 
-                       packs = append(packs, pack)
+                       packs = append(packs, testPkgs...)
                }
        }
 
+       proj := project.GetProject()
+
        if testAll {
-               packs = []*pkg.LocalPackage{}
-               for _, repoHash := range project.GetProject().PackageList() {
-                       for _, pack := range *repoHash {
-                               lclPack := pack.(*pkg.LocalPackage)
-
-                               if pkgIsTestable(lclPack) {
-                                       packs = append(packs, lclPack)
-                               }
-                       }
+               packItfs := proj.PackagesOfType(pkg.PACKAGE_TYPE_UNITTEST)
+               packs = make([]*pkg.LocalPackage, len(packItfs))
+               for i, p := range packItfs {
+                       packs[i] = p.(*pkg.LocalPackage)
                }
+
+               packs = pkg.SortLclPkgs(packs)
        }
 
        if len(packs) == 0 {
@@ -186,13 +250,36 @@ func testRunCmd(cmd *cobra.Command, args []string) {
                        NewtUsage(nil, err)
                }
 
-               // Use the standard unit test target for all tests.
-               t := ResolveTarget(TARGET_TEST_NAME)
-               if t == nil {
+               // Each unit test package gets its own target.  This target is 
a copy
+               // of the base unit test package, just with an appropriate 
name.  The
+               // reason each test needs a unique target is: syscfg and 
sysinit are
+               // target-specific.  If each test package shares a target, they 
will
+               // overwrite these generated headers each time they are run.  
Worse, if
+               // two tests are run back-to-back, the timestamps may indicate 
that the
+               // headers have not changed between tests, causing build 
failures.
+               baseTarget := ResolveTarget(TARGET_TEST_NAME)
+               if baseTarget == nil {
                        NewtUsage(nil, util.NewNewtError("Can't find unit test 
target: "+
                                TARGET_TEST_NAME))
                }
 
+               targetName := fmt.Sprintf("%s/%s/%s",
+                       TARGET_DEFAULT_DIR, TARGET_TEST_NAME,
+                       builder.TestTargetName(pack.Name()))
+
+               t := ResolveTarget(targetName)
+               if t == nil {
+                       targetName, err := ResolveNewTargetName(targetName)
+                       if err != nil {
+                               NewtUsage(nil, err)
+                       }
+
+                       t = baseTarget.Clone(proj.LocalRepo(), targetName)
+                       if err := t.Save(); err != nil {
+                               NewtUsage(nil, err)
+                       }
+               }
+
                b, err := builder.NewTargetBuilder(t)
                if err != nil {
                        NewtUsage(nil, err)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/cli/complete_cmd.go
----------------------------------------------------------------------
diff --git a/newt/cli/complete_cmd.go b/newt/cli/complete_cmd.go
index c01410c..b2e83b6 100644
--- a/newt/cli/complete_cmd.go
+++ b/newt/cli/complete_cmd.go
@@ -54,35 +54,17 @@ func targetList() []string {
        return targetNames
 }
 
-/* return a list of all packages */
+/* @return                      A slice of all testable package names. */
 func packageList() []string {
-
-       err := project.Initialize()
-
-       var list []string
-
-       if err != nil {
-               return list
-       }
-       for _, repoHash := range project.GetProject().PackageList() {
-               for _, pack := range *repoHash {
-                       lclPack := pack.(*pkg.LocalPackage)
-
-                       if pkgIsTestable(lclPack) {
-                               list = append(list, lclPack.FullName())
-                       }
+       packs := testablePkgs()
+       names := make([]string, 0, len(packs))
+       for pack, _ := range packs {
+               if pack.Type() != pkg.PACKAGE_TYPE_UNITTEST {
+                       names = append(names, pack.FullName())
                }
        }
-       return list
-}
 
-func isValueInList(value string, list []string) int {
-       for i, v := range list {
-               if v == value {
-                       return i
-               }
-       }
-       return -1
+       return names
 }
 
 func completeRunCmd(cmd *cobra.Command, args []string) {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/cli/target_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/target_cmds.go b/newt/cli/target_cmds.go
index b9ebada..364fbaf 100644
--- a/newt/cli/target_cmds.go
+++ b/newt/cli/target_cmds.go
@@ -29,8 +29,10 @@ import (
        "strings"
 
        "github.com/spf13/cobra"
+       "mynewt.apache.org/newt/newt/builder"
        "mynewt.apache.org/newt/newt/pkg"
        "mynewt.apache.org/newt/newt/project"
+       "mynewt.apache.org/newt/newt/syscfg"
        "mynewt.apache.org/newt/newt/target"
        "mynewt.apache.org/newt/util"
 )
@@ -333,6 +335,90 @@ func targetCopyCmd(cmd *cobra.Command, args []string) {
        }
 }
 
+func printSetting(entry syscfg.CfgEntry) {
+       util.StatusMessage(util.VERBOSITY_DEFAULT,
+               "  * Setting: %s\n", entry.Name)
+
+       util.StatusMessage(util.VERBOSITY_DEFAULT,
+               "    * Description: %s\n", entry.Description)
+
+       util.StatusMessage(util.VERBOSITY_DEFAULT,
+               "    * Value: %s", entry.Value)
+
+       unfixed := syscfg.UnfixedValue(entry)
+       if unfixed != entry.Value {
+               util.StatusMessage(util.VERBOSITY_DEFAULT, " [%s]", unfixed)
+       }
+       util.StatusMessage(util.VERBOSITY_DEFAULT, "\n")
+
+       if len(entry.History) > 1 {
+               util.StatusMessage(util.VERBOSITY_DEFAULT,
+                       "    * Overridden: ")
+               for i := 1; i < len(entry.History); i++ {
+                       util.StatusMessage(util.VERBOSITY_DEFAULT, "%s, ",
+                               entry.History[i].Source.Name())
+               }
+               util.StatusMessage(util.VERBOSITY_DEFAULT,
+                       "default=%s\n", entry.History[0].Value)
+       }
+}
+
+func printPkgCfg(pkgName string, cfg syscfg.Cfg, entries []syscfg.CfgEntry) {
+       util.StatusMessage(util.VERBOSITY_DEFAULT, "* PACKAGE: %s\n", pkgName)
+
+       settingNames := make([]string, len(entries))
+       for i, entry := range entries {
+               settingNames[i] = entry.Name
+       }
+       sort.Strings(settingNames)
+
+       for _, name := range settingNames {
+               printSetting(cfg[name])
+       }
+}
+
+func printCfg(cfg syscfg.Cfg) {
+       pkgNameEntryMap := syscfg.EntriesByPkg(cfg)
+
+       pkgNames := make([]string, 0, len(pkgNameEntryMap))
+       for pkgName, _ := range pkgNameEntryMap {
+               pkgNames = append(pkgNames, pkgName)
+       }
+       sort.Strings(pkgNames)
+
+       for i, pkgName := range pkgNames {
+               if i > 0 {
+                       util.StatusMessage(util.VERBOSITY_DEFAULT, "\n")
+               }
+               printPkgCfg(pkgName, cfg, pkgNameEntryMap[pkgName])
+       }
+}
+
+func targetConfigCmd(cmd *cobra.Command, args []string) {
+       if err := project.Initialize(); err != nil {
+               NewtUsage(cmd, err)
+       }
+       if len(args) != 1 {
+               NewtUsage(cmd, util.NewNewtError("Must specify target name"))
+       }
+
+       t, err := resolveExistingTargetArg(args[0])
+       if err != nil {
+               NewtUsage(cmd, err)
+       }
+
+       b, err := builder.NewTargetBuilder(t)
+       if err != nil {
+               NewtUsage(nil, err)
+       }
+
+       if err := b.PrepBuild(); err != nil {
+               NewtUsage(nil, err)
+       }
+
+       printCfg(b.App.Cfg)
+}
+
 func AddTargetCommands(cmd *cobra.Command) {
        targetHelpText := ""
        targetHelpEx := ""
@@ -415,12 +501,25 @@ func AddTargetCommands(cmd *cobra.Command) {
        copyHelpEx += "  newt target copy blinky_sim my_target"
 
        copyCmd := &cobra.Command{
-               Use:     "copy",
-               Short:   "Copy target",
-               Long:    copyHelpText,
-               Example: copyHelpEx,
-               Run:     targetCopyCmd,
+               Use:       "copy",
+               Short:     "Copy target",
+               Long:      copyHelpText,
+               Example:   copyHelpEx,
+               Run:       targetCopyCmd,
+               ValidArgs: targetList(),
        }
 
        targetCmd.AddCommand(copyCmd)
+
+       configHelpText := "View a target's system configuration."
+
+       configCmd := &cobra.Command{
+               Use:       "config <target-name>",
+               Short:     "View target system configuration",
+               Long:      configHelpText,
+               Run:       targetConfigCmd,
+               ValidArgs: targetList(),
+       }
+
+       targetCmd.AddCommand(configCmd)
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/newt.go
----------------------------------------------------------------------
diff --git a/newt/newt.go b/newt/newt.go
index 03fb8de..f1e0c2d 100644
--- a/newt/newt.go
+++ b/newt/newt.go
@@ -28,6 +28,7 @@ import (
 
        "mynewt.apache.org/newt/newt/cli"
        "mynewt.apache.org/newt/newt/newtutil"
+       "mynewt.apache.org/newt/newt/project"
        "mynewt.apache.org/newt/util"
 )
 
@@ -114,13 +115,14 @@ func newtCmd() *cobra.Command {
 }
 
 func main() {
-
        cmd := newtCmd()
 
        /* some of the setup code logs which messes with autocomplete */
        hold_lvl := log.GetLevel()
        log.SetLevel(log.FatalLevel)
 
+       initErr := project.Initialize()
+
        cli.AddCompleteCommands(cmd)
        cli.AddProjectCommands(cmd)
        cli.AddTargetCommands(cmd)
@@ -146,6 +148,10 @@ func main() {
                cmd.SilenceUsage = false
        }
 
+       if initErr != nil {
+               cli.NewtUsage(nil, initErr)
+       }
+
        log.SetLevel(hold_lvl)
        cmd.Execute()
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/newtutil/newtutil.go
----------------------------------------------------------------------
diff --git a/newt/newtutil/newtutil.go b/newt/newtutil/newtutil.go
index 42e68fb..947ab49 100644
--- a/newt/newtutil/newtutil.go
+++ b/newt/newtutil/newtutil.go
@@ -27,6 +27,8 @@ import (
        "strconv"
        "strings"
 
+       "github.com/spf13/cast"
+
        "mynewt.apache.org/newt/util"
        "mynewt.apache.org/newt/viper"
 )
@@ -34,6 +36,51 @@ import (
 var NewtVersionStr string = "Apache Newt (incubating) version: 0.9.0"
 var NewtBlinkyTag string = "mynewt_0_9_0_tag"
 
+func GetSliceFeatures(v *viper.Viper, features map[string]bool,
+       key string) []interface{} {
+
+       val := v.Get(key)
+       vals := []interface{}{val}
+
+       // Process the features in alphabetical order to ensure consistent
+       // results across repeated runs.
+       var featureKeys []string
+       for feature, _ := range features {
+               featureKeys = append(featureKeys, feature)
+       }
+       sort.Strings(featureKeys)
+
+       for _, feature := range featureKeys {
+               overwriteVal := v.Get(key + "." + feature + ".OVERWRITE")
+               if overwriteVal != nil {
+                       return []interface{}{overwriteVal}
+               }
+
+               appendVal := v.Get(key + "." + feature)
+               if appendVal != nil {
+                       vals = append(vals, appendVal)
+               }
+       }
+
+       return vals
+}
+
+func GetStringMapFeatures(v *viper.Viper, features map[string]bool,
+       key string) map[string]interface{} {
+
+       result := map[string]interface{}{}
+
+       slice := GetSliceFeatures(v, features, key)
+       for _, itf := range slice {
+               sub := cast.ToStringMap(itf)
+               for k, v := range sub {
+                       result[k] = v
+               }
+       }
+
+       return result
+}
+
 func GetStringFeatures(v *viper.Viper, features map[string]bool,
        key string) string {
        val := v.GetString(key)
@@ -87,28 +134,15 @@ func GetBoolFeatures(v *viper.Viper, features 
map[string]bool,
 func GetStringSliceFeatures(v *viper.Viper, features map[string]bool,
        key string) []string {
 
-       val := v.GetStringSlice(key)
+       vals := GetSliceFeatures(v, features, key)
 
-       // string empty items
-       result := []string{}
-       for _, item := range val {
-               if item == "" || item == " " {
-                       continue
-               }
-               result = append(result, item)
+       strVals := []string{}
+       for _, v := range vals {
+               subVals := cast.ToStringSlice(v)
+               strVals = append(strVals, subVals...)
        }
 
-       for item, _ := range features {
-               overwriteVal := v.GetStringSlice(key + "." + item + 
".OVERWRITE")
-               if overwriteVal != nil {
-                       result = overwriteVal
-                       break
-               }
-
-               result = append(result, v.GetStringSlice(key+"."+item)...)
-       }
-
-       return result
+       return strVals
 }
 
 // Parses a string of the following form:

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/pkg/localpackage.go
----------------------------------------------------------------------
diff --git a/newt/pkg/localpackage.go b/newt/pkg/localpackage.go
index 0e73d8d..86c5777 100644
--- a/newt/pkg/localpackage.go
+++ b/newt/pkg/localpackage.go
@@ -60,15 +60,15 @@ type LocalPackage struct {
        desc *PackageDesc
        // Dependencies for this package
        deps []*Dependency
-       // APIs that this package exports
-       apis []string
-       // 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{}
+       // Package init function name and stage.  These are used to generate the
+       // sysinit C file.
+       initFnName string
+       initStage  int
+
+       // Extra package-specific settings that don't come from syscfg.  For
+       // example, SELFTEST gets set when the newt test command is used.
+       injectedSettings map[string]string
 
        // Pointer to pkg.yml configuration structure
        Viper *viper.Viper
@@ -82,8 +82,10 @@ func NewLocalPackage(r *repo.Repo, pkgDir string) 
*LocalPackage {
                desc: &PackageDesc{},
                // XXX: Initialize viper object; clients should not need to 
check for
                // nil pointer.
+               repo:             r,
+               basePath:         filepath.Clean(pkgDir) + "/", // XXX: Remove 
slash.
+               injectedSettings: map[string]string{},
        }
-       pkg.Init(r, pkgDir)
        return pkg
 }
 
@@ -101,7 +103,7 @@ func (pkg *LocalPackage) FullName() string {
 }
 
 func (pkg *LocalPackage) BasePath() string {
-       return pkg.basePath
+       return filepath.Clean(pkg.basePath)
 }
 
 func (pkg *LocalPackage) Type() interfaces.PackageType {
@@ -201,22 +203,6 @@ func (pkg *LocalPackage) Deps() []*Dependency {
        return pkg.deps
 }
 
-func (pkg *LocalPackage) AddApi(api string) {
-       pkg.apis = append(pkg.apis, api)
-}
-
-func (pkg *LocalPackage) Apis() []string {
-       return pkg.apis
-}
-
-func (pkg *LocalPackage) AddReqApi(api string) {
-       pkg.reqApis = append(pkg.reqApis, api)
-}
-
-func (pkg *LocalPackage) ReqApis() []string {
-       return pkg.reqApis
-}
-
 func (pkg *LocalPackage) readDesc(v *viper.Viper) (*PackageDesc, error) {
        pdesc := &PackageDesc{}
 
@@ -228,11 +214,6 @@ func (pkg *LocalPackage) readDesc(v *viper.Viper) 
(*PackageDesc, error) {
        return pdesc, nil
 }
 
-func (pkg *LocalPackage) Init(repo *repo.Repo, pkgDir string) {
-       pkg.repo = repo
-       pkg.basePath = filepath.Clean(pkgDir) + "/"
-}
-
 func (pkg *LocalPackage) sequenceString(key string) string {
        var buffer bytes.Buffer
 
@@ -314,8 +295,8 @@ func (pkg *LocalPackage) Load() error {
                }
        }
 
-       pkg.featureBlackList = v.GetStringMap("pkg.feature_blacklist")
-       pkg.featureWhiteList = v.GetStringMap("pkg.feature_whitelist")
+       pkg.initFnName = v.GetString("pkg.init_function")
+       pkg.initStage = v.GetInt("pkg.init_stage")
 
        // Read the package description from the file
        pkg.desc, err = pkg.readDesc(v)
@@ -328,12 +309,16 @@ func (pkg *LocalPackage) Load() error {
        return nil
 }
 
-func (pkg *LocalPackage) FeatureBlackList() map[string]interface{} {
-       return pkg.featureBlackList
+func (pkg *LocalPackage) InitStage() int {
+       return pkg.initStage
+}
+
+func (pkg *LocalPackage) InitFnName() string {
+       return pkg.initFnName
 }
 
-func (pkg *LocalPackage) FeatureWhiteList() map[string]interface{} {
-       return pkg.featureWhiteList
+func (pkg *LocalPackage) InjectedSettings() map[string]string {
+       return pkg.injectedSettings
 }
 
 func (pkg *LocalPackage) Clone(newRepo *repo.Repo,
@@ -356,8 +341,7 @@ func (pkg *LocalPackage) Clone(newRepo *repo.Repo,
 }
 
 func LoadLocalPackage(repo *repo.Repo, pkgDir string) (*LocalPackage, error) {
-       pkg := &LocalPackage{}
-       pkg.Init(repo, pkgDir)
+       pkg := NewLocalPackage(repo, pkgDir)
        err := pkg.Load()
        return pkg, err
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/pkg/package.go
----------------------------------------------------------------------
diff --git a/newt/pkg/package.go b/newt/pkg/package.go
index 4fa988c..644889e 100644
--- a/newt/pkg/package.go
+++ b/newt/pkg/package.go
@@ -1,5 +1,4 @@
 /**
-   PACKAGE_TYPE_LIB: "lib",
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
@@ -16,7 +15,7 @@
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
-*/
+ */
 
 package pkg
 
@@ -37,6 +36,7 @@ const (
        PACKAGE_TYPE_COMPILER
        PACKAGE_TYPE_LIB
        PACKAGE_TYPE_TARGET
+       PACKAGE_TYPE_UNITTEST
 )
 
 var PackageTypeNames = map[interfaces.PackageType]string{
@@ -46,6 +46,7 @@ var PackageTypeNames = map[interfaces.PackageType]string{
        PACKAGE_TYPE_COMPILER: "compiler",
        PACKAGE_TYPE_LIB:      "lib",
        PACKAGE_TYPE_TARGET:   "target",
+       PACKAGE_TYPE_UNITTEST: "unittest",
 }
 
 // An interface, representing information about a Package

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/pkg/packageutil.go
----------------------------------------------------------------------
diff --git a/newt/pkg/packageutil.go b/newt/pkg/packageutil.go
new file mode 100644
index 0000000..f3f6132
--- /dev/null
+++ b/newt/pkg/packageutil.go
@@ -0,0 +1,32 @@
+package pkg
+
+import (
+       "sort"
+)
+
+type lpkgSorter struct {
+       pkgs []*LocalPackage
+}
+
+func (s lpkgSorter) Len() int {
+       return len(s.pkgs)
+}
+func (s lpkgSorter) Swap(i, j int) {
+       s.pkgs[i], s.pkgs[j] = s.pkgs[j], s.pkgs[i]
+}
+func (s lpkgSorter) Less(i, j int) bool {
+       return s.pkgs[i].Name() < s.pkgs[j].Name()
+}
+
+func SortLclPkgs(pkgs []*LocalPackage) []*LocalPackage {
+       sorter := lpkgSorter{
+               pkgs: make([]*LocalPackage, 0, len(pkgs)),
+       }
+
+       for _, p := range pkgs {
+               sorter.pkgs = append(sorter.pkgs, p)
+       }
+
+       sort.Sort(sorter)
+       return sorter.pkgs
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/project/project.go
----------------------------------------------------------------------
diff --git a/newt/project/project.go b/newt/project/project.go
index 78585af..29646e5 100644
--- a/newt/project/project.go
+++ b/newt/project/project.go
@@ -497,7 +497,6 @@ func findProjectDir(dir string) (string, error) {
 
                log.Debugf("Searching for project file %s", projFile)
                if util.NodeExist(projFile) {
-                       log.Infof("Project file found at %s", projFile)
                        break
                }
 
@@ -518,7 +517,6 @@ func (proj *Project) loadPackageList() error {
        // packages / store them in the project package list.
        repos := proj.Repos()
        for name, repo := range repos {
-               log.Debugf("Loading packages in repository %s", repo.Path())
                list, err := pkg.ReadLocalPackages(repo, repo.Path())
                if err != nil {
                        return err

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/syscfg/syscfg.go
----------------------------------------------------------------------
diff --git a/newt/syscfg/syscfg.go b/newt/syscfg/syscfg.go
new file mode 100644
index 0000000..c94abfb
--- /dev/null
+++ b/newt/syscfg/syscfg.go
@@ -0,0 +1,801 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 syscfg
+
+import (
+       "bytes"
+       "fmt"
+       "io"
+       "io/ioutil"
+       "os"
+       "path/filepath"
+       "sort"
+       "strconv"
+       "strings"
+
+       log "github.com/Sirupsen/logrus"
+       "github.com/spf13/cast"
+
+       "mynewt.apache.org/newt/newt/newtutil"
+       "mynewt.apache.org/newt/newt/pkg"
+       "mynewt.apache.org/newt/util"
+)
+
+const SYSCFG_INCLUDE_SUBDIR = "include/syscfg"
+const SYSCFG_HEADER_FILENAME = "syscfg.h"
+
+const SYSCFG_PREFIX_API = "MYNEWT_API_"
+const SYSCFG_PREFIX_PKG = "MYNEWT_PKG_"
+const SYSCFG_PREFIX_SETTING = "MYNEWT_VAL_"
+
+type CfgSettingType int
+
+const (
+       CFG_SETTING_TYPE_RAW CfgSettingType = iota
+       CFG_SETTING_TYPE_TASK_PRIO
+       CFG_SETTING_TYPE_INTERRUPT_PRIO
+)
+
+const SYSCFG_PRIO_ANY = "any"
+
+// Reserve last 16 priorities for the system (sanity, idle).
+const SYSCFG_TASK_PRIO_MAX = 0xef
+
+// The range of interrupt priorities is hardware dependent, so don't limit
+// these here.
+const SYSCFG_INTERRUPT_PRIO_MAX = 0xffffffff
+
+var cfgSettingNameTypeMap = map[string]CfgSettingType{
+       "raw":                CFG_SETTING_TYPE_RAW,
+       "task_priority":      CFG_SETTING_TYPE_TASK_PRIO,
+       "interrupt_priority": CFG_SETTING_TYPE_INTERRUPT_PRIO,
+}
+
+type CfgPoint struct {
+       Value  string
+       Source *pkg.LocalPackage
+}
+
+type CfgEntry struct {
+       Name        string
+       Value       string
+       History     []CfgPoint
+       Description string
+       SettingType CfgSettingType
+}
+
+type Cfg map[string]CfgEntry
+
+type cfgRoster struct {
+       settings    map[string]string
+       pkgsPresent map[string]bool
+       apisPresent map[string]bool
+}
+
+func WritePreamble(w io.Writer) {
+       fmt.Fprintf(w, "/**\n * This file was generated by %s\n */\n\n",
+               newtutil.NewtVersionStr)
+}
+
+func ValueIsTrue(val string) bool {
+       if val == "" {
+               return false
+       }
+
+       i, err := util.AtoiNoOct(val)
+       if err == nil && i == 0 {
+               return false
+       }
+
+       return true
+}
+
+func Features(cfg Cfg) map[string]bool {
+       features := map[string]bool{}
+       for k, v := range cfg {
+               if v.IsTrue() {
+                       features[k] = true
+               }
+       }
+
+       return features
+}
+
+func FeaturesForLpkg(cfg Cfg, lpkg *pkg.LocalPackage) map[string]bool {
+       features := Features(cfg)
+
+       for k, v := range lpkg.InjectedSettings() {
+               _, ok := features[k]
+               if ok {
+                       log.Warnf("Attempt to override syscfg setting %s with "+
+                               "injected feature from package %s", k, 
lpkg.Name())
+               } else {
+                       if ValueIsTrue(v) {
+                               features[k] = true
+                       }
+               }
+       }
+
+       return features
+}
+
+func (point CfgPoint) Name() string {
+       if point.Source == nil {
+               return "newt"
+       } else {
+               return point.Source.Name()
+       }
+}
+
+func (entry *CfgEntry) IsTrue() bool {
+       return ValueIsTrue(entry.Value)
+}
+
+func appendValue(entry *CfgEntry, lpkg *pkg.LocalPackage, value interface{}) {
+       strval := fmt.Sprintf("%+v", value)
+       point := CfgPoint{Value: strval, Source: lpkg}
+       entry.History = append(entry.History, point)
+       entry.Value = strval
+}
+
+func FeatureToCflag(featureName string) string {
+       return fmt.Sprintf("-D%s=1", settingName(featureName))
+}
+
+func stringValue(val interface{}) string {
+       return strings.TrimSpace(cast.ToString(val))
+}
+
+func readSetting(name string, lpkg *pkg.LocalPackage,
+       vals map[interface{}]interface{}) (CfgEntry, error) {
+
+       entry := CfgEntry{}
+
+       entry.Name = name
+       entry.Description = stringValue(vals["description"])
+       entry.Value = stringValue(vals["value"])
+       if vals["type"] == nil {
+               entry.SettingType = CFG_SETTING_TYPE_RAW
+       } else {
+               var ok bool
+               typename := stringValue(vals["type"])
+               entry.SettingType, ok = cfgSettingNameTypeMap[typename]
+               if !ok {
+                       return entry, util.FmtNewtError(
+                               "setting %s specifies invalid type: %s", name, 
typename)
+               }
+       }
+
+       appendValue(&entry, lpkg, entry.Value)
+
+       return entry, nil
+}
+
+func readOnce(cfg Cfg, lpkg *pkg.LocalPackage) error {
+       v := lpkg.Viper
+
+       features := FeaturesForLpkg(cfg, lpkg)
+       settings := newtutil.GetStringMapFeatures(v, features, 
"pkg.syscfg_defs")
+       if settings != nil {
+               for k, v := range settings {
+                       vals := v.(map[interface{}]interface{})
+                       entry, err := readSetting(k, lpkg, vals)
+                       if err != nil {
+                               return util.FmtNewtError("Config for package 
%s: %s",
+                                       lpkg.Name(), err.Error())
+                       }
+
+                       if _, exists := cfg[k]; exists {
+                               // XXX: Better error message.
+                               return util.FmtNewtError("setting %s 
redefined", k)
+                       }
+                       cfg[k] = entry
+               }
+       }
+
+       values := newtutil.GetStringMapFeatures(v, features, "pkg.syscfg_vals")
+       if values != nil {
+               for k, v := range values {
+                       entry, ok := cfg[k]
+                       if ok {
+                               appendValue(&entry, lpkg, v)
+                               cfg[k] = entry
+                       } else {
+                               log.Warnf("ignoring override of undefined 
setting; "+
+                                       "%s sets %s=%+v", lpkg.Name(), k, v)
+                       }
+
+               }
+       }
+
+       return nil
+}
+
+func Log(cfg Cfg) {
+       keys := make([]string, len(cfg))
+       i := 0
+       for k, _ := range cfg {
+               keys[i] = k
+               i++
+       }
+       sort.Strings(keys)
+
+       log.Debugf("syscfg settings (%d entries):", len(cfg))
+       for _, k := range keys {
+               entry := cfg[k]
+
+               str := fmt.Sprintf("    %s=%s [", k, entry.Value)
+
+               for i, p := range entry.History {
+                       if i != 0 {
+                               str += ", "
+                       }
+                       str += fmt.Sprintf("%s:%s", p.Name(), p.Value)
+               }
+               str += "]"
+
+               log.Debug(str)
+       }
+}
+
+func escapeStr(s string) string {
+       s = strings.Replace(s, "/", "_", -1)
+       s = strings.Replace(s, "-", "_", -1)
+       s = strings.Replace(s, " ", "_", -1)
+       s = strings.ToUpper(s)
+       return s
+}
+
+func isSettingVal(s string) bool {
+       return strings.HasPrefix(s, SYSCFG_PREFIX_SETTING)
+}
+
+func isPkgVal(s string) bool {
+       return strings.HasPrefix(s, SYSCFG_PREFIX_PKG)
+}
+
+func isApiVal(s string) bool {
+       return strings.HasPrefix(s, SYSCFG_PREFIX_API)
+}
+
+func settingName(setting string) string {
+       return SYSCFG_PREFIX_SETTING + escapeStr(setting)
+}
+
+func pkgPresentName(pkgName string) string {
+       return SYSCFG_PREFIX_PKG + escapeStr(pkgName)
+}
+
+func apiPresentName(apiName string) string {
+       return SYSCFG_PREFIX_API + strings.ToUpper(apiName)
+}
+
+func Read(lpkgs []*pkg.LocalPackage, apis []string,
+       injectedSettings map[string]string) (Cfg, error) {
+
+       cfg := Cfg{}
+       for k, v := range injectedSettings {
+               cfg[k] = CfgEntry{
+                       Name:        k,
+                       Description: "Injected setting",
+                       Value:       v,
+                       History: []CfgPoint{{
+                               Value:  v,
+                               Source: nil,
+                       }},
+               }
+       }
+
+       // Read system configuration files.  In case of conflicting settings, 
the
+       // higher priority pacakge's setting wins.  Package priorities are 
assigned
+       // as follows (highest priority first):
+       //     * target
+       //     * app (if present)
+       //     * unittest (if no app)
+       //     * bsp
+
+       var app *pkg.LocalPackage
+       var bsp *pkg.LocalPackage
+       var target *pkg.LocalPackage
+       var unittest *pkg.LocalPackage
+
+       for _, lpkg := range lpkgs {
+               switch lpkg.Type() {
+               case pkg.PACKAGE_TYPE_LIB:
+                       if err := readOnce(cfg, lpkg); err != nil {
+                               return cfg, err
+                       }
+
+               case pkg.PACKAGE_TYPE_APP:
+                       app = lpkg
+
+               case pkg.PACKAGE_TYPE_BSP:
+                       bsp = lpkg
+
+               case pkg.PACKAGE_TYPE_TARGET:
+                       target = lpkg
+
+               case pkg.PACKAGE_TYPE_UNITTEST:
+                       unittest = lpkg
+               }
+       }
+
+       if bsp != nil {
+               if err := readOnce(cfg, bsp); err != nil {
+                       return cfg, err
+               }
+       }
+       if app != nil {
+               if err := readOnce(cfg, app); err != nil {
+                       return cfg, err
+               }
+       } else if unittest != nil {
+               if err := readOnce(cfg, unittest); err != nil {
+                       return cfg, err
+               }
+       }
+       if target != nil {
+               if err := readOnce(cfg, target); err != nil {
+                       return cfg, err
+               }
+       }
+
+       roster := buildCfgRoster(cfg, lpkgs, apis)
+       if err := fixupSettings(cfg, roster); err != nil {
+               return cfg, err
+       }
+
+       return cfg, nil
+}
+
+func mostRecentPoint(entry CfgEntry) CfgPoint {
+       if len(entry.History) == 0 {
+               panic("invalid cfg entry; len(history) == 0")
+       }
+
+       return entry.History[len(entry.History)-1]
+}
+
+func calcPriorities(cfg Cfg, settingType CfgSettingType, max int,
+       allowDups bool) error {
+
+       // setting-name => entry
+       anyEntries := map[string]CfgEntry{}
+
+       // priority-value => entry
+       valEntries := map[int]CfgEntry{}
+
+       for name, entry := range cfg {
+               if entry.SettingType == settingType {
+                       if entry.Value == SYSCFG_PRIO_ANY {
+                               anyEntries[name] = entry
+                       } else {
+                               prio, err := util.AtoiNoOct(entry.Value)
+                               if err != nil {
+                                       return util.FmtNewtError(
+                                               "invalid priority value: 
setting=%s value=%s pkg=%s",
+                                               name, entry.Value, 
entry.History[0].Name())
+                               }
+
+                               if prio > max {
+                                       return util.FmtNewtError(
+                                               "invalid priority value: value 
too great (> %d); "+
+                                                       "setting=%s value=%s 
pkg=%s",
+                                               max, entry.Name, entry.Value,
+                                               mostRecentPoint(entry).Name())
+                               }
+
+                               if !allowDups {
+                                       if oldEntry, ok := valEntries[prio]; ok 
{
+                                               return util.FmtNewtError(
+                                                       "duplicate priority 
value: setting1=%s "+
+                                                               "setting2=%s 
pkg1=%s pkg2=%s value=%s",
+                                                       oldEntry.Name, 
entry.Name, entry.Value,
+                                                       
oldEntry.History[0].Name(),
+                                                       entry.History[0].Name())
+                                       }
+                               }
+
+                               valEntries[prio] = entry
+                       }
+               }
+       }
+
+       greatest := 0
+       for prio, _ := range valEntries {
+               if prio > greatest {
+                       greatest = prio
+               }
+       }
+
+       anyNames := make([]string, 0, len(anyEntries))
+       for name, _ := range anyEntries {
+               anyNames = append(anyNames, name)
+       }
+       sort.Strings(anyNames)
+
+       for _, name := range anyNames {
+               entry := anyEntries[name]
+
+               greatest++
+               if greatest > max {
+                       return util.FmtNewtError("could not assign 'any' 
priority: "+
+                               "value too great (> %d); setting=%s value=%s 
pkg=%s",
+                               max, name, greatest,
+                               mostRecentPoint(entry).Name())
+               }
+
+               entry.Value = strconv.Itoa(greatest)
+               cfg[name] = entry
+       }
+
+       return nil
+}
+
+func writeCheckMacros(w io.Writer) {
+       s := `/**
+ * These macros exists to ensure code includes this header when needed.  If
+ * code checks the existence of a setting directly via ifdef without including
+ * this header, the setting macro will silently evaluate to 0.  In contrast, an
+ * attempt to use these macros without including this header will result in a
+ * compiler error.
+ */
+#define MYNEWT_VAL(x)                           MYNEWT_VAL_ ## x
+#define MYNEWT_PKG(x)                           MYNEWT_PKG_ ## x
+#define MYNEWT_API(x)                           MYNEWT_API_ ## x
+`
+       fmt.Fprintf(w, "%s\n", s)
+}
+
+func writeComment(entry CfgEntry, w io.Writer) {
+       if len(entry.History) > 1 {
+               fmt.Fprintf(w, "/* Overridden by %s (defined by %s) */\n",
+                       mostRecentPoint(entry).Name(),
+                       entry.History[0].Name())
+       }
+}
+
+func writeDefine(key string, value string, w io.Writer) {
+       fmt.Fprintf(w, "#ifndef %s\n", key)
+       fmt.Fprintf(w, "#define %s (%s)\n", key, value)
+       fmt.Fprintf(w, "#endif\n")
+}
+
+func specialValues(cfg Cfg) (apis, pkgs, settings []string) {
+       for _, entry := range cfg {
+               if isApiVal(entry.Value) {
+                       apis = append(apis, entry.Value)
+               } else if isPkgVal(entry.Value) {
+                       pkgs = append(pkgs, entry.Value)
+               } else if isSettingVal(entry.Value) {
+                       settings = append(settings, entry.Value)
+               }
+       }
+
+       return
+}
+
+func buildCfgRoster(cfg Cfg, lpkgs []*pkg.LocalPackage,
+       apis []string) cfgRoster {
+
+       roster := cfgRoster{
+               settings:    make(map[string]string, len(cfg)),
+               pkgsPresent: make(map[string]bool, len(lpkgs)),
+               apisPresent: make(map[string]bool, len(apis)),
+       }
+
+       for k, v := range cfg {
+               roster.settings[settingName(k)] = v.Value
+       }
+
+       for _, v := range lpkgs {
+               roster.pkgsPresent[pkgPresentName(v.Name())] = true
+       }
+
+       for _, v := range apis {
+               roster.apisPresent[apiPresentName(v)] = true
+       }
+
+       apisNotPresent, pkgsNotPresent, _ := specialValues(cfg)
+
+       for _, v := range apisNotPresent {
+               _, ok := roster.apisPresent[v]
+               if !ok {
+                       roster.apisPresent[v] = false
+               }
+       }
+
+       for _, v := range pkgsNotPresent {
+               _, ok := roster.pkgsPresent[v]
+               if !ok {
+                       roster.pkgsPresent[v] = false
+               }
+       }
+
+       return roster
+}
+
+func settingValueToConstant(value string,
+       roster cfgRoster) (string, bool, error) {
+
+       seen := map[string]struct{}{}
+       curVal := value
+       for {
+               v, ok := roster.settings[curVal]
+               if ok {
+                       if _, ok := seen[v]; ok {
+                               return "", false, util.FmtNewtError("Syscfg 
cycle detected: "+
+                                       "%s <==> %s", value, v)
+                       }
+                       seen[v] = struct{}{}
+                       curVal = v
+               } else {
+                       break
+               }
+       }
+       if curVal != value {
+               return curVal, true, nil
+       }
+
+       v, ok := roster.apisPresent[value]
+       if ok {
+               if v {
+                       return "1", true, nil
+               } else {
+                       return "0", true, nil
+               }
+       }
+
+       v, ok = roster.pkgsPresent[value]
+       if ok {
+               if v {
+                       return "1", true, nil
+               } else {
+                       return "0", true, nil
+               }
+       }
+
+       return value, false, nil
+}
+
+func fixupSettings(cfg Cfg, roster cfgRoster) error {
+       for k, entry := range cfg {
+               value, changed, err := settingValueToConstant(entry.Value, 
roster)
+               if err != nil {
+                       return err
+               }
+
+               if changed {
+                       entry.Value = value
+                       cfg[k] = entry
+               }
+       }
+
+       return nil
+}
+
+func UnfixedValue(entry CfgEntry) string {
+       point := mostRecentPoint(entry)
+       return point.Value
+}
+
+func EntriesByPkg(cfg Cfg) map[string][]CfgEntry {
+       pkgEntries := map[string][]CfgEntry{}
+       for _, v := range cfg {
+               name := v.History[0].Name()
+               pkgEntries[name] = append(pkgEntries[name], v)
+       }
+       return pkgEntries
+}
+
+func writeSettingsOnePkg(cfg Cfg, pkgName string, pkgEntries []CfgEntry,
+       w io.Writer) {
+
+       fmt.Fprintf(w, "/*** %s */\n", pkgName)
+
+       names := make([]string, len(pkgEntries), len(pkgEntries))
+       for i, entry := range pkgEntries {
+               names[i] = entry.Name
+       }
+       sort.Strings(names)
+
+       first := true
+       for _, n := range names {
+               entry := cfg[n]
+               if entry.Value != "" {
+                       if first {
+                               first = false
+                       } else {
+                               fmt.Fprintf(w, "\n")
+                       }
+
+                       writeComment(entry, w)
+                       writeDefine(settingName(n), entry.Value, w)
+               }
+       }
+}
+
+func writeSettings(cfg Cfg, w io.Writer) {
+       // Group settings by package name so that the generated header file is
+       // easier to readOnce.
+       pkgEntries := EntriesByPkg(cfg)
+       for _, v := range cfg {
+               name := v.History[0].Name()
+               pkgEntries[name] = append(pkgEntries[name], v)
+       }
+
+       pkgNames := make([]string, 0, len(pkgEntries))
+       for name, _ := range pkgEntries {
+               pkgNames = append(pkgNames, name)
+       }
+       sort.Strings(pkgNames)
+
+       fmt.Fprintf(w, "/***** Settings */\n")
+
+       for _, name := range pkgNames {
+               fmt.Fprintf(w, "\n")
+               entries := pkgEntries[name]
+               writeSettingsOnePkg(cfg, name, entries, w)
+       }
+}
+
+func writePkgsPresent(roster cfgRoster, w io.Writer) {
+       present := make([]string, 0, len(roster.pkgsPresent))
+       notPresent := make([]string, 0, len(roster.pkgsPresent))
+       for k, v := range roster.pkgsPresent {
+               if v {
+                       present = append(present, k)
+               } else {
+                       notPresent = append(notPresent, k)
+               }
+       }
+
+       sort.Strings(present)
+       sort.Strings(notPresent)
+
+       fmt.Fprintf(w, "/*** Packages (present) */\n")
+       for _, symbol := range present {
+               fmt.Fprintf(w, "\n")
+               writeDefine(symbol, "1", w)
+       }
+
+       fmt.Fprintf(w, "\n")
+       fmt.Fprintf(w, "/*** Packages (not present)*/\n")
+       for _, symbol := range notPresent {
+               fmt.Fprintf(w, "\n")
+               writeDefine(symbol, "0", w)
+       }
+}
+
+func writeApisPresent(roster cfgRoster, w io.Writer) {
+       present := make([]string, 0, len(roster.apisPresent))
+       notPresent := make([]string, 0, len(roster.apisPresent))
+       for k, v := range roster.apisPresent {
+               if v {
+                       present = append(present, k)
+               } else {
+                       notPresent = append(notPresent, k)
+               }
+       }
+
+       sort.Strings(present)
+       sort.Strings(notPresent)
+
+       fmt.Fprintf(w, "/*** APIs (present) */\n")
+       for _, symbol := range present {
+               fmt.Fprintf(w, "\n")
+               writeDefine(symbol, "1", w)
+       }
+
+       fmt.Fprintf(w, "\n")
+       fmt.Fprintf(w, "/*** APIs (not present) */\n")
+       for _, symbol := range notPresent {
+               writeDefine(symbol, "0", w)
+               fmt.Fprintf(w, "\n")
+       }
+}
+
+func write(cfg Cfg, roster cfgRoster, w io.Writer) {
+       WritePreamble(w)
+
+       fmt.Fprintf(w, "#ifndef H_MYNEWT_SYSCFG_\n")
+       fmt.Fprintf(w, "#define H_MYNEWT_SYSCFG_\n\n")
+
+       writeCheckMacros(w)
+       fmt.Fprintf(w, "\n")
+
+       writeSettings(cfg, w)
+       fmt.Fprintf(w, "\n")
+
+       writePkgsPresent(roster, w)
+       fmt.Fprintf(w, "\n")
+
+       writeApisPresent(roster, w)
+       fmt.Fprintf(w, "\n")
+
+       fmt.Fprintf(w, "#endif\n")
+}
+
+func writeRequired(contents []byte, path string) (bool, error) {
+       oldHeader, err := ioutil.ReadFile(path)
+       if err != nil {
+               if os.IsNotExist(err) {
+                       // File doesn't exist; write required.
+                       return true, nil
+               }
+
+               return true, util.NewNewtError(err.Error())
+       }
+
+       rc := bytes.Compare(oldHeader, contents)
+       return rc != 0, nil
+}
+
+func headerPath(targetPath string) string {
+       return fmt.Sprintf("%s/%s/%s", targetPath, SYSCFG_INCLUDE_SUBDIR,
+               SYSCFG_HEADER_FILENAME)
+}
+
+func EnsureWritten(cfg Cfg, lpkgs []*pkg.LocalPackage,
+       apis []string, targetPath string) error {
+
+       if err := calcPriorities(cfg, CFG_SETTING_TYPE_TASK_PRIO,
+               SYSCFG_TASK_PRIO_MAX, false); err != nil {
+
+               return err
+       }
+
+       if err := calcPriorities(cfg, CFG_SETTING_TYPE_INTERRUPT_PRIO,
+               SYSCFG_INTERRUPT_PRIO_MAX, true); err != nil {
+
+               return err
+       }
+
+       roster := buildCfgRoster(cfg, lpkgs, apis)
+       if err := fixupSettings(cfg, roster); err != nil {
+               return err
+       }
+
+       buf := bytes.Buffer{}
+       write(cfg, roster, &buf)
+
+       path := headerPath(targetPath)
+
+       writeReqd, err := writeRequired(buf.Bytes(), path)
+       if err != nil {
+               return err
+       }
+       if !writeReqd {
+               log.Debugf("syscfg unchanged; not writing header file (%s).", 
path)
+               return nil
+       }
+
+       log.Debugf("syscfg changed; writing header file (%s).", path)
+
+       if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
+               return util.NewNewtError(err.Error())
+       }
+
+       if err := ioutil.WriteFile(path, buf.Bytes(), 0644); err != nil {
+               return util.NewNewtError(err.Error())
+       }
+
+       return nil
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/sysinit/sysinit.go
----------------------------------------------------------------------
diff --git a/newt/sysinit/sysinit.go b/newt/sysinit/sysinit.go
new file mode 100644
index 0000000..8e8188b
--- /dev/null
+++ b/newt/sysinit/sysinit.go
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 sysinit
+
+import (
+       "bytes"
+       "fmt"
+       "io"
+       "io/ioutil"
+       "os"
+       "path/filepath"
+       "sort"
+
+       log "github.com/Sirupsen/logrus"
+
+       "mynewt.apache.org/newt/newt/pkg"
+       "mynewt.apache.org/newt/newt/syscfg"
+       "mynewt.apache.org/newt/util"
+)
+
+const FILENAME = "sysinit.c"
+const SYSINIT_FN_SIG = `void
+sysinit(void)
+{
+`
+
+func buildStageMap(pkgs []*pkg.LocalPackage) map[int][]*pkg.LocalPackage {
+       sm := map[int][]*pkg.LocalPackage{}
+
+       for _, p := range pkgs {
+               stage := p.InitStage()
+               sm[stage] = append(sm[stage], p)
+       }
+
+       return sm
+}
+
+func writePrototypes(pkgs []*pkg.LocalPackage, w io.Writer) {
+       sorted := pkg.SortLclPkgs(pkgs)
+       for _, p := range sorted {
+               fmt.Fprintf(w, "void %s(void);\n", p.InitFnName())
+       }
+}
+
+func writeStage(stage int, pkgs []*pkg.LocalPackage, w io.Writer) {
+       sorted := pkg.SortLclPkgs(pkgs)
+
+       fmt.Fprintf(w, "    /*** Stage %d */\n", stage)
+       for i, p := range sorted {
+               fmt.Fprintf(w, "    /* %d.%d: %s */\n", stage, i, p.Name())
+               fmt.Fprintf(w, "    %s();\n", p.InitFnName())
+       }
+}
+
+func onlyPkgsWithInit(pkgs []*pkg.LocalPackage) []*pkg.LocalPackage {
+       good := make([]*pkg.LocalPackage, 0, len(pkgs))
+       for _, p := range pkgs {
+               if p.InitFnName() != "" {
+                       good = append(good, p)
+               }
+       }
+
+       return good
+}
+
+func write(pkgs []*pkg.LocalPackage, w io.Writer) {
+       goodPkgs := onlyPkgsWithInit(pkgs)
+       stageMap := buildStageMap(goodPkgs)
+
+       i := 0
+       stages := make([]int, len(stageMap))
+       for k, _ := range stageMap {
+               stages[i] = k
+               i++
+       }
+       sort.Ints(stages)
+
+       syscfg.WritePreamble(w)
+
+       writePrototypes(goodPkgs, w)
+       fmt.Fprintf(w, "\n")
+
+       fmt.Fprintf(w, "%s", SYSINIT_FN_SIG)
+       for i, s := range stages {
+               if i != 0 {
+                       fmt.Fprintf(w, "\n")
+               }
+
+               writeStage(s, stageMap[s], w)
+       }
+
+       fmt.Fprintf(w, "}\n")
+}
+
+func writeRequired(contents []byte, path string) (bool, error) {
+       oldSrc, err := ioutil.ReadFile(path)
+       if err != nil {
+               if os.IsNotExist(err) {
+                       // File doesn't exist; write required.
+                       return true, nil
+               }
+
+               return true, util.NewNewtError(err.Error())
+       }
+
+       rc := bytes.Compare(oldSrc, contents)
+       return rc != 0, nil
+}
+
+func EnsureWritten(pkgs []*pkg.LocalPackage, targetPath string) error {
+       buf := bytes.Buffer{}
+       write(pkgs, &buf)
+
+       path := fmt.Sprintf("%s/src/%s", targetPath, FILENAME)
+
+       writeReqd, err := writeRequired(buf.Bytes(), path)
+       if err != nil {
+               return err
+       }
+
+       if !writeReqd {
+               log.Debugf("sysinit unchanged; not writing src file (%s).", 
path)
+               return nil
+       }
+
+       log.Debugf("sysinit changed; writing src file (%s).", path)
+
+       if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
+               return util.NewNewtError(err.Error())
+       }
+
+       if err := ioutil.WriteFile(path, buf.Bytes(), 0644); err != nil {
+               return util.NewNewtError(err.Error())
+       }
+
+       return nil
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/toolchain/compiler.go
----------------------------------------------------------------------
diff --git a/newt/toolchain/compiler.go b/newt/toolchain/compiler.go
index b032d97..a961051 100644
--- a/newt/toolchain/compiler.go
+++ b/newt/toolchain/compiler.go
@@ -153,6 +153,10 @@ func addFlags(flagType string, orig []string, new 
[]string) []string {
        return combined
 }
 
+func (ci *CompilerInfo) AddCflags(cflags []string) {
+       ci.Cflags = addFlags("cflag", ci.Cflags, cflags)
+}
+
 func (ci *CompilerInfo) AddCompilerInfo(newCi *CompilerInfo) {
        ci.Includes = append(ci.Includes, newCi.Includes...)
        ci.Cflags = addFlags("cflag", ci.Cflags, newCi.Cflags)
@@ -168,7 +172,7 @@ func NewCompiler(compilerDir string, dstDir string,
        c := &Compiler{
                ObjPathList: map[string]bool{},
                dstDir:      filepath.Clean(dstDir),
-               extraDeps:   []string{compilerDir + COMPILER_FILENAME},
+               extraDeps:   []string{},
        }
 
        c.depTracker = NewDepTracker(c)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/toolchain/deps.go
----------------------------------------------------------------------
diff --git a/newt/toolchain/deps.go b/newt/toolchain/deps.go
index a50e265..e54c255 100644
--- a/newt/toolchain/deps.go
+++ b/newt/toolchain/deps.go
@@ -165,6 +165,7 @@ func (tracker *DepTracker) CompileRequired(srcFile string,
        if err != nil {
                return false, err
        }
+
        if commandHasChanged(objFile, cmd) {
                util.StatusMessage(util.VERBOSITY_VERBOSE, "%s - rebuild 
required; "+
                        "different command\n", srcFile)
@@ -175,6 +176,13 @@ func (tracker *DepTracker) CompileRequired(srcFile string,
                return true, nil
        }
 
+       if util.NodeNotExist(depFile) {
+               err := tracker.compiler.GenDepsForFile(srcFile)
+               if err != nil {
+                       return false, err
+               }
+       }
+
        srcModTime, err := util.FileModificationTime(srcFile)
        if err != nil {
                return false, err

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/vendor/mynewt.apache.org/newt/DISCLAIMER
----------------------------------------------------------------------
diff --git a/newt/vendor/mynewt.apache.org/newt/DISCLAIMER 
b/newt/vendor/mynewt.apache.org/newt/DISCLAIMER
deleted file mode 100644
index 1600825..0000000
--- a/newt/vendor/mynewt.apache.org/newt/DISCLAIMER
+++ /dev/null
@@ -1,8 +0,0 @@
-Apache Mynewt is an effort undergoing incubation at The Apache Software
-Foundation (ASF), sponsored by the Incubator PMC.  Incubation is
-required of all newly accepted projects until a further review indicates
-that the infrastructure, communications, and decision making process
-have stabilized in a manner consistent with other successful ASF
-projects. While incubation status is not necessarily a reflection of the
-completeness or stability of the code, it does indicate that the project
-has yet to be fully endorsed by the ASF.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/vendor/mynewt.apache.org/newt/LICENSE
----------------------------------------------------------------------
diff --git a/newt/vendor/mynewt.apache.org/newt/LICENSE 
b/newt/vendor/mynewt.apache.org/newt/LICENSE
deleted file mode 100644
index 88a6f68..0000000
--- a/newt/vendor/mynewt.apache.org/newt/LICENSE
+++ /dev/null
@@ -1,244 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "{}"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright {yyyy} {name of copyright owner}
-
-   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.
-
-This product bundles pretty, which is available under the MIT license.  For
-details, see newt/vendor/github.com/kr/pretty/License
-
-This product bundles kr/text, which is available under the MIT license.  For
-details, see newt/vendor/github.com/kr/text/License
-
-This product bundles mapstructure, which is available under the MIT license.
-For details, see newt/vendor/github.com/mitchellh/mapstructure/LICENSE
-
-This product bundles logrus, which is available under the MIT license.  For
-details, see newt/vendor/github.com/Sirupsen/logrus/LICENSE
-
-This product bundles Cast, which is available under the MIT license.  For
-details, see newt/vendor/github.com/spf13/cast/LICENSE
-
-This product bundles jWalterWeatherman, which is available under the MIT
-license.  For details, see
-newt/vendor/github.com/spf13/jwalterweatherman/LICENSE
-
-This product bundles pflag, which is available under the "3-clause BSD"
-license.  For details, see newt/vendor/github.com/spf13/pflag/LICENSE
-
-This product bundles the unix Go package, which is available under the
-"3-clause BSD" license.  For details, see newt/vendor/golang.org/x/sys/LICENSE
-
-This product bundles fsnotify.v1, which is available under the "3-clause BSD"
-license.  For details, see newt/vendor/gopkg.in/fsnotify.v1/LICENSE
-
-This product bundles yaml.v2's Go port of libyaml, which is available under the
-MIT license.  For details, see:
-    * yaml/apic.go
-    * yaml/emitterc.go
-    * yaml/parserc.go
-    * yaml/readerc.go
-    * yaml/scannerc.go
-    * yaml/writerc.go
-    * yaml/yamlh.go
-    * yaml/yamlprivateh.go
-
-This product bundles viper, which is available under the MIT license.  For
-details, see:
-    * viper/LICENSE

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/vendor/mynewt.apache.org/newt/NOTICE
----------------------------------------------------------------------
diff --git a/newt/vendor/mynewt.apache.org/newt/NOTICE 
b/newt/vendor/mynewt.apache.org/newt/NOTICE
deleted file mode 100644
index 94bea73..0000000
--- a/newt/vendor/mynewt.apache.org/newt/NOTICE
+++ /dev/null
@@ -1,8 +0,0 @@
-Apache Mynewt (incubating)
-Copyright 2015-2016 The Apache Software Foundation
-
-This product includes software developed at
-The Apache Software Foundation (http://www.apache.org/).
-
-Portions of this software were developed at
-Runtime Inc, copyright 2015.

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/0ae71ef1/newt/vendor/mynewt.apache.org/newt/util/util.go
----------------------------------------------------------------------
diff --git a/newt/vendor/mynewt.apache.org/newt/util/util.go 
b/newt/vendor/mynewt.apache.org/newt/util/util.go
index 27b407c..930c24e 100644
--- a/newt/vendor/mynewt.apache.org/newt/util/util.go
+++ b/newt/vendor/mynewt.apache.org/newt/util/util.go
@@ -32,6 +32,7 @@ import (
        "path/filepath"
        "runtime"
        "sort"
+       "strconv"
        "strings"
        "syscall"
        "time"
@@ -422,3 +423,23 @@ func SortFields(wsSepStrings ...string) []string {
        sort.Strings(slice)
        return slice
 }
+
+func AtoiNoOct(s string) (int, error) {
+       var runLen int
+       for runLen = 0; runLen < len(s)-1; runLen++ {
+               if s[runLen] != '0' || s[runLen+1] == 'x' {
+                       break
+               }
+       }
+
+       if runLen > 0 {
+               s = s[runLen:]
+       }
+
+       i, err := strconv.ParseInt(s, 0, 0)
+       if err != nil {
+               return 0, NewNewtError(err.Error())
+       }
+
+       return int(i), nil
+}


Reply via email to