You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/10/02 20:42:17 UTC
[1/2] incubator-mynewt-newt git commit: Syscfg / sysinit update
Repository: incubator-mynewt-newt
Updated Branches:
refs/heads/develop 23179e28e -> dd715c24b
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/pkg/localpackage.go
----------------------------------------------------------------------
diff --git a/newt/pkg/localpackage.go b/newt/pkg/localpackage.go
index 19cd3b1..755a477 100644
--- a/newt/pkg/localpackage.go
+++ b/newt/pkg/localpackage.go
@@ -70,8 +70,11 @@ type LocalPackage struct {
// example, SELFTEST gets set when the newt test command is used.
injectedSettings map[string]string
- // Pointer to pkg.yml configuration structure
- Viper *viper.Viper
+ // Settings read from pkg.yml.
+ PkgV *viper.Viper
+
+ // Settings read from syscfg.yml.
+ SyscfgV *viper.Viper
// Names of all source yml files; used to determine if rebuild required.
cfgFilenames []string
@@ -79,9 +82,9 @@ type LocalPackage struct {
func NewLocalPackage(r *repo.Repo, pkgDir string) *LocalPackage {
pkg := &LocalPackage{
- desc: &PackageDesc{},
- // XXX: Initialize viper object; clients should not need to check for
- // nil pointer.
+ desc: &PackageDesc{},
+ PkgV: viper.New(),
+ SyscfgV: viper.New(),
repo: r,
basePath: filepath.Clean(pkgDir) + "/", // XXX: Remove slash.
injectedSettings: map[string]string{},
@@ -194,8 +197,6 @@ func (pkg *LocalPackage) HasDep(searchDep *Dependency) bool {
}
func (pkg *LocalPackage) AddDep(dep *Dependency) {
- // Remember the name of the configuration file so that it can be specified
- // as a dependency to the compiler.
pkg.deps = append(pkg.deps, dep)
}
@@ -217,8 +218,8 @@ func (pkg *LocalPackage) readDesc(v *viper.Viper) (*PackageDesc, error) {
func (pkg *LocalPackage) sequenceString(key string) string {
var buffer bytes.Buffer
- if pkg.Viper != nil {
- for _, f := range pkg.Viper.GetStringSlice(key) {
+ if pkg.PkgV != nil {
+ for _, f := range pkg.PkgV.GetStringSlice(key) {
buffer.WriteString(" - " + yaml.EscapeString(f) + "\n")
}
}
@@ -276,17 +277,19 @@ func (pkg *LocalPackage) Load() error {
// Load configuration
log.Debugf("Loading configuration for package %s", pkg.basePath)
- v, err := util.ReadConfig(pkg.basePath,
+ var err error
+
+ pkg.PkgV, err = util.ReadConfig(pkg.basePath,
strings.TrimSuffix(PACKAGE_FILE_NAME, ".yml"))
if err != nil {
return err
}
- pkg.Viper = v
+ pkg.AddCfgFilename(pkg.basePath + PACKAGE_FILE_NAME)
// Set package name from the package
- pkg.name = v.GetString("pkg.name")
+ pkg.name = pkg.PkgV.GetString("pkg.name")
- typeString := v.GetString("pkg.type")
+ typeString := pkg.PkgV.GetString("pkg.type")
pkg.packageType = PACKAGE_TYPE_LIB
for t, n := range PackageTypeNames {
if typeString == n {
@@ -295,16 +298,24 @@ func (pkg *LocalPackage) Load() error {
}
}
- pkg.initFnName = v.GetString("pkg.init_function")
- pkg.initStage = v.GetInt("pkg.init_stage")
+ pkg.initFnName = pkg.PkgV.GetString("pkg.init_function")
+ pkg.initStage = pkg.PkgV.GetInt("pkg.init_stage")
// Read the package description from the file
- pkg.desc, err = pkg.readDesc(v)
+ pkg.desc, err = pkg.readDesc(pkg.PkgV)
if err != nil {
return err
}
- pkg.AddCfgFilename(pkg.basePath + PACKAGE_FILE_NAME)
+ // Load syscfg settings.
+ if util.NodeExist(pkg.basePath + "/" + SYSCFG_YAML_FILENAME) {
+ pkg.SyscfgV, err = util.ReadConfig(pkg.basePath,
+ strings.TrimSuffix(SYSCFG_YAML_FILENAME, ".yml"))
+ if err != nil {
+ return err
+ }
+ pkg.AddCfgFilename(pkg.basePath + SYSCFG_YAML_FILENAME)
+ }
return nil
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/pkg/package.go
----------------------------------------------------------------------
diff --git a/newt/pkg/package.go b/newt/pkg/package.go
index 644889e..b3b4d3b 100644
--- a/newt/pkg/package.go
+++ b/newt/pkg/package.go
@@ -22,6 +22,7 @@ package pkg
import "mynewt.apache.org/newt/newt/interfaces"
const PACKAGE_FILE_NAME = "pkg.yml"
+const SYSCFG_YAML_FILENAME = "syscfg.yml"
const (
PACKAGE_STABILITY_STABLE = "stable"
@@ -37,6 +38,7 @@ const (
PACKAGE_TYPE_LIB
PACKAGE_TYPE_TARGET
PACKAGE_TYPE_UNITTEST
+ PACKAGE_TYPE_GENERATED
)
var PackageTypeNames = map[interfaces.PackageType]string{
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/pkg/packageutil.go
----------------------------------------------------------------------
diff --git a/newt/pkg/packageutil.go b/newt/pkg/packageutil.go
index f3f6132..2cadc28 100644
--- a/newt/pkg/packageutil.go
+++ b/newt/pkg/packageutil.go
@@ -1,7 +1,10 @@
package pkg
import (
+ "path/filepath"
"sort"
+
+ "mynewt.apache.org/newt/newt/interfaces"
)
type lpkgSorter struct {
@@ -30,3 +33,7 @@ func SortLclPkgs(pkgs []*LocalPackage) []*LocalPackage {
sort.Sort(sorter)
return sorter.pkgs
}
+
+func ShortName(p interfaces.PackageInterface) string {
+ return filepath.Base(p.Name())
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/project/project.go
----------------------------------------------------------------------
diff --git a/newt/project/project.go b/newt/project/project.go
index 5099e6f..857bcfb 100644
--- a/newt/project/project.go
+++ b/newt/project/project.go
@@ -67,7 +67,6 @@ type Project struct {
func InitProject(dir string) error {
var err error
-
globalProject, err = LoadProject(dir)
if err != nil {
return err
@@ -79,30 +78,32 @@ func InitProject(dir string) error {
return nil
}
-func Initialize() error {
+func initialize() error {
if globalProject == nil {
wd, err := os.Getwd()
if err != nil {
return util.NewNewtError(err.Error())
}
- if err = InitProject(wd); err != nil {
+ if err := InitProject(wd); err != nil {
return err
}
}
return nil
}
-func GetProject() *Project {
+func TryGetProject() (*Project, error) {
if globalProject == nil {
- wd, err := os.Getwd()
- if err != nil {
- panic(err.Error())
- }
- err = InitProject(wd)
- if err != nil {
- return nil
+ if err := initialize(); err != nil {
+ return nil, err
}
}
+ return globalProject, nil
+}
+func GetProject() *Project {
+ if _, err := TryGetProject(); err != nil {
+ panic(err.Error())
+ }
+
return globalProject
}
@@ -111,6 +112,7 @@ func ResetProject() {
}
func ResetDeps(newList interfaces.PackageList) interfaces.PackageList {
+ return nil
if globalProject == nil {
return nil
}
@@ -514,6 +516,42 @@ func (proj *Project) ResolveDependency(dep interfaces.DependencyInterface) inter
return nil
}
+func (proj *Project) ResolvePackage(
+ dfltRepo interfaces.RepoInterface, name string) (*pkg.LocalPackage, error) {
+
+ // Trim trailing slash from name. This is necessary when tab
+ // completion is used to specify the name.
+ name = strings.TrimSuffix(name, "/")
+
+ repoName, pkgName, err := newtutil.ParsePackageString(name)
+ if err != nil {
+ return nil, util.FmtNewtError("invalid package name: %s (%s)", name,
+ err.Error())
+ }
+
+ var repo interfaces.RepoInterface
+ if repoName == "" {
+ repo = dfltRepo
+ } else {
+ repo = proj.repos[repoName]
+ }
+
+ dep, err := pkg.NewDependency(repo, pkgName)
+ if err != nil {
+ return nil, util.FmtNewtError("invalid package name: %s (%s)", name,
+ err.Error())
+ }
+ if dep == nil {
+ return nil, util.NewNewtError("invalid package name: " + name)
+ }
+ pack := proj.ResolveDependency(dep)
+ if pack == nil {
+ return nil, util.NewNewtError("unknown package: " + name)
+ }
+
+ return pack.(*pkg.LocalPackage), nil
+}
+
func findProjectDir(dir string) (string, error) {
for {
projFile := path.Clean(dir) + "/" + PROJECT_FILE_NAME
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/repo/repo.go
----------------------------------------------------------------------
diff --git a/newt/repo/repo.go b/newt/repo/repo.go
index a7b0253..7a5c654 100644
--- a/newt/repo/repo.go
+++ b/newt/repo/repo.go
@@ -92,7 +92,8 @@ func (repo *Repo) FilteredSearchList(curPath string) ([]string, error) {
dirList, err := ioutil.ReadDir(filepath.Join(repo.Path(), curPath))
if err != nil {
- return list, util.NewNewtError(err.Error())
+ return list, util.FmtNewtError("failed to read repo \"%s\": %s",
+ repo.Name(), err.Error())
}
for _, dirEnt := range dirList {
if !dirEnt.IsDir() {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/resolve/resolve.go
----------------------------------------------------------------------
diff --git a/newt/resolve/resolve.go b/newt/resolve/resolve.go
new file mode 100644
index 0000000..fc2f34c
--- /dev/null
+++ b/newt/resolve/resolve.go
@@ -0,0 +1,540 @@
+/**
+ * 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 resolve
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+
+ log "github.com/Sirupsen/logrus"
+
+ "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/util"
+)
+
+type Resolver struct {
+ apis map[string]*ResolvePackage
+ pkgMap map[*pkg.LocalPackage]*ResolvePackage
+ injectedSettings map[string]string
+ cfg syscfg.Cfg
+}
+
+type ResolvePackage struct {
+ *pkg.LocalPackage
+
+ // Keeps track of API requirements and whether they are satisfied.
+ reqApiMap map[string]bool
+
+ depsResolved bool
+ apisSatisfied bool
+}
+
+type CfgResolution struct {
+ Cfg syscfg.Cfg
+ ApiMap map[string]*pkg.LocalPackage
+ UnsatisfiedApis map[string][]*pkg.LocalPackage
+}
+
+func newResolver() *Resolver {
+ return &Resolver{
+ apis: map[string]*ResolvePackage{},
+ pkgMap: map[*pkg.LocalPackage]*ResolvePackage{},
+ injectedSettings: map[string]string{},
+ cfg: syscfg.NewCfg(),
+ }
+}
+
+func newResolvePkg(lpkg *pkg.LocalPackage) *ResolvePackage {
+ return &ResolvePackage{
+ LocalPackage: lpkg,
+ reqApiMap: map[string]bool{},
+ }
+}
+
+func newCfgResolution() CfgResolution {
+ return CfgResolution{
+ Cfg: syscfg.NewCfg(),
+ ApiMap: map[string]*pkg.LocalPackage{},
+ UnsatisfiedApis: map[string][]*pkg.LocalPackage{},
+ }
+}
+
+func (r *Resolver) lpkgSlice() []*pkg.LocalPackage {
+ lpkgs := make([]*pkg.LocalPackage, len(r.pkgMap))
+
+ i := 0
+ for lpkg, _ := range r.pkgMap {
+ lpkgs[i] = lpkg
+ i++
+ }
+
+ return lpkgs
+}
+
+func (r *Resolver) apiSlice() []string {
+ apis := make([]string, len(r.apis))
+
+ i := 0
+ for api, _ := range r.apis {
+ apis[i] = api
+ i++
+ }
+
+ return apis
+}
+
+func (r *Resolver) addPkg(lpkg *pkg.LocalPackage) *ResolvePackage {
+ rpkg := newResolvePkg(lpkg)
+ r.pkgMap[lpkg] = rpkg
+ return rpkg
+}
+
+// @return bool true if this is a new API.
+func (r *Resolver) addApi(apiString string, rpkg *ResolvePackage) bool {
+ curRpkg := r.apis[apiString]
+ if curRpkg == nil {
+ r.apis[apiString] = rpkg
+ return true
+ } else {
+ if curRpkg != rpkg {
+ util.StatusMessage(util.VERBOSITY_QUIET,
+ "Warning: API conflict: %s (%s <-> %s)\n", apiString,
+ curRpkg.Name(), rpkg.Name())
+ }
+ return false
+ }
+}
+
+// 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.
+func (r *Resolver) satisfyReqApi(rpkg *ResolvePackage, reqApi string) bool {
+ depRpkg := r.apis[reqApi]
+ if depRpkg == nil {
+ // Insert nil to indicate an unsatisfied API.
+ r.apis[reqApi] = nil
+ return false
+ }
+
+ dep := &pkg.Dependency{
+ Name: depRpkg.Name(),
+ Repo: depRpkg.Repo().Name(),
+ }
+ rpkg.reqApiMap[reqApi] = true
+
+ // This package now has a new unresolved dependency.
+ rpkg.depsResolved = false
+
+ log.Debugf("API requirement satisfied; pkg=%s API=(%s, %s)",
+ rpkg.Name(), reqApi, dep.String())
+
+ return true
+}
+
+// @return bool true if a new dependency was detected as a
+// result of satisfying an API for this
+// package.
+func (r *Resolver) satisfyApis(rpkg *ResolvePackage) bool {
+ // Assume all this package's APIs are satisfied and that no new
+ // dependencies will be detected.
+ rpkg.apisSatisfied = true
+ newDeps := false
+
+ features := r.cfg.FeaturesForLpkg(rpkg.LocalPackage)
+
+ // Determine if any of the package's API requirements can now be satisfied.
+ // If so, another full iteration is required.
+ reqApis := newtutil.GetStringSliceFeatures(rpkg.PkgV, features,
+ "pkg.req_apis")
+ for _, reqApi := range reqApis {
+ reqStatus := rpkg.reqApiMap[reqApi]
+ if !reqStatus {
+ apiSatisfied := r.satisfyReqApi(rpkg, reqApi)
+ if apiSatisfied {
+ // An API was satisfied; the package now has a new dependency
+ // that needs to be resolved.
+ newDeps = true
+ reqStatus = true
+ } else {
+ rpkg.reqApiMap[reqApi] = false
+ }
+ }
+ if reqStatus {
+ rpkg.apisSatisfied = false
+ }
+ }
+
+ return newDeps
+}
+
+// @return bool True if this this function changed the builder
+// state; another full iteration is required
+// in this case.
+// error non-nil on failure.
+func (r *Resolver) loadDepsForPkg(rpkg *ResolvePackage) (bool, error) {
+ proj := project.GetProject()
+ features := r.cfg.FeaturesForLpkg(rpkg.LocalPackage)
+
+ changed := false
+
+ newDeps := newtutil.GetStringSliceFeatures(rpkg.PkgV, features, "pkg.deps")
+ for _, newDepStr := range newDeps {
+ newDep, err := pkg.NewDependency(rpkg.Repo(), newDepStr)
+ if err != nil {
+ return false, err
+ }
+
+ lpkg, ok := proj.ResolveDependency(newDep).(*pkg.LocalPackage)
+ if !ok {
+ return false,
+ util.NewNewtError("Could not resolve package dependency " +
+ newDep.String())
+ }
+
+ if r.pkgMap[lpkg] == nil {
+ changed = true
+ r.addPkg(lpkg)
+ }
+ }
+
+ // Determine if this package supports any APIs that we haven't seen
+ // yet. If so, another full iteration is required.
+ apis := newtutil.GetStringSliceFeatures(rpkg.PkgV, features, "pkg.apis")
+ for _, api := range apis {
+ newApi := r.addApi(api, rpkg)
+ if newApi {
+ changed = true
+ }
+ }
+
+ return changed, nil
+}
+
+// Attempts to resolve all of a build package's dependencies, identities, APIs,
+// and required APIs. This function should be called repeatedly until the
+// package is fully resolved.
+//
+// If a dependency is resolved by this function, the new dependency needs to be
+// processed. The caller should attempt to resolve all packages again.
+//
+// If a new supported feature is detected by this function, all pacakges need
+// to be reprocessed from scratch. The caller should set all packages'
+// depsResolved and apisSatisfied variables to false and attempt to resolve
+// everything again.
+//
+// @return bool true if >=1 dependencies were resolved
+// bool true if >=1 new features were detected
+func (r *Resolver) resolvePkg(rpkg *ResolvePackage) (bool, error) {
+ var err error
+ newDeps := false
+
+ if !rpkg.depsResolved {
+ newDeps, err = r.loadDepsForPkg(rpkg)
+ if err != nil {
+ return false, err
+ }
+
+ rpkg.depsResolved = !newDeps
+ }
+
+ if !rpkg.apisSatisfied {
+ newApiDep := r.satisfyApis(rpkg)
+ if newApiDep {
+ newDeps = true
+ }
+ }
+
+ return newDeps, nil
+}
+
+// @return changed,err
+func (r *Resolver) reloadCfg() (bool, error) {
+ lpkgs := r.lpkgSlice()
+ apis := r.apiSlice()
+
+ // Determine which features have been detected so far. The feature map is
+ // required for reloading syscfg, as features may unlock additional
+ // settings.
+ features := r.cfg.Features()
+ cfg, err := syscfg.Read(lpkgs, apis, r.injectedSettings, features)
+ if err != nil {
+ return false, err
+ }
+
+ changed := false
+ for k, v := range cfg.Settings {
+ oldval, ok := r.cfg.Settings[k]
+ if !ok || len(oldval.History) != len(v.History) {
+ r.cfg = cfg
+ changed = true
+ }
+ }
+
+ return changed, nil
+}
+
+func (r *Resolver) loadDepsOnce() (bool, error) {
+ // Circularly resolve dependencies, APIs, and required APIs until no new
+ // ones exist.
+ newDeps := false
+ for {
+ reprocess := false
+ for _, rpkg := range r.pkgMap {
+ newDeps, err := r.resolvePkg(rpkg)
+ if err != nil {
+ return false, err
+ }
+
+ if newDeps {
+ // The new dependencies need to be processed. Iterate again
+ // after this iteration completes.
+ reprocess = true
+ }
+ }
+
+ if !reprocess {
+ break
+ }
+ }
+
+ return newDeps, nil
+}
+
+func (r *Resolver) loadDepsAndCfg() error {
+ if _, err := r.loadDepsOnce(); err != nil {
+ return err
+ }
+
+ for {
+ cfgChanged, err := r.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 _, rpkg := range r.pkgMap {
+ rpkg.depsResolved = false
+ rpkg.apisSatisfied = false
+ }
+ }
+
+ newDeps, err := r.loadDepsOnce()
+ if err != nil {
+ return err
+ }
+
+ if !newDeps && !cfgChanged {
+ break
+ }
+ }
+
+ // Log the final syscfg.
+ r.cfg.Log()
+
+ return nil
+}
+
+func pkgSliceUnion(left []*pkg.LocalPackage,
+ right []*pkg.LocalPackage) []*pkg.LocalPackage {
+
+ set := make(map[*pkg.LocalPackage]struct{}, len(left)+len(right))
+ for _, lpkg := range left {
+ set[lpkg] = struct{}{}
+ }
+ for _, lpkg := range right {
+ set[lpkg] = struct{}{}
+ }
+
+ result := []*pkg.LocalPackage{}
+ for lpkg := range set {
+ result = append(result, lpkg)
+ }
+
+ return result
+}
+
+func pkgSliceRemove(slice []*pkg.LocalPackage,
+ toRemove *pkg.LocalPackage) []*pkg.LocalPackage {
+
+ for i, lpkg := range slice {
+ if lpkg == toRemove {
+ return append(slice[:i], slice[i+1:]...)
+ }
+ }
+
+ return slice
+}
+
+func ResolvePkgs(cfgResolution CfgResolution,
+ seedPkgs []*pkg.LocalPackage) ([]*pkg.LocalPackage, error) {
+
+ r := newResolver()
+ r.cfg = cfgResolution.Cfg
+ for _, lpkg := range seedPkgs {
+ r.addPkg(lpkg)
+ }
+
+ if _, err := r.loadDepsOnce(); err != nil {
+ return nil, err
+ }
+
+ // Satisfy API requirements.
+ for _, rpkg := range r.pkgMap {
+ for api, _ := range rpkg.reqApiMap {
+ apiPkg := cfgResolution.ApiMap[api]
+ if apiPkg == nil {
+ return nil, util.FmtNewtError(
+ "Unsatisfied API at unexpected time: %s", api)
+ }
+
+ r.addPkg(apiPkg)
+ }
+ }
+
+ lpkgs := make([]*pkg.LocalPackage, len(r.pkgMap))
+ i := 0
+ for lpkg, _ := range r.pkgMap {
+ lpkgs[i] = lpkg
+ i++
+ }
+
+ return lpkgs, nil
+}
+
+func ResolveSplitPkgs(cfgResolution CfgResolution,
+ appLoaderPkg *pkg.LocalPackage,
+ appAppPkg *pkg.LocalPackage,
+ bspPkg *pkg.LocalPackage,
+ compilerPkg *pkg.LocalPackage,
+ targetPkg *pkg.LocalPackage) (
+
+ loaderPkgs []*pkg.LocalPackage,
+ appPkgs []*pkg.LocalPackage,
+ err error) {
+
+ if appLoaderPkg != nil {
+ loaderSeedPkgs := []*pkg.LocalPackage{
+ appLoaderPkg, bspPkg, compilerPkg, targetPkg}
+ loaderPkgs, err = ResolvePkgs(cfgResolution, loaderSeedPkgs)
+ if err != nil {
+ return
+ }
+ }
+
+ appSeedPkgs := []*pkg.LocalPackage{
+ appAppPkg, bspPkg, compilerPkg, targetPkg}
+ appPkgs, err = ResolvePkgs(cfgResolution, appSeedPkgs)
+ if err != nil {
+ return
+ }
+
+ // The app image needs to have access to all the loader packages except
+ // the loader app itself. This is required because the app sysinit
+ // function needs to initialize every package in the build.
+ if appLoaderPkg != nil {
+ appPkgs = pkgSliceUnion(appPkgs, loaderPkgs)
+ appPkgs = pkgSliceRemove(appPkgs, appLoaderPkg)
+ }
+
+ return
+}
+
+func ResolveCfg(seedPkgs []*pkg.LocalPackage,
+ injectedSettings map[string]string) (CfgResolution, error) {
+
+ resolution := newCfgResolution()
+
+ r := newResolver()
+ if injectedSettings == nil {
+ injectedSettings = map[string]string{}
+ }
+ r.injectedSettings = injectedSettings
+
+ for _, lpkg := range seedPkgs {
+ r.addPkg(lpkg)
+ }
+
+ if err := r.loadDepsAndCfg(); err != nil {
+ return resolution, err
+ }
+
+ resolution.Cfg = r.cfg
+ resolution.ApiMap = make(map[string]*pkg.LocalPackage, len(r.apis))
+ anyUnsatisfied := false
+ for api, rpkg := range r.apis {
+ if rpkg == nil {
+ anyUnsatisfied = true
+ } else {
+ resolution.ApiMap[api] = rpkg.LocalPackage
+ }
+ }
+
+ if anyUnsatisfied {
+ for lpkg, rpkg := range r.pkgMap {
+ for api, satisfied := range rpkg.reqApiMap {
+ if !satisfied {
+ slice := resolution.UnsatisfiedApis[api]
+ slice = append(slice, lpkg)
+ resolution.UnsatisfiedApis[api] = slice
+ }
+ }
+ }
+ }
+
+ return resolution, nil
+}
+
+func (cfgResolution *CfgResolution) ErrorText() string {
+ str := ""
+
+ if len(cfgResolution.UnsatisfiedApis) > 0 {
+ apiNames := make([]string, 0, len(cfgResolution.UnsatisfiedApis))
+ for api, _ := range cfgResolution.UnsatisfiedApis {
+ apiNames = append(apiNames, api)
+ }
+ sort.Strings(apiNames)
+
+ str += "Unsatisfied APIs detected:\n"
+ for _, api := range apiNames {
+ str += fmt.Sprintf(" * %s, required by: ", api)
+
+ pkgs := cfgResolution.UnsatisfiedApis[api]
+ pkgNames := make([]string, len(pkgs))
+ for i, lpkg := range pkgs {
+ pkgNames[i] = lpkg.Name()
+ }
+ sort.Strings(pkgNames)
+
+ str += strings.Join(pkgNames, ", ")
+ str += "\n"
+ }
+ }
+
+ str += cfgResolution.Cfg.ErrorText()
+
+ return strings.TrimSpace(str)
+}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/syscfg/syscfg.go
----------------------------------------------------------------------
diff --git a/newt/syscfg/syscfg.go b/newt/syscfg/syscfg.go
index 04241ec..2b6b0c4 100644
--- a/newt/syscfg/syscfg.go
+++ b/newt/syscfg/syscfg.go
@@ -39,11 +39,9 @@ import (
"mynewt.apache.org/newt/util"
)
-const SYSCFG_INCLUDE_SUBDIR = "include/syscfg"
+const SYSCFG_INCLUDE_SUBDIR = "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
@@ -74,40 +72,53 @@ type CfgPoint struct {
Source *pkg.LocalPackage
}
+type CfgRestriction struct {
+ ReqSetting string
+ ReqVal bool
+ BaseSetting string
+ BaseVal bool
+}
+
type CfgEntry struct {
- Name string
- Value string
- History []CfgPoint
- Description string
- SettingType CfgSettingType
+ Name string
+ Value string
+ Description string
+ SettingType CfgSettingType
+ Restrictions []CfgRestriction
+
+ History []CfgPoint
}
-type CfgRoster struct {
- settings map[string]string
- pkgsPresent map[string]bool
- apisPresent map[string]bool
+type CfgLateral struct {
+ PkgName string
+ SettingName string
}
type Cfg struct {
- Settings map[string]CfgEntry
- Roster CfgRoster
- Orphans map[string][]CfgPoint
- Ambiguities []CfgEntry
-}
+ Settings map[string]CfgEntry
-func newRoster() CfgRoster {
- return CfgRoster{
- settings: map[string]string{},
- pkgsPresent: map[string]bool{},
- apisPresent: map[string]bool{},
- }
+ //// Errors
+ // Overrides of undefined settings.
+ Orphans map[string][]CfgPoint
+
+ // Two packages of equal priority override a setting with different
+ // values; not overridden by higher priority package.
+ Ambiguities map[string][]CfgPoint
+
+ // Setting restrictions not met.
+ Violations map[string][]CfgRestriction
+
+ // Attempted override by bottom-priority packages (libraries).
+ Laterals []CfgLateral
}
func NewCfg() Cfg {
return Cfg{
- Settings: map[string]CfgEntry{},
- Roster: newRoster(),
- Orphans: map[string][]CfgPoint{},
+ Settings: map[string]CfgEntry{},
+ Orphans: map[string][]CfgPoint{},
+ Ambiguities: map[string][]CfgPoint{},
+ Violations: map[string][]CfgRestriction{},
+ Laterals: []CfgLateral{},
}
}
@@ -177,9 +188,24 @@ func (entry *CfgEntry) appendValue(lpkg *pkg.LocalPackage, value interface{}) {
entry.Value = strval
}
-func (entry *CfgEntry) ambiguousCount() int {
+func historyToString(history []CfgPoint) string {
+ str := "["
+ for i, _ := range history {
+ if i != 0 {
+ str += ", "
+ }
+ p := history[len(history)-i-1]
+ str += fmt.Sprintf("%s:%s", p.Name(), p.Value)
+ }
+ str += "]"
+
+ return str
+}
+
+func (entry *CfgEntry) ambiguities() []CfgPoint {
diffVals := false
- count := 0
+ var points []CfgPoint
+
for i := 1; i < len(entry.History)-1; i++ {
cur := entry.History[len(entry.History)-i-1]
next := entry.History[len(entry.History)-i]
@@ -200,42 +226,61 @@ func (entry *CfgEntry) ambiguousCount() int {
diffVals = true
}
- count++
- }
-
- // Account for final package that was skipped in loop.
- if count > 0 {
- count++
+ if len(points) == 0 {
+ points = append(points, cur)
+ }
+ points = append(points, next)
}
// If all values are identical, there is no ambiguity
if !diffVals {
- count = 0
+ points = nil
}
- return count
+ return points
}
-func (entry *CfgEntry) ambiguousText() string {
- count := entry.ambiguousCount()
- if count == 0 {
+func (entry *CfgEntry) ambiguityText() string {
+ points := entry.ambiguities()
+ if len(points) == 0 {
return ""
}
- str := fmt.Sprintf("%s [", entry.Name)
-
- for i := 0; i < count; i++ {
- cur := entry.History[len(entry.History)-i-1]
- if i != 0 {
+ str := fmt.Sprintf("Setting: %s, Packages: [", entry.Name)
+ for i, p := range points {
+ if i > 0 {
str += ", "
}
- str += fmt.Sprintf("%s:%s", cur.Name(), cur.Value)
+
+ str += p.Source.Name()
}
str += "]"
return str
}
+func (cfg *Cfg) violationText(entry CfgEntry, r CfgRestriction) string {
+ str := fmt.Sprintf("%s=%s ", entry.Name, entry.Value)
+
+ reqVal := ""
+ if r.ReqVal {
+ reqVal = "1"
+ } else {
+ reqVal = "0"
+ }
+
+ str += fmt.Sprintf("requires %s=%s, but %s", r.ReqSetting, reqVal,
+ r.ReqSetting)
+ reqEntry, ok := cfg.Settings[r.ReqSetting]
+ if !ok {
+ str += "undefined"
+ } else {
+ str += fmt.Sprintf("=%s", reqEntry.Value)
+ }
+
+ return str
+}
+
func FeatureToCflag(featureName string) string {
return fmt.Sprintf("-D%s=1", settingName(featureName))
}
@@ -244,6 +289,68 @@ func stringValue(val interface{}) string {
return strings.TrimSpace(cast.ToString(val))
}
+func parseRestrictionConsequent(field string) (string, bool) {
+ var val bool
+ var name string
+
+ if strings.HasPrefix(field, "!") {
+ val = false
+ name = strings.TrimPrefix(field, "!")
+ } else {
+ val = true
+ name = field
+ }
+
+ return name, val
+}
+
+// Parses a restriction expression.
+//
+// It would be better to have a real expression parser. For now, only very
+// simple expressions are supported. A restriction expression must be of the
+// following form:
+// [!]<req-setting> [if <base-val>]
+//
+// All setting values are interpreted as booleans. If a setting is "0", "",
+// or undefined, it is false; otherwise it is true.
+//
+// Examples:
+// # Can't enable this setting unless LOG_FCB is enabled.
+// pkg.restrictions:
+// LOG_FCB
+//
+// # Can't enable this setting unless LOG_FCB is disabled.
+// pkg.restrictions:
+// !LOG_FCB
+//
+// # Can't disable this setting unless LOG_FCB is enabled.
+// pkg.restrictions:
+// LOG_FCB if 0
+func readRestriction(baseSetting string, text string) (CfgRestriction, error) {
+ r := CfgRestriction{
+ BaseSetting: baseSetting,
+ }
+
+ fields := strings.Fields(text)
+ switch len(fields) {
+ case 1:
+ r.ReqSetting, r.ReqVal = parseRestrictionConsequent(fields[0])
+ r.BaseVal = true
+
+ case 3:
+ if fields[1] != "if" {
+ return r, util.FmtNewtError("invalid restriction: %s", text)
+ }
+ r.ReqSetting, r.ReqVal = parseRestrictionConsequent(fields[0])
+ r.BaseVal = ValueIsTrue(fields[2])
+
+ default:
+ return r, util.FmtNewtError("invalid restriction: %s", text)
+ }
+
+ return r, nil
+}
+
func readSetting(name string, lpkg *pkg.LocalPackage,
vals map[interface{}]interface{}) (CfgEntry, error) {
@@ -263,22 +370,32 @@ func readSetting(name string, lpkg *pkg.LocalPackage,
"setting %s specifies invalid type: %s", name, typename)
}
}
-
entry.appendValue(lpkg, entry.Value)
+ entry.Restrictions = []CfgRestriction{}
+ restrictionStrings := cast.ToStringSlice(vals["restrictions"])
+ for _, rstring := range restrictionStrings {
+ r, err := readRestriction(name, rstring)
+ if err != nil {
+ return entry,
+ util.PreNewtError(err, "error parsing setting %s", name)
+ }
+ entry.Restrictions = append(entry.Restrictions, r)
+ }
+
return entry, nil
}
func (cfg *Cfg) readDefsOnce(lpkg *pkg.LocalPackage,
features map[string]bool) error {
- v := lpkg.Viper
+ v := lpkg.SyscfgV
lfeatures := cfg.FeaturesForLpkg(lpkg)
for k, _ := range features {
lfeatures[k] = true
}
- settings := newtutil.GetStringMapFeatures(v, lfeatures, "pkg.syscfg_defs")
+ settings := newtutil.GetStringMapFeatures(v, lfeatures, "syscfg.defs")
if settings != nil {
for k, v := range settings {
vals := v.(map[interface{}]interface{})
@@ -301,15 +418,24 @@ func (cfg *Cfg) readDefsOnce(lpkg *pkg.LocalPackage,
func (cfg *Cfg) readValsOnce(lpkg *pkg.LocalPackage,
features map[string]bool) error {
- v := lpkg.Viper
+ v := lpkg.SyscfgV
lfeatures := cfg.FeaturesForLpkg(lpkg)
for k, _ := range features {
lfeatures[k] = true
}
- values := newtutil.GetStringMapFeatures(v, lfeatures, "pkg.syscfg_vals")
- if values != nil {
- for k, v := range values {
+
+ values := newtutil.GetStringMapFeatures(v, lfeatures, "syscfg.vals")
+ for k, v := range values {
+ if normalizePkgType(lpkg.Type()) == pkg.PACKAGE_TYPE_LIB {
+ // A library package is overriding a setting; this is disallowed.
+ // Overrides must come from a higher priority package.
+ lateral := CfgLateral{
+ PkgName: lpkg.Name(),
+ SettingName: k,
+ }
+ cfg.Laterals = append(cfg.Laterals, lateral)
+ } else {
entry, ok := cfg.Settings[k]
if ok {
entry.appendValue(lpkg, v)
@@ -321,7 +447,6 @@ func (cfg *Cfg) readValsOnce(lpkg *pkg.LocalPackage,
}
cfg.Orphans[k] = append(cfg.Orphans[k], orphan)
}
-
}
}
@@ -341,17 +466,8 @@ func (cfg *Cfg) Log() {
for _, k := range keys {
entry := cfg.Settings[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)
+ log.Debugf(" %s=%s %s", k, entry.Value,
+ historyToString(entry.History))
}
keys = make([]string, len(cfg.Orphans))
@@ -376,16 +492,93 @@ func (cfg *Cfg) Log() {
}
}
-func (cfg *Cfg) DetectErrors() error {
- if len(cfg.Ambiguities) == 0 {
- return nil
+func (cfg *Cfg) restrictionMet(r CfgRestriction) bool {
+ baseEntry := cfg.Settings[r.BaseSetting]
+ baseVal := baseEntry.IsTrue()
+
+ if baseVal != r.BaseVal {
+ // Restriction does not apply.
+ return true
}
- str := "Syscfg ambiguities detected:"
- for _, entry := range cfg.Ambiguities {
- str += "\n " + entry.ambiguousText()
+ reqEntry, ok := cfg.Settings[r.ReqSetting]
+ reqVal := ok && reqEntry.IsTrue()
+
+ return reqVal == r.ReqVal
+}
+
+func (cfg *Cfg) detectViolations() {
+ for _, entry := range cfg.Settings {
+ var ev []CfgRestriction
+ for _, r := range entry.Restrictions {
+ if !cfg.restrictionMet(r) {
+ ev = append(ev, r)
+ }
+ }
+
+ if ev != nil {
+ cfg.Violations[entry.Name] = ev
+ }
}
- return util.NewNewtError(str)
+}
+
+func (cfg *Cfg) ErrorText() string {
+ str := ""
+
+ interestingNames := map[string]struct{}{}
+
+ if len(cfg.Violations) > 0 {
+ str += "Syscfg restriction violations detected:\n"
+ for settingName, rslice := range cfg.Violations {
+ interestingNames[settingName] = struct{}{}
+
+ entry := cfg.Settings[settingName]
+ for _, r := range rslice {
+ interestingNames[r.ReqSetting] = struct{}{}
+ str += " " + cfg.violationText(entry, r) + "\n"
+ }
+ }
+ }
+
+ if len(cfg.Ambiguities) > 0 {
+ str += "Syscfg ambiguities detected:\n"
+
+ settingNames := make([]string, 0, len(cfg.Ambiguities))
+ for k, _ := range cfg.Ambiguities {
+ settingNames = append(settingNames, k)
+ }
+ sort.Strings(settingNames)
+
+ for _, name := range settingNames {
+ entry := cfg.Settings[name]
+ interestingNames[entry.Name] = struct{}{}
+ str += " " + entry.ambiguityText()
+ }
+ }
+
+ if len(cfg.Laterals) > 0 {
+ str += "Lateral overrides detected (bottom-priority packages " +
+ "cannot override settings):\n"
+ for _, lateral := range cfg.Laterals {
+ interestingNames[lateral.SettingName] = struct{}{}
+
+ str += fmt.Sprintf(" Package: %s, Setting: %s\n",
+ lateral.PkgName, lateral.SettingName)
+ }
+ }
+
+ if str == "" {
+ return ""
+ }
+
+ str += "\nSetting history:\n"
+ for name, _ := range interestingNames {
+ entry := cfg.Settings[name]
+ str += fmt.Sprintf(" %s: %s\n", name,
+ historyToString(entry.History))
+ }
+
+ return strings.TrimSpace(str)
}
func escapeStr(s string) string {
@@ -396,30 +589,10 @@ func escapeStr(s string) string {
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 normalizePkgType(typ interfaces.PackageType) interfaces.PackageType {
switch typ {
case pkg.PACKAGE_TYPE_TARGET:
@@ -435,7 +608,9 @@ func normalizePkgType(typ interfaces.PackageType) interfaces.PackageType {
}
}
-func categorizePkgs(lpkgs []*pkg.LocalPackage) map[interfaces.PackageType][]*pkg.LocalPackage {
+func categorizePkgs(
+ lpkgs []*pkg.LocalPackage) map[interfaces.PackageType][]*pkg.LocalPackage {
+
pmap := map[interfaces.PackageType][]*pkg.LocalPackage{
pkg.PACKAGE_TYPE_TARGET: []*pkg.LocalPackage{},
pkg.PACKAGE_TYPE_APP: []*pkg.LocalPackage{},
@@ -473,14 +648,12 @@ func (cfg *Cfg) readForPkgType(lpkgs []*pkg.LocalPackage,
return nil
}
-func detectAmbiguities(cfg Cfg) Cfg {
+func (cfg *Cfg) detectAmbiguities() {
for _, entry := range cfg.Settings {
- if entry.ambiguousCount() > 0 {
- cfg.Ambiguities = append(cfg.Ambiguities, entry)
+ if points := entry.ambiguities(); len(points) > 0 {
+ cfg.Ambiguities[entry.Name] = points
}
}
-
- return cfg
}
func Read(lpkgs []*pkg.LocalPackage, apis []string,
@@ -526,12 +699,8 @@ func Read(lpkgs []*pkg.LocalPackage, apis []string,
}
}
- cfg.buildCfgRoster(lpkgs, apis)
- if err := fixupSettings(cfg); err != nil {
- return cfg, err
- }
-
- cfg = detectAmbiguities(cfg)
+ cfg.detectAmbiguities()
+ cfg.detectViolations()
return cfg, nil
}
@@ -622,15 +791,13 @@ func calcPriorities(cfg Cfg, settingType CfgSettingType, max int,
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
+ * This macro 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)
}
@@ -644,125 +811,13 @@ func writeComment(entry CfgEntry, w io.Writer) {
}
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 (cfg *Cfg) specialValues() (apis, pkgs, settings []string) {
- for _, entry := range cfg.Settings {
- 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 (cfg *Cfg) buildCfgRoster(lpkgs []*pkg.LocalPackage, apis []string) {
- roster := CfgRoster{
- settings: make(map[string]string, len(cfg.Settings)),
- pkgsPresent: make(map[string]bool, len(lpkgs)),
- apisPresent: make(map[string]bool, len(apis)),
- }
-
- for k, v := range cfg.Settings {
- 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, _ := cfg.specialValues()
-
- 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
- }
- }
-
- cfg.Roster = 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) error {
- for k, entry := range cfg.Settings {
- value, changed, err := settingValueToConstant(entry.Value, cfg.Roster)
- if err != nil {
- return err
- }
-
- if changed {
- entry.Value = value
- cfg.Settings[k] = entry
- }
+ if value == "" {
+ fmt.Fprintf(w, "#undef %s\n", key)
+ } else {
+ fmt.Fprintf(w, "#ifndef %s\n", key)
+ fmt.Fprintf(w, "#define %s (%s)\n", key, value)
+ fmt.Fprintf(w, "#endif\n")
}
-
- return nil
-}
-
-func UnfixedValue(entry CfgEntry) string {
- point := mostRecentPoint(entry)
- return point.Value
}
func EntriesByPkg(cfg Cfg) map[string][]CfgEntry {
@@ -777,27 +832,29 @@ func EntriesByPkg(cfg Cfg) map[string][]CfgEntry {
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
}
+
+ if len(names) == 0 {
+ return
+ }
sort.Strings(names)
+ fmt.Fprintf(w, "/*** %s */\n", pkgName)
+
first := true
for _, n := range names {
entry := cfg.Settings[n]
- if entry.Value != "" {
- if first {
- first = false
- } else {
- fmt.Fprintf(w, "\n")
- }
-
- writeComment(entry, w)
- writeDefine(settingName(n), entry.Value, w)
+ if first {
+ first = false
+ } else {
+ fmt.Fprintf(w, "\n")
}
+
+ writeComment(entry, w)
+ writeDefine(settingName(n), entry.Value, w)
}
}
@@ -812,8 +869,6 @@ func writeSettings(cfg Cfg, w io.Writer) {
}
sort.Strings(pkgNames)
- fmt.Fprintf(w, "/***** Settings */\n")
-
for _, name := range pkgNames {
fmt.Fprintf(w, "\n")
entries := pkgEntries[name]
@@ -821,62 +876,6 @@ func writeSettings(cfg Cfg, w io.Writer) {
}
}
-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, w io.Writer) {
WritePreamble(w)
@@ -889,12 +888,6 @@ func write(cfg Cfg, w io.Writer) {
writeSettings(cfg, w)
fmt.Fprintf(w, "\n")
- writePkgsPresent(cfg.Roster, w)
- fmt.Fprintf(w, "\n")
-
- writeApisPresent(cfg.Roster, w)
- fmt.Fprintf(w, "\n")
-
fmt.Fprintf(w, "#endif\n")
}
@@ -913,14 +906,12 @@ func writeRequired(contents []byte, path string) (bool, error) {
return rc != 0, nil
}
-func headerPath(targetPath string) string {
- return fmt.Sprintf("%s/%s/%s", targetPath, SYSCFG_INCLUDE_SUBDIR,
+func headerPath(includeDir string) string {
+ return fmt.Sprintf("%s/%s/%s", includeDir, SYSCFG_INCLUDE_SUBDIR,
SYSCFG_HEADER_FILENAME)
}
-func EnsureWritten(cfg Cfg, lpkgs []*pkg.LocalPackage,
- apis []string, targetPath string) error {
-
+func EnsureWritten(cfg Cfg, includeDir string) error {
if err := calcPriorities(cfg, CFG_SETTING_TYPE_TASK_PRIO,
SYSCFG_TASK_PRIO_MAX, false); err != nil {
@@ -933,15 +924,10 @@ func EnsureWritten(cfg Cfg, lpkgs []*pkg.LocalPackage,
return err
}
- cfg.buildCfgRoster(lpkgs, apis)
- if err := fixupSettings(cfg); err != nil {
- return err
- }
-
buf := bytes.Buffer{}
write(cfg, &buf)
- path := headerPath(targetPath)
+ path := headerPath(includeDir)
writeReqd, err := writeRequired(buf.Bytes(), path)
if err != nil {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/sysinit/sysinit.go
----------------------------------------------------------------------
diff --git a/newt/sysinit/sysinit.go b/newt/sysinit/sysinit.go
index 8e8188b..5d6d392 100644
--- a/newt/sysinit/sysinit.go
+++ b/newt/sysinit/sysinit.go
@@ -35,12 +35,6 @@ import (
"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{}
@@ -54,6 +48,7 @@ func buildStageMap(pkgs []*pkg.LocalPackage) map[int][]*pkg.LocalPackage {
func writePrototypes(pkgs []*pkg.LocalPackage, w io.Writer) {
sorted := pkg.SortLclPkgs(pkgs)
+ fmt.Fprintf(w, "void os_init(void);\n")
for _, p := range sorted {
fmt.Fprintf(w, "void %s(void);\n", p.InitFnName())
}
@@ -80,7 +75,9 @@ func onlyPkgsWithInit(pkgs []*pkg.LocalPackage) []*pkg.LocalPackage {
return good
}
-func write(pkgs []*pkg.LocalPackage, w io.Writer) {
+func write(pkgs []*pkg.LocalPackage, isLoader bool,
+ w io.Writer) {
+
goodPkgs := onlyPkgsWithInit(pkgs)
stageMap := buildStageMap(goodPkgs)
@@ -94,19 +91,32 @@ func write(pkgs []*pkg.LocalPackage, w io.Writer) {
syscfg.WritePreamble(w)
+ if isLoader {
+ fmt.Fprintf(w, "#if SPLIT_LOADER\n\n")
+ } else {
+ fmt.Fprintf(w, "#if !SPLIT_LOADER\n\n")
+ }
+
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")
- }
+ var fnName string
+ if isLoader {
+ fnName = "sysinit_loader"
+ } else {
+ fnName = "sysinit_app"
+ }
+
+ fmt.Fprintf(w, "\n")
+ fmt.Fprintf(w, "void\n%s(void)\n{\n", fnName)
+ fmt.Fprintf(w, " os_init();\n")
+ for _, s := range stages {
+ fmt.Fprintf(w, "\n")
writeStage(s, stageMap[s], w)
}
- fmt.Fprintf(w, "}\n")
+ fmt.Fprintf(w, "}\n\n")
+ fmt.Fprintf(w, "#endif\n")
}
func writeRequired(contents []byte, path string) (bool, error) {
@@ -124,11 +134,18 @@ func writeRequired(contents []byte, path string) (bool, error) {
return rc != 0, nil
}
-func EnsureWritten(pkgs []*pkg.LocalPackage, targetPath string) error {
+func EnsureWritten(pkgs []*pkg.LocalPackage, srcDir string, targetName string,
+ isLoader bool) error {
+
buf := bytes.Buffer{}
- write(pkgs, &buf)
+ write(pkgs, isLoader, &buf)
- path := fmt.Sprintf("%s/src/%s", targetPath, FILENAME)
+ var path string
+ if isLoader {
+ path = fmt.Sprintf("%s/%s-sysinit-loader.c", srcDir, targetName)
+ } else {
+ path = fmt.Sprintf("%s/%s-sysinit-app.c", srcDir, targetName)
+ }
writeReqd, err := writeRequired(buf.Bytes(), path)
if err != nil {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/target/target.go
----------------------------------------------------------------------
diff --git a/newt/target/target.go b/newt/target/target.go
index eadfa60..00d3e72 100644
--- a/newt/target/target.go
+++ b/newt/target/target.go
@@ -122,7 +122,6 @@ func (target *Target) Validate(appRequired bool) error {
return util.NewNewtError("Target does not specify an app " +
"package (target.app)")
}
-
app := target.resolvePackageName(target.AppName)
if app == nil {
return util.FmtNewtError("Could not resolve app package: %s",
@@ -134,6 +133,21 @@ func (target *Target) Validate(appRequired bool) error {
"type app; type is: %s\n", app.Name(),
pkg.PackageTypeNames[app.Type()])
}
+
+ if target.LoaderName != "" {
+ loader := target.resolvePackageName(target.LoaderName)
+ if loader == nil {
+ return util.FmtNewtError(
+ "Could not resolve loader package: %s", target.LoaderName)
+ }
+
+ if loader.Type() != pkg.PACKAGE_TYPE_APP {
+ return util.FmtNewtError(
+ "target.loader package (%s) is not of type app; type "+
+ "is: %s\n", loader.Name(),
+ pkg.PackageTypeNames[loader.Type()])
+ }
+ }
}
return nil
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/toolchain/compiler.go
----------------------------------------------------------------------
diff --git a/newt/toolchain/compiler.go b/newt/toolchain/compiler.go
index a961051..c2cfa7d 100644
--- a/newt/toolchain/compiler.go
+++ b/newt/toolchain/compiler.go
@@ -254,9 +254,6 @@ func (c *Compiler) load(compilerDir string, buildProfile string) error {
buildProfile, runtime.GOOS)
}
- log.Infof("ccPath = %s, arPath = %s, flags = %s", c.ccPath,
- c.arPath, c.info.Cflags)
-
return nil
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/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 930c24e..ad517cd 100644
--- a/newt/vendor/mynewt.apache.org/newt/util/util.go
+++ b/newt/vendor/mynewt.apache.org/newt/util/util.go
@@ -82,6 +82,13 @@ func FmtNewtError(format string, args ...interface{}) *NewtError {
return NewNewtError(fmt.Sprintf(format, args...))
}
+func PreNewtError(err error, format string, args ...interface{}) *NewtError {
+ baseErr := err.(*NewtError)
+ baseErr.Text = fmt.Sprintf(format, args...) + "; " + baseErr.Text
+
+ return baseErr
+}
+
// Print Silent, Quiet and Verbose aware status messages to stdout.
func StatusMessage(level int, message string, args ...interface{}) {
if Verbosity >= level {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/util/util.go
----------------------------------------------------------------------
diff --git a/util/util.go b/util/util.go
index 27b407c..ad517cd 100644
--- a/util/util.go
+++ b/util/util.go
@@ -32,6 +32,7 @@ import (
"path/filepath"
"runtime"
"sort"
+ "strconv"
"strings"
"syscall"
"time"
@@ -81,6 +82,13 @@ func FmtNewtError(format string, args ...interface{}) *NewtError {
return NewNewtError(fmt.Sprintf(format, args...))
}
+func PreNewtError(err error, format string, args ...interface{}) *NewtError {
+ baseErr := err.(*NewtError)
+ baseErr.Text = fmt.Sprintf(format, args...) + "; " + baseErr.Text
+
+ return baseErr
+}
+
// Print Silent, Quiet and Verbose aware status messages to stdout.
func StatusMessage(level int, message string, args ...interface{}) {
if Verbosity >= level {
@@ -422,3 +430,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
+}
[2/2] incubator-mynewt-newt git commit: Syscfg / sysinit update
Posted by cc...@apache.org.
Syscfg / sysinit update
* Move syscfg from pkg.yml to syscfg.yml.
* Fix for split images.
* Don't allow lateral overrides by library packages.
* System initialization is done via sysinit() now, not os_init().
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/dd715c24
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/dd715c24
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/dd715c24
Branch: refs/heads/develop
Commit: dd715c24b20d18fd77e52c02cab1a9f860ed329f
Parents: 23179e2
Author: Christopher Collins <cc...@apache.org>
Authored: Wed Sep 28 16:29:24 2016 -0700
Committer: Christopher Collins <cc...@apache.org>
Committed: Sun Oct 2 13:39:41 2016 -0700
----------------------------------------------------------------------
newt/builder/build.go | 359 ++++-------
newt/builder/buildpackage.go | 254 +++-----
newt/builder/buildutil.go | 120 ++--
newt/builder/library.go | 9 +-
newt/builder/load.go | 43 +-
newt/builder/size.go | 16 +-
newt/builder/targetbuild.go | 418 +++++++------
newt/cli/build_cmds.go | 98 ++-
newt/cli/complete_cmd.go | 3 +-
newt/cli/image_cmds.go | 37 +-
newt/cli/project_cmds.go | 21 +-
newt/cli/run_cmds.go | 52 +-
newt/cli/target_cmds.go | 71 ++-
newt/cli/util.go | 21 -
newt/cli/vars.go | 7 +-
newt/image/image.go | 4 +-
newt/newt.go | 7 +-
newt/pkg/bsp_package.go | 12 +-
newt/pkg/localpackage.go | 45 +-
newt/pkg/package.go | 2 +
newt/pkg/packageutil.go | 7 +
newt/project/project.go | 60 +-
newt/repo/repo.go | 3 +-
newt/resolve/resolve.go | 540 ++++++++++++++++
newt/syscfg/syscfg.go | 610 +++++++++----------
newt/sysinit/sysinit.go | 51 +-
newt/target/target.go | 16 +-
newt/toolchain/compiler.go | 3 -
newt/vendor/mynewt.apache.org/newt/util/util.go | 7 +
util/util.go | 28 +
30 files changed, 1701 insertions(+), 1223 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/builder/build.go
----------------------------------------------------------------------
diff --git a/newt/builder/build.go b/newt/builder/build.go
index 271372c..5d57153 100644
--- a/newt/builder/build.go
+++ b/newt/builder/build.go
@@ -23,191 +23,123 @@ import (
"fmt"
"os"
"path/filepath"
- "regexp"
- "strings"
log "github.com/Sirupsen/logrus"
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/project"
+ "mynewt.apache.org/newt/newt/repo"
"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"
)
type Builder struct {
- Packages map[*pkg.LocalPackage]*BuildPackage
- apis map[string]*BuildPackage
+ PkgMap map[*pkg.LocalPackage]*BuildPackage
+
+ apiMap map[string]*BuildPackage
appPkg *BuildPackage
- BspPkg *pkg.LocalPackage
+ bspPkg *BuildPackage
+ compilerPkg *BuildPackage
+ targetPkg *BuildPackage
compilerInfo *toolchain.CompilerInfo
- target *TargetBuilder
+ targetBuilder *TargetBuilder
+ cfg syscfg.Cfg
linkerScript string
buildName string
- LinkElf string
+ linkElf string
injectedSettings map[string]string
-
- Cfg syscfg.Cfg
}
-func NewBuilder(t *TargetBuilder, buildName string) (*Builder, error) {
+func NewBuilder(t *TargetBuilder, buildName string, lpkgs []*pkg.LocalPackage,
+ apiMap map[string]*pkg.LocalPackage, cfg syscfg.Cfg) (*Builder, error) {
+
b := &Builder{
- Packages: map[*pkg.LocalPackage]*BuildPackage{},
+ PkgMap: make(map[*pkg.LocalPackage]*BuildPackage, len(lpkgs)),
+ cfg: cfg,
+
buildName: buildName,
- apis: map[string]*BuildPackage{},
- LinkElf: "",
- target: t,
+ apiMap: make(map[string]*BuildPackage, len(apiMap)),
+ linkElf: "",
+ targetBuilder: t,
injectedSettings: map[string]string{},
- Cfg: syscfg.NewCfg(),
}
- return b, nil
-}
-
-func (b *Builder) AddPackage(npkg *pkg.LocalPackage) *BuildPackage {
- // Don't allow nil entries to the map
- if npkg == nil {
- panic("Cannot add nil package builder map")
+ for _, lpkg := range lpkgs {
+ if _, err := b.addPackage(lpkg); err != nil {
+ return nil, err
+ }
}
- bpkg := b.Packages[npkg]
- if bpkg == nil {
- bpkg = NewBuildPackage(npkg)
- b.Packages[npkg] = bpkg
+ // Create a pseudo build package for the generated sysinit code.
+ if _, err := b.addSysinitBpkg(); err != nil {
+ return nil, err
}
- return bpkg
-}
-
-// @return bool true if this is a new API.
-func (b *Builder) AddApi(apiString string, bpkg *BuildPackage) bool {
- curBpkg := b.apis[apiString]
- if curBpkg == nil {
- b.apis[apiString] = bpkg
- return true
- } else {
- if curBpkg != bpkg {
- util.StatusMessage(util.VERBOSITY_QUIET,
- "Warning: API conflict: %s (%s <-> %s)\n", apiString,
- curBpkg.Name(), bpkg.Name())
+ for api, lpkg := range apiMap {
+ bpkg := b.PkgMap[lpkg]
+ if bpkg == nil {
+ for _, lpkg := range b.sortedLocalPackages() {
+ log.Debugf(" * %s", lpkg.Name())
+ }
+ return nil, util.FmtNewtError(
+ "Unexpected unsatisfied API: %s; required by: %s", api,
+ lpkg.Name())
}
- return false
- }
-}
-
-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
+ b.apiMap[api] = bpkg
}
- return apiNames
+ return b, nil
}
-// @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++
- }
-
- // Determine which features have been detected so far. The feature map is
- // required for reloading syscfg, as features may unlock additional
- // settings.
- features := b.Cfg.Features()
- cfg, err := syscfg.Read(b.sortedLocalPackages(), apis, b.injectedSettings,
- features)
- if err != nil {
- return false, err
- }
-
- changed := false
- for k, v := range cfg.Settings {
- oldval, ok := b.Cfg.Settings[k]
- if !ok || len(oldval.History) != len(v.History) {
- b.Cfg = cfg
- changed = true
- }
+func (b *Builder) addPackage(npkg *pkg.LocalPackage) (*BuildPackage, error) {
+ // Don't allow nil entries to the map
+ if npkg == nil {
+ panic("Cannot add nil package builder map")
}
- return changed, nil
-}
+ bpkg := b.PkgMap[npkg]
+ if bpkg == nil {
+ bpkg = NewBuildPackage(npkg)
-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, err := bpkg.Resolve(b, b.Cfg)
- if err != nil {
- return false, err
+ switch bpkg.Type() {
+ case pkg.PACKAGE_TYPE_APP:
+ if b.appPkg != nil {
+ return nil, pkgTypeConflictErr(b.appPkg, bpkg)
}
+ b.appPkg = bpkg
- if newDeps {
- // The new dependencies need to be processed. Iterate again
- // after this iteration completes.
- reprocess = true
+ case pkg.PACKAGE_TYPE_BSP:
+ if b.bspPkg != nil {
+ return nil, pkgTypeConflictErr(b.bspPkg, bpkg)
}
- }
-
- if !reprocess {
- break
- }
- }
-
- return newDeps, nil
-}
-
-func (b *Builder) loadDeps() error {
- if _, err := b.loadDepsOnce(); err != nil {
- return err
- }
+ b.bspPkg = bpkg
- 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
+ case pkg.PACKAGE_TYPE_COMPILER:
+ if b.compilerPkg != nil {
+ return nil, pkgTypeConflictErr(b.compilerPkg, bpkg)
}
- }
+ b.compilerPkg = bpkg
- newDeps, err := b.loadDepsOnce()
- if err != nil {
- return err
+ case pkg.PACKAGE_TYPE_TARGET:
+ if b.targetPkg != nil {
+ return nil, pkgTypeConflictErr(b.targetPkg, bpkg)
+ }
+ b.targetPkg = bpkg
}
- if !newDeps && !cfgChanged {
- break
- }
+ b.PkgMap[npkg] = bpkg
}
- // Log the final syscfg.
- b.Cfg.Log()
-
- // Report syscfg errors.
- if err := b.Cfg.DetectErrors(); err != nil {
- return err
- }
+ return bpkg, nil
+}
- return nil
+func pkgTypeConflictErr(p1 *BuildPackage, p2 *BuildPackage) error {
+ return util.FmtNewtError("Two %s packages in build: %s, %s",
+ pkg.PackageTypeNames[p1.Type()], p1.Name(), p2.Name())
}
// Recursively compiles all the .c and .s files in the specified directory.
@@ -267,7 +199,7 @@ func buildDir(srcDir string, c *toolchain.Compiler, arch string,
func (b *Builder) newCompiler(bpkg *BuildPackage,
dstDir string) (*toolchain.Compiler, error) {
- c, err := b.target.NewCompiler(dstDir)
+ c, err := b.targetBuilder.NewCompiler(dstDir)
if err != nil {
return nil, err
}
@@ -288,7 +220,7 @@ func (b *Builder) newCompiler(bpkg *BuildPackage,
// Compiles and archives a package.
func (b *Builder) buildPackage(bpkg *BuildPackage) error {
- c, err := b.newCompiler(bpkg, b.PkgBinDir(bpkg.Name()))
+ c, err := b.newCompiler(bpkg, b.PkgBinDir(bpkg))
if err != nil {
return err
}
@@ -316,7 +248,7 @@ func (b *Builder) buildPackage(bpkg *BuildPackage) error {
}
for _, dir := range srcDirs {
- if err = buildDir(dir, c, b.target.Bsp.Arch, nil); err != nil {
+ if err = buildDir(dir, c, b.targetBuilder.bspPkg.Arch, nil); err != nil {
return err
}
}
@@ -325,7 +257,7 @@ func (b *Builder) buildPackage(bpkg *BuildPackage) error {
if err := os.Chdir(bpkg.BasePath() + "/"); err != nil {
return util.NewNewtError(err.Error())
}
- archiveFile := b.ArchivePath(bpkg.Name())
+ archiveFile := b.ArchivePath(bpkg)
if err = c.CompileArchive(archiveFile); err != nil {
return err
}
@@ -334,11 +266,10 @@ func (b *Builder) buildPackage(bpkg *BuildPackage) error {
}
func (b *Builder) RemovePackages(cmn map[string]bool) error {
-
for pkgName, _ := range cmn {
- for lp, bpkg := range b.Packages {
+ for lp, bpkg := range b.PkgMap {
if bpkg.Name() == pkgName {
- delete(b.Packages, lp)
+ delete(b.PkgMap, lp)
}
}
}
@@ -347,7 +278,7 @@ func (b *Builder) RemovePackages(cmn map[string]bool) error {
func (b *Builder) ExtractSymbolInfo() (error, *symbol.SymbolMap) {
syms := symbol.NewSymbolMap()
- for _, bpkg := range b.Packages {
+ for _, bpkg := range b.PkgMap {
err, sm := b.ParseObjectLibrary(bpkg)
if err == nil {
syms, err = (*syms).Merge(sm)
@@ -361,24 +292,28 @@ func (b *Builder) ExtractSymbolInfo() (error, *symbol.SymbolMap) {
func (b *Builder) link(elfName string, linkerScript string,
keepSymbols []string) error {
- c, err := b.newCompiler(b.appPkg, b.PkgBinDir(elfName))
+
+ c, err := b.newCompiler(b.appPkg, b.FileBinDir(elfName))
if err != nil {
return err
}
- /* always used the trimmed archive files */
+ /* Always used the trimmed archive files. */
pkgNames := []string{}
- for _, bpkg := range b.Packages {
- if util.NodeExist(b.ArchivePath(bpkg.Name())) {
- pkgNames = append(pkgNames, b.ArchivePath(bpkg.Name()))
+ for _, bpkg := range b.PkgMap {
+ if util.NodeExist(b.ArchivePath(bpkg)) {
+ pkgNames = append(pkgNames, b.ArchivePath(bpkg))
}
}
+ // Include sysinit archive in elf file. */
+ //pkgNames = append(pkgNames, SysinitArchivePath(b.targetPkg.Name()))
+
if linkerScript != "" {
- c.LinkerScript = b.target.Bsp.BasePath() + "/" + linkerScript
+ c.LinkerScript = b.bspPkg.BasePath() + "/" + linkerScript
}
- err = c.CompileElf(elfName, pkgNames, keepSymbols, b.LinkElf)
+ err = c.CompileElf(elfName, pkgNames, keepSymbols, b.linkElf)
if err != nil {
return err
}
@@ -389,43 +324,16 @@ func (b *Builder) link(elfName string, linkerScript string,
// Populates the builder with all the packages that need to be built and
// configures each package's build settings. After this function executes,
// packages are ready to be built.
-func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
- bspPkg *pkg.LocalPackage, targetPkg *pkg.LocalPackage) error {
-
- // Seed the builder with the app (if present), bsp, and target packages.
-
- b.BspPkg = bspPkg
-
- var appBpkg *BuildPackage
- if appPkg != nil {
- appBpkg = b.Packages[appPkg]
- if appBpkg == nil {
- appBpkg = b.AddPackage(appPkg)
+func (b *Builder) PrepBuild() error {
+ // Populate the full set of packages to be built.
+ for _, bpkg := range b.PkgMap {
+ if err := bpkg.resolveDeps(b.cfg, b.apiMap); err != nil {
+ return err
}
- b.appPkg = appBpkg
- }
-
- bspBpkg := b.Packages[bspPkg]
-
- if bspBpkg == nil {
- bspBpkg = b.AddPackage(bspPkg)
- }
-
- targetBpkg := b.AddPackage(targetPkg)
-
- // Populate the full set of packages to be built and resolve the feature
- // set.
- if err := b.loadDeps(); err != nil {
- return err
}
b.logDepInfo()
- // Terminate if any package has an unmet API requirement.
- if err := b.verifyApisSatisfied(); err != nil {
- return err
- }
-
// Populate the base set of compiler flags. Flags from the following
// packages get applied to every source file:
// * target
@@ -446,17 +354,17 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
// Target flags.
log.Debugf("Generating build flags for target %s",
- b.target.target.FullName())
- targetCi, err := targetBpkg.CompilerInfo(b)
+ b.targetPkg.FullName())
+ targetCi, err := b.targetPkg.CompilerInfo(b)
if err != nil {
return err
}
baseCi.AddCompilerInfo(targetCi)
// App flags.
- if appBpkg != nil {
- log.Debugf("Generating build flags for app %s", appPkg.FullName())
- appCi, err := appBpkg.CompilerInfo(b)
+ if b.appPkg != nil {
+ log.Debugf("Generating build flags for app %s", b.appPkg.FullName())
+ appCi, err := b.appPkg.CompilerInfo(b)
if err != nil {
return err
}
@@ -465,71 +373,51 @@ func (b *Builder) PrepBuild(appPkg *pkg.LocalPackage,
}
// Bsp flags.
- log.Debugf("Generating build flags for bsp %s", bspPkg.FullName())
- bspCi, err := bspBpkg.CompilerInfo(b)
+ log.Debugf("Generating build flags for bsp %s", b.bspPkg.FullName())
+ bspCi, err := b.bspPkg.CompilerInfo(b)
if err != nil {
return err
}
// Define a cpp symbol indicating the BSP architecture, name of the
// BSP and app.
- bspCi.Cflags = append(bspCi.Cflags, "-DARCH_"+b.target.Bsp.Arch)
+ bspCi.Cflags = append(bspCi.Cflags, "-DARCH_"+b.targetBuilder.bspPkg.Arch)
bspCi.Cflags = append(bspCi.Cflags,
- "-DBSP_NAME=\""+filepath.Base(b.target.Bsp.Name())+"\"")
- if appPkg != nil {
+ "-DBSP_NAME=\""+filepath.Base(b.bspPkg.Name())+"\"")
+ if b.appPkg != nil {
bspCi.Cflags = append(bspCi.Cflags,
- "-DAPP_NAME=\""+filepath.Base(appPkg.Name())+"\"")
+ "-DAPP_NAME=\""+filepath.Base(b.appPkg.Name())+"\"")
}
baseCi.AddCompilerInfo(bspCi)
+ // All packages have access to the generated syscfg header directory.
+ baseCi.Cflags = append(baseCi.Cflags,
+ "-I"+GeneratedIncludeDir(b.targetPkg.Name()))
+
// Note: Compiler flags get added at the end, after the flags for library
// 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
}
-func (b *Builder) matchFeature(flist []map[string]interface{},
- pkg pkg.Package, featureName string) bool {
-
- fullName := ""
- if pkg != nil {
- fullName = pkg.FullName()
- }
-
- for _, matchList := range flist {
- for pkgDesc, featureDesc := range matchList {
- re, _ := regexp.Compile(pkgDesc)
- if re.MatchString(fullName) {
- if strings.Compare(featureDesc.(string), featureName) == 0 {
- return true
- }
- }
- }
- }
-
- return false
-}
-
func (b *Builder) AddCompilerInfo(info *toolchain.CompilerInfo) {
b.compilerInfo.AddCompilerInfo(info)
}
+func (b *Builder) addSysinitBpkg() (*BuildPackage, error) {
+ lpkg := pkg.NewLocalPackage(b.targetPkg.Repo().(*repo.Repo),
+ GeneratedBaseDir(b.targetPkg.Name()))
+ lpkg.SetName(pkg.ShortName(b.targetPkg) + "-sysinit-" + b.buildName)
+ lpkg.SetType(pkg.PACKAGE_TYPE_GENERATED)
+
+ return b.addPackage(lpkg)
+}
+
func (b *Builder) Build() error {
// Build the packages alphabetically to ensure a consistent order.
bpkgs := b.sortedBuildPackages()
+
for _, bpkg := range bpkgs {
if err := b.buildPackage(bpkg); err != nil {
return err
@@ -568,7 +456,7 @@ func (b *Builder) TestLink(linkerScript string) error {
}
func (b *Builder) pkgWithPath(path string) *BuildPackage {
- for _, p := range b.Packages {
+ for _, p := range b.PkgMap {
if p.BasePath() == path {
return p
}
@@ -608,7 +496,8 @@ func (b *Builder) Test(p *pkg.LocalPackage) error {
}
}
- testFilename := b.TestExePath(p.Name())
+ testBpkg := b.PkgMap[p]
+ testFilename := b.TestExePath(testBpkg)
if err := b.link(testFilename, "", nil); err != nil {
return err
}
@@ -633,7 +522,7 @@ func (b *Builder) Test(p *pkg.LocalPackage) error {
func (b *Builder) FetchSymbolMap() (error, *symbol.SymbolMap) {
loader_sm := symbol.NewSymbolMap()
- for _, value := range b.Packages {
+ for _, value := range b.PkgMap {
err, sm := b.ParseObjectLibrary(value)
if err == nil {
util.StatusMessage(util.VERBOSITY_VERBOSE,
@@ -649,7 +538,7 @@ func (b *Builder) FetchSymbolMap() (error, *symbol.SymbolMap) {
}
func (b *Builder) GetTarget() *target.Target {
- return b.target.GetTarget()
+ return b.targetBuilder.GetTarget()
}
func (b *Builder) buildRomElf(common *symbol.SymbolMap) error {
@@ -657,7 +546,7 @@ func (b *Builder) buildRomElf(common *symbol.SymbolMap) error {
/* check dependencies on the ROM ELF. This is really dependent on
* all of the .a files, but since we already depend on the loader
* .as to build the initial elf, we only need to check the app .a */
- c, err := b.target.NewCompiler(b.AppElfPath())
+ c, err := b.targetBuilder.NewCompiler(b.AppElfPath())
d := toolchain.NewDepTracker(c)
if err != nil {
return err
@@ -666,8 +555,8 @@ func (b *Builder) buildRomElf(common *symbol.SymbolMap) error {
archNames := []string{}
/* build the set of archive file names */
- for _, bpkg := range b.Packages {
- archivePath := b.ArchivePath(bpkg.Name())
+ for _, bpkg := range b.PkgMap {
+ archivePath := b.ArchivePath(bpkg)
if util.NodeExist(archivePath) {
archNames = append(archNames, archivePath)
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/builder/buildpackage.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildpackage.go b/newt/builder/buildpackage.go
index 596b359..1806901 100644
--- a/newt/builder/buildpackage.go
+++ b/newt/builder/buildpackage.go
@@ -20,7 +20,6 @@
package builder
import (
- "fmt"
"os"
"path/filepath"
"regexp"
@@ -35,26 +34,11 @@ import (
"mynewt.apache.org/newt/util"
)
-// Indicates whether a package's API dependency has been another package.
-type reqApiStatus int
-
-const (
- REQ_API_STATUS_UNSATISFIED reqApiStatus = iota
- REQ_API_STATUS_SATISFIED
-)
-
type BuildPackage struct {
*pkg.LocalPackage
- ci *toolchain.CompilerInfo
-
+ ci *toolchain.CompilerInfo
SourceDirectories []string
-
- // Keeps track of API requirements and whether they are satisfied.
- reqApiMap map[string]reqApiStatus
-
- depsResolved bool
- apisSatisfied bool
}
// Recursively iterates through an pkg's dependencies, adding each pkg
@@ -74,15 +58,16 @@ func (bpkg *BuildPackage) collectDepsAux(b *Builder,
}
// Get pkg structure
- dpkg := project.GetProject().ResolveDependency(dep).(*pkg.LocalPackage)
- if dpkg == nil {
- return util.NewNewtError("Cannot resolve dependency " + dep.String())
+ p := project.GetProject().ResolveDependency(dep)
+ if p == nil {
+ return util.FmtNewtError("Cannot resolve dependency %+v", dep)
}
+ dpkg := p.(*pkg.LocalPackage)
- dbpkg := b.Packages[dpkg]
+ dbpkg := b.PkgMap[dpkg]
if dbpkg == nil {
- return util.NewNewtError(fmt.Sprintf("Package not found (%s)",
- dpkg.Name()))
+ return util.FmtNewtError("Package not found %s; required by %s",
+ dpkg.Name(), bpkg.Name())
}
if err := dbpkg.collectDepsAux(b, set); err != nil {
@@ -113,7 +98,9 @@ func (bpkg *BuildPackage) collectDeps(b *Builder) ([]*BuildPackage, error) {
// Calculates the include paths exported by the specified pkg and all of
// its recursive dependencies.
-func (bpkg *BuildPackage) recursiveIncludePaths(b *Builder) ([]string, error) {
+func (bpkg *BuildPackage) recursiveIncludePaths(
+ b *Builder) ([]string, error) {
+
deps, err := bpkg.collectDeps(b)
if err != nil {
return nil, err
@@ -121,17 +108,14 @@ func (bpkg *BuildPackage) recursiveIncludePaths(b *Builder) ([]string, error) {
incls := []string{}
for _, p := range deps {
- incls = append(incls, p.publicIncludeDirs(b)...)
+ incls = append(incls, p.publicIncludeDirs(b.targetBuilder.bspPkg)...)
}
return incls, nil
}
-func (bpkg *BuildPackage) CompilerInfo(b *Builder) (*toolchain.CompilerInfo, error) {
- if !bpkg.depsResolved || !bpkg.apisSatisfied {
- return nil, util.NewNewtError("Package must be resolved before " +
- "compiler info is fetched; package=" + bpkg.Name())
- }
+func (bpkg *BuildPackage) CompilerInfo(
+ b *Builder) (*toolchain.CompilerInfo, error) {
// If this package's compiler info has already been generated, returned the
// cached copy.
@@ -140,43 +124,45 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) (*toolchain.CompilerInfo, err
}
ci := toolchain.NewCompilerInfo()
- features := b.Cfg.FeaturesForLpkg(bpkg.LocalPackage)
- ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.Viper, features,
+ features := b.cfg.FeaturesForLpkg(bpkg.LocalPackage)
+ ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.PkgV, features,
"pkg.cflags")
- ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.Viper, features,
+ ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.PkgV, features,
"pkg.lflags")
- ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.Viper, features,
+ ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.PkgV, features,
"pkg.aflags")
+ // Package-specific injected settings get specified as C flags on the
+ // command line.
for k, _ := range bpkg.InjectedSettings() {
ci.Cflags = append(ci.Cflags, syscfg.FeatureToCflag(k))
}
ci.IgnoreFiles = []*regexp.Regexp{}
- ignPats := newtutil.GetStringSliceFeatures(bpkg.Viper,
+ ignPats := newtutil.GetStringSliceFeatures(bpkg.PkgV,
features, "pkg.ign_files")
for _, str := range ignPats {
re, err := regexp.Compile(str)
if err != nil {
- return nil, util.NewNewtError("Ignore files, unable to compile re: " +
- err.Error())
+ return nil, util.NewNewtError(
+ "Ignore files, unable to compile re: " + err.Error())
}
ci.IgnoreFiles = append(ci.IgnoreFiles, re)
}
ci.IgnoreDirs = []*regexp.Regexp{}
- ignPats = newtutil.GetStringSliceFeatures(bpkg.Viper,
+ ignPats = newtutil.GetStringSliceFeatures(bpkg.PkgV,
features, "pkg.ign_dirs")
for _, str := range ignPats {
re, err := regexp.Compile(str)
if err != nil {
- return nil, util.NewNewtError("Ignore dirs, unable to compile re: " +
- err.Error())
+ return nil, util.NewNewtError(
+ "Ignore dirs, unable to compile re: " + err.Error())
}
ci.IgnoreDirs = append(ci.IgnoreDirs, re)
}
- bpkg.SourceDirectories = newtutil.GetStringSliceFeatures(bpkg.Viper,
+ bpkg.SourceDirectories = newtutil.GetStringSliceFeatures(bpkg.PkgV,
features, "pkg.src_dirs")
includePaths, err := bpkg.recursiveIncludePaths(b)
@@ -193,128 +179,34 @@ func (bpkg *BuildPackage) CompilerInfo(b *Builder) (*toolchain.CompilerInfo, err
// 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.
-func (bpkg *BuildPackage) satisfyReqApi(b *Builder, reqApi string) bool {
- depBpkg := b.apis[reqApi]
- if depBpkg == nil {
- return false
- }
+func (bpkg *BuildPackage) satisfyReqApi(
+ reqApi string, apiPkg *BuildPackage) error {
dep := &pkg.Dependency{
- Name: depBpkg.Name(),
- Repo: depBpkg.Repo().Name(),
+ Name: apiPkg.Name(),
+ Repo: apiPkg.Repo().Name(),
}
bpkg.AddDep(dep)
- bpkg.reqApiMap[reqApi] = REQ_API_STATUS_SATISFIED
-
- // This package now has a new unresolved dependency.
- bpkg.depsResolved = false
log.Debugf("API requirement satisfied; pkg=%s API=(%s, %s)",
bpkg.Name(), reqApi, dep.String())
- return true
-}
-
-// @return bool True if this this function changed the builder
-// state; another full iteration is required
-// in this case.
-// error non-nil on failure.
-func (bpkg *BuildPackage) loadDeps(b *Builder,
- features map[string]bool) (bool, error) {
-
- proj := project.GetProject()
-
- changed := false
-
- newDeps := newtutil.GetStringSliceFeatures(bpkg.Viper, features, "pkg.deps")
- for _, newDepStr := range newDeps {
- newDep, err := pkg.NewDependency(bpkg.Repo(), newDepStr)
- if err != nil {
- return false, err
- }
-
- pkg, ok := proj.ResolveDependency(newDep).(*pkg.LocalPackage)
- if !ok {
- return false,
- util.NewNewtError("Could not resolve package dependency " +
- newDep.String())
- }
-
- if b.Packages[pkg] == nil {
- changed = true
- b.AddPackage(pkg)
- }
-
- if !bpkg.HasDep(newDep) {
- changed = true
- bpkg.AddDep(newDep)
- }
- }
-
- // 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, features, "pkg.apis")
- for _, api := range apis {
- newApi := b.AddApi(api, bpkg)
- if newApi {
- changed = true
- }
- }
-
- return changed, nil
-}
-
-// @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,
- features map[string]bool) bool {
-
- // Assume all this package's APIs are satisfied and that no new
- // dependencies will be detected.
- bpkg.apisSatisfied = true
- newDeps := false
-
- // 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, features,
- "pkg.req_apis")
- for _, reqApi := range reqApis {
- reqStatus, ok := bpkg.reqApiMap[reqApi]
- if !ok {
- reqStatus = REQ_API_STATUS_UNSATISFIED
- bpkg.reqApiMap[reqApi] = reqStatus
- }
-
- if reqStatus == REQ_API_STATUS_UNSATISFIED {
- apiSatisfied := bpkg.satisfyReqApi(b, reqApi)
- if apiSatisfied {
- // An API was satisfied; the package now has a new dependency
- // that needs to be resolved.
- newDeps = true
- reqStatus = REQ_API_STATUS_SATISFIED
- }
- }
- if reqStatus == REQ_API_STATUS_UNSATISFIED {
- bpkg.apisSatisfied = false
- }
- }
-
- return newDeps
+ return nil
}
func (bpkg *BuildPackage) findSdkIncludes() []string {
sdkDir := bpkg.BasePath() + "/src/ext/"
sdkPathList := []string{}
- err := filepath.Walk(sdkDir, func(path string, info os.FileInfo, err error) error {
- if !info.IsDir() {
- return nil
- }
+ err := filepath.Walk(sdkDir,
+ func(path string, info os.FileInfo, err error) error {
+ if !info.IsDir() {
+ return nil
+ }
- sdkPathList = append(sdkPathList, path)
- return nil
- })
+ sdkPathList = append(sdkPathList, path)
+ return nil
+ })
if err != nil {
return []string{}
}
@@ -322,17 +214,17 @@ func (bpkg *BuildPackage) findSdkIncludes() []string {
return sdkPathList
}
-func (bpkg *BuildPackage) publicIncludeDirs(b *Builder) []string {
+func (bpkg *BuildPackage) publicIncludeDirs(bspPkg *pkg.BspPackage) []string {
pkgBase := filepath.Base(bpkg.Name())
bp := bpkg.BasePath()
incls := []string{
bp + "/include",
- bp + "/include/" + pkgBase + "/arch/" + b.target.Bsp.Arch,
+ bp + "/include/" + pkgBase + "/arch/" + bspPkg.Arch,
}
if bpkg.Type() == pkg.PACKAGE_TYPE_SDK {
- incls = append(incls, b.target.Bsp.BasePath()+"/include/bsp/")
+ incls = append(incls, bspPkg.BasePath()+"/include/bsp/")
sdkIncls := bpkg.findSdkIncludes()
incls = append(incls, sdkIncls...)
@@ -346,13 +238,13 @@ func (bpkg *BuildPackage) privateIncludeDirs(b *Builder) []string {
incls := []string{}
incls = append(incls, srcDir)
- incls = append(incls, srcDir+"/arch/"+b.target.Bsp.Arch)
+ incls = append(incls, srcDir+"/arch/"+b.targetBuilder.bspPkg.Arch)
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/")
+ incls = append(incls, b.bspPkg.BasePath()+"/include/bsp/")
sdkIncls := bpkg.findSdkIncludes()
incls = append(incls, sdkIncls...)
@@ -372,51 +264,47 @@ func (bpkg *BuildPackage) privateIncludeDirs(b *Builder) []string {
return incls
}
-// Attempts to resolve all of a build package's dependencies, identities, APIs,
-// and required APIs. This function should be called repeatedly until the
-// package is fully resolved.
-//
-// If a dependency is resolved by this function, the new dependency needs to be
-// processed. The caller should attempt to resolve all packages again.
-//
-// If a new supported feature is detected by this function, all pacakges need
-// to be reprocessed from scratch. The caller should set all packages'
-// depsResolved and apisSatisfied variables to false and attempt to resolve
-// everything again.
-//
-// @return bool true if >=1 dependencies were resolved
-// bool true if >=1 new features were detected
-func (bpkg *BuildPackage) Resolve(b *Builder,
- cfg syscfg.Cfg) (bool, error) {
-
- var err error
- newDeps := false
+// Resolves all of a build package's dependencies and API requirements.
+func (bpkg *BuildPackage) resolveDeps(
+ cfg syscfg.Cfg, apiMap map[string]*BuildPackage) error {
features := cfg.FeaturesForLpkg(bpkg.LocalPackage)
- if !bpkg.depsResolved {
- newDeps, err = bpkg.loadDeps(b, features)
+ // Match each required API with the package which implements it.
+ reqApis := newtutil.GetStringSliceFeatures(bpkg.PkgV, features,
+ "pkg.req_apis")
+ for _, reqApi := range reqApis {
+ if err := bpkg.satisfyReqApi(reqApi, apiMap[reqApi]); err != nil {
+ return err
+ }
+ }
+
+ proj := project.GetProject()
+ newDeps := newtutil.GetStringSliceFeatures(bpkg.PkgV, features,
+ "pkg.deps")
+ for _, newDepStr := range newDeps {
+ newDep, err := pkg.NewDependency(bpkg.Repo(), newDepStr)
if err != nil {
- return false, err
+ return err
}
- bpkg.depsResolved = !newDeps
- }
+ _, ok := proj.ResolveDependency(newDep).(*pkg.LocalPackage)
+ if !ok {
+ return util.NewNewtError("Could not resolve package dependency " +
+ newDep.String())
+ }
- if !bpkg.apisSatisfied {
- newApiDep := bpkg.satisfyApis(b, features)
- if newApiDep {
- newDeps = true
+ if !bpkg.HasDep(newDep) {
+ bpkg.AddDep(newDep)
}
}
- return newDeps, nil
+ return nil
}
func NewBuildPackage(pkg *pkg.LocalPackage) *BuildPackage {
bpkg := &BuildPackage{
LocalPackage: pkg,
- reqApiMap: map[string]reqApiStatus{},
}
return bpkg
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/builder/buildutil.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildutil.go b/newt/builder/buildutil.go
index be87509..ea1e7f4 100644
--- a/newt/builder/buildutil.go
+++ b/newt/builder/buildutil.go
@@ -30,7 +30,6 @@ import (
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/project"
"mynewt.apache.org/newt/newt/target"
- "mynewt.apache.org/newt/util"
)
func BinRoot() string {
@@ -41,61 +40,88 @@ func TargetBinDir(target *target.Target) string {
return BinRoot() + "/" + target.Name()
}
+func GeneratedBaseDir(targetName string) string {
+ return BinRoot() + "/" + targetName + "/generated"
+}
+
+func GeneratedSrcDir(targetName string) string {
+ return GeneratedBaseDir(targetName) + "/src"
+}
+
+func GeneratedIncludeDir(targetName string) string {
+ return GeneratedBaseDir(targetName) + "/include"
+}
+
+func GeneratedBinDir(targetName string) string {
+ return GeneratedBaseDir(targetName) + "/bin"
+}
+
+func SysinitArchivePath(targetName string) string {
+ return GeneratedBinDir(targetName) + "/sysinit.a"
+}
+
func (b *Builder) BinDir() string {
- return BinRoot() + "/" + b.target.target.Name() + "/" + b.buildName
+ return BinRoot() + "/" + b.targetPkg.Name() + "/" + b.buildName
}
-func (b *Builder) PkgBinDir(pkgName string) string {
+func (b *Builder) FileBinDir(pkgName string) string {
return b.BinDir() + "/" + pkgName
}
+func (b *Builder) PkgBinDir(bpkg *BuildPackage) string {
+ switch bpkg.Type() {
+ case pkg.PACKAGE_TYPE_GENERATED:
+ return GeneratedBinDir(b.targetPkg.Name())
+ default:
+ return b.FileBinDir(bpkg.Name())
+ }
+}
+
// Generates the path+filename of the specified package's .a file.
-func (b *Builder) ArchivePath(pkgName string) string {
- return b.PkgBinDir(pkgName) + "/" + filepath.Base(pkgName) + ".a"
+func (b *Builder) ArchivePath(bpkg *BuildPackage) string {
+ return b.PkgBinDir(bpkg) + "/" + filepath.Base(bpkg.Name()) + ".a"
}
func (b *Builder) AppTempElfPath() string {
- pkgName := b.appPkg.Name()
- return b.PkgBinDir(pkgName) + "/" + filepath.Base(pkgName) + "_tmp.elf"
+ return b.PkgBinDir(b.appPkg) + "/" + filepath.Base(b.appPkg.Name()) +
+ "_tmp.elf"
}
func (b *Builder) AppElfPath() string {
- pkgName := b.appPkg.Name()
- return b.PkgBinDir(pkgName) + "/" + filepath.Base(pkgName) + ".elf"
+ return b.PkgBinDir(b.appPkg) + "/" + filepath.Base(b.appPkg.Name()) +
+ ".elf"
}
func (b *Builder) AppLinkerElfPath() string {
- pkgName := b.appPkg.Name()
- return b.PkgBinDir(pkgName) + "/" + filepath.Base(pkgName) + "linker.elf"
+ return b.PkgBinDir(b.appPkg) + "/" + filepath.Base(b.appPkg.Name()) +
+ "linker.elf"
}
func (b *Builder) AppImgPath() string {
- pkgName := b.appPkg.Name()
- return b.PkgBinDir(pkgName) + "/" + filepath.Base(pkgName) + ".img"
+ return b.PkgBinDir(b.appPkg) + "/" + filepath.Base(b.appPkg.Name()) +
+ ".img"
}
func (b *Builder) AppPath() string {
- pkgName := b.appPkg.Name()
- return b.PkgBinDir(pkgName) + "/"
+ return b.PkgBinDir(b.appPkg) + "/"
}
func (b *Builder) AppBinBasePath() string {
- pkgName := b.appPkg.Name()
- return b.PkgBinDir(pkgName) + "/" + filepath.Base(pkgName)
+ return b.PkgBinDir(b.appPkg) + "/" + filepath.Base(b.appPkg.Name())
}
func TestTargetName(testPkgName string) string {
return strings.Replace(testPkgName, "/", "_", -1)
}
-func (b *Builder) TestExePath(pkgName string) string {
- return b.PkgBinDir(pkgName) + "/" + TestTargetName(pkgName)
+func (b *Builder) TestExePath(bpkg *BuildPackage) string {
+ return b.PkgBinDir(bpkg) + "/" + TestTargetName(bpkg.Name())
}
func (b *Builder) FeatureString() string {
var buffer bytes.Buffer
- featureMap := b.Cfg.Features()
+ featureMap := b.cfg.Features()
featureSlice := make([]string, 0, len(featureMap))
for k, _ := range featureMap {
featureSlice = append(featureSlice, k)
@@ -112,44 +138,6 @@ func (b *Builder) FeatureString() string {
return buffer.String()
}
-// Makes sure all packages with required APIs have been augmented with a
-// dependency that satisfies that requirement. If there are any unsatisfied
-// requirements, an error is returned.
-func (b *Builder) verifyApisSatisfied() error {
- unsatisfied := map[*BuildPackage][]string{}
-
- for _, bpkg := range b.Packages {
- for api, status := range bpkg.reqApiMap {
- if status == REQ_API_STATUS_UNSATISFIED {
- slice := unsatisfied[bpkg]
- if slice == nil {
- unsatisfied[bpkg] = []string{api}
- } else {
- slice = append(slice, api)
- }
- }
- }
- }
-
- if len(unsatisfied) != 0 {
- var buffer bytes.Buffer
- for bpkg, apis := range unsatisfied {
- buffer.WriteString("Package " + bpkg.Name() +
- " has unsatisfied required APIs: ")
- for i, api := range apis {
- if i != 0 {
- buffer.WriteString(", ")
- }
- buffer.WriteString(api)
- }
- buffer.WriteString("\n")
- }
- return util.NewNewtError(buffer.String())
- }
-
- return nil
-}
-
type bpkgSorter struct {
bpkgs []*BuildPackage
}
@@ -166,10 +154,10 @@ func (b bpkgSorter) Less(i, j int) bool {
func (b *Builder) sortedBuildPackages() []*BuildPackage {
sorter := bpkgSorter{
- bpkgs: make([]*BuildPackage, 0, len(b.Packages)),
+ bpkgs: make([]*BuildPackage, 0, len(b.PkgMap)),
}
- for _, bpkg := range b.Packages {
+ for _, bpkg := range b.PkgMap {
sorter.bpkgs = append(sorter.bpkgs, bpkg)
}
@@ -193,23 +181,23 @@ func (b *Builder) logDepInfo() {
log.Debugf("Feature set: [" + b.FeatureString() + "]")
// Log API set.
- apis := make([]string, 0, len(b.apis))
- for api, _ := range b.apis {
+ apis := make([]string, 0, len(b.apiMap))
+ for api, _ := range b.apiMap {
apis = append(apis, api)
}
sort.Strings(apis)
log.Debugf("API set:")
for _, api := range apis {
- bpkg := b.apis[api]
- log.Debugf(" * " + api + " (" + bpkg.Name() + ")")
+ bpkg := b.apiMap[api]
+ log.Debugf(" * " + api + " (" + bpkg.FullName() + ")")
}
// Log dependency graph.
bpkgSorter := bpkgSorter{
- bpkgs: make([]*BuildPackage, 0, len(b.Packages)),
+ bpkgs: make([]*BuildPackage, 0, len(b.PkgMap)),
}
- for _, bpkg := range b.Packages {
+ for _, bpkg := range b.PkgMap {
bpkgSorter.bpkgs = append(bpkgSorter.bpkgs, bpkg)
}
sort.Sort(bpkgSorter)
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/builder/library.go
----------------------------------------------------------------------
diff --git a/newt/builder/library.go b/newt/builder/library.go
index c3d7cde..40a0752 100644
--- a/newt/builder/library.go
+++ b/newt/builder/library.go
@@ -113,9 +113,10 @@ func getParseRexeg() (error, *regexp.Regexp) {
return nil, r
}
-func (b *Builder) ParseObjectLibrary(bp *BuildPackage) (error, *symbol.SymbolMap) {
+func (b *Builder) ParseObjectLibrary(bp *BuildPackage) (
+ error, *symbol.SymbolMap) {
- file := b.ArchivePath(bp.Name())
+ file := b.ArchivePath(bp)
return b.ParseObjectLibraryFile(bp, file, true)
}
@@ -126,7 +127,7 @@ func (b *Builder) ParseObjectElf(elf_file string) (error, *symbol.SymbolMap) {
func (b *Builder) ParseObjectLibraryFile(bp *BuildPackage,
file string, textDataOnly bool) (error, *symbol.SymbolMap) {
- c, err := b.target.NewCompiler(b.AppElfPath())
+ c, err := b.targetBuilder.NewCompiler(b.AppElfPath())
ext := filepath.Ext(file)
@@ -206,7 +207,7 @@ func (b *Builder) ParseObjectLibraryFile(bp *BuildPackage,
func (b *Builder) CopySymbols(sm *symbol.SymbolMap) error {
- c, err := b.target.NewCompiler(b.AppElfPath())
+ c, err := b.targetBuilder.NewCompiler(b.AppElfPath())
if err != nil {
return err
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/builder/load.go
----------------------------------------------------------------------
diff --git a/newt/builder/load.go b/newt/builder/load.go
index f3d0bbe..fba8e93 100644
--- a/newt/builder/load.go
+++ b/newt/builder/load.go
@@ -36,13 +36,13 @@ func (t *TargetBuilder) Load(extraJtagCmd string) error {
return err
}
- if t.Loader != nil {
- err = t.App.Load(1, extraJtagCmd)
+ if t.LoaderBuilder != nil {
+ err = t.AppBuilder.Load(1, extraJtagCmd)
if err == nil {
- err = t.Loader.Load(0, extraJtagCmd)
+ err = t.LoaderBuilder.Load(0, extraJtagCmd)
}
} else {
- err = t.App.Load(0, extraJtagCmd)
+ err = t.AppBuilder.Load(0, extraJtagCmd)
}
return err
@@ -56,22 +56,23 @@ func (b *Builder) Load(image_slot int, extraJtagCmd string) error {
/*
* Populate the package list and feature sets.
*/
- err := b.target.PrepBuild()
+ err := b.targetBuilder.PrepBuild()
if err != nil {
return err
}
- if b.target.Bsp.DownloadScript == "" {
+ if b.targetBuilder.bspPkg.DownloadScript == "" {
/*
*
*/
util.StatusMessage(util.VERBOSITY_DEFAULT,
- "No download script for BSP %s\n", b.target.Bsp.Name())
+ "No download script for BSP %s\n", b.bspPkg.Name())
return nil
}
- bspPath := b.target.Bsp.BasePath()
- downloadScript := filepath.Join(bspPath, b.target.Bsp.DownloadScript)
+ bspPath := b.bspPkg.BasePath()
+ downloadScript := filepath.Join(bspPath,
+ b.targetBuilder.bspPkg.DownloadScript)
binBaseName := b.AppBinBasePath()
featureString := b.FeatureString()
@@ -88,7 +89,7 @@ func (b *Builder) Load(image_slot int, extraJtagCmd string) error {
downloadCmd := fmt.Sprintf("%s %s %s %s", envSettings, downloadScript,
bspPath, binBaseName)
- features := b.Cfg.Features()
+ features := b.cfg.Features()
if _, ok := features["bootloader"]; ok {
util.StatusMessage(util.VERBOSITY_DEFAULT,
@@ -118,17 +119,10 @@ func (t *TargetBuilder) Debug(extraJtagCmd string, reset bool) error {
return err
}
- // if t.Loader != nil {
- // basename := t.Loader.AppElfPath()
- // name := strings.TrimSuffix(basename, filepath.Ext(basename))
- // additional_libs = append(additional_libs, name)
- // }
-
- // return t.App.Debug(additional_libs)
- if t.Loader == nil {
- return t.App.Debug(extraJtagCmd, reset)
+ if t.LoaderBuilder == nil {
+ return t.AppBuilder.Debug(extraJtagCmd, reset)
}
- return t.Loader.Debug(extraJtagCmd, reset)
+ return t.LoaderBuilder.Debug(extraJtagCmd, reset)
}
func (b *Builder) Debug(extraJtagCmd string, reset bool) error {
@@ -139,12 +133,12 @@ func (b *Builder) Debug(extraJtagCmd string, reset bool) error {
/*
* Populate the package list and feature sets.
*/
- err := b.target.PrepBuild()
+ err := b.targetBuilder.PrepBuild()
if err != nil {
return err
}
- bspPath := b.target.Bsp.BasePath()
+ bspPath := b.bspPkg.BasePath()
binBaseName := b.AppBinBasePath()
featureString := b.FeatureString()
@@ -160,11 +154,12 @@ func (b *Builder) Debug(extraJtagCmd string, reset bool) error {
if reset == true {
envSettings = append(envSettings, fmt.Sprintf("RESET=true"))
}
- debugScript := filepath.Join(bspPath, b.target.Bsp.DebugScript)
+ debugScript := filepath.Join(bspPath, b.targetBuilder.bspPkg.DebugScript)
os.Chdir(project.GetProject().Path())
- // bspPath, binBaseName are passed in command line for backwards compatibility
+ // bspPath, binBaseName are passed in command line for backwards
+ // compatibility
cmdLine := []string{debugScript, bspPath, binBaseName}
fmt.Printf("%s\n", cmdLine)
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/builder/size.go
----------------------------------------------------------------------
diff --git a/newt/builder/size.go b/newt/builder/size.go
index 37f1b47..970db2d 100644
--- a/newt/builder/size.go
+++ b/newt/builder/size.go
@@ -323,13 +323,13 @@ func (t *TargetBuilder) Size() error {
return err
}
- fmt.Printf("Size of Application Image: %s\n", t.App.buildName)
- err = t.App.Size()
+ fmt.Printf("Size of Application Image: %s\n", t.AppBuilder.buildName)
+ err = t.AppBuilder.Size()
if err == nil {
- if t.Loader != nil {
- fmt.Printf("Size of Loader Image: %s\n", t.Loader.buildName)
- err = t.Loader.Size()
+ if t.LoaderBuilder != nil {
+ fmt.Printf("Size of Loader Image: %s\n", t.LoaderBuilder.buildName)
+ err = t.LoaderBuilder.Size()
}
}
@@ -341,11 +341,11 @@ func (b *Builder) Size() error {
return util.NewNewtError("app package not specified for this target")
}
- err := b.target.PrepBuild()
+ err := b.targetBuilder.PrepBuild()
if err != nil {
return err
}
- if b.target.Bsp.Arch == "sim" {
+ if b.targetBuilder.bspPkg.Arch == "sim" {
fmt.Println("'newt size' not supported for sim targets.")
return nil
}
@@ -361,7 +361,7 @@ func (b *Builder) Size() error {
}
fmt.Printf("%s", output)
- c, err := b.newCompiler(b.appPkg, b.PkgBinDir(b.AppElfPath()))
+ c, err := b.newCompiler(b.appPkg, b.FileBinDir(b.AppElfPath()))
if err != nil {
return err
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/builder/targetbuild.go
----------------------------------------------------------------------
diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go
index 0ca8154..a34b885 100644
--- a/newt/builder/targetbuild.go
+++ b/newt/builder/targetbuild.go
@@ -24,32 +24,57 @@ import (
"os"
"strings"
+ log "github.com/Sirupsen/logrus"
+
"mynewt.apache.org/newt/newt/interfaces"
"mynewt.apache.org/newt/newt/pkg"
"mynewt.apache.org/newt/newt/project"
+ "mynewt.apache.org/newt/newt/resolve"
"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"
)
type TargetBuilder struct {
- compilerPkg *pkg.LocalPackage
- Bsp *pkg.BspPackage
target *target.Target
+ bspPkg *pkg.BspPackage
+ compilerPkg *pkg.LocalPackage
+ appPkg *pkg.LocalPackage
+ loaderPkg *pkg.LocalPackage
+ testPkg *pkg.LocalPackage
- App *Builder
- AppList interfaces.PackageList
+ AppBuilder *Builder
+ AppList interfaces.PackageList
- Loader *Builder
- LoaderList interfaces.PackageList
+ LoaderBuilder *Builder
+ LoaderList interfaces.PackageList
}
-func NewTargetBuilder(target *target.Target) (*TargetBuilder, error) {
- t := &TargetBuilder{}
+func NewTargetBuilder(target *target.Target,
+ testPkg *pkg.LocalPackage) (*TargetBuilder, error) {
- /* TODO */
- t.target = target
+ if err := target.Validate(testPkg == nil); err != nil {
+ return nil, err
+ }
+
+ bspPkg := pkg.NewBspPackage(target.Bsp())
+ compilerPkg, err := project.GetProject().ResolvePackage(
+ bspPkg.Repo(), bspPkg.CompilerName)
+ if err != nil {
+ return nil, err
+ }
+
+ t := &TargetBuilder{
+ target: target,
+ bspPkg: bspPkg,
+ compilerPkg: compilerPkg,
+ appPkg: target.App(),
+ loaderPkg: target.Loader(),
+ testPkg: testPkg,
+ }
return t, nil
}
@@ -61,84 +86,157 @@ func (t *TargetBuilder) NewCompiler(dstDir string) (*toolchain.Compiler, error)
return c, err
}
-func (t *TargetBuilder) PrepBuild() error {
+func (t *TargetBuilder) resolveCfg(injectedSettings map[string]string) (
+ resolve.CfgResolution, error) {
- if t.Bsp != nil {
- // Already prepped
- return nil
- }
- // Collect the seed packages.
- bspPkg := t.target.Bsp()
- if bspPkg == nil {
- if t.target.BspName == "" {
- return util.NewNewtError("BSP package not specified by target")
- } else {
- return util.NewNewtError("BSP package not found: " +
- t.target.BspName)
- }
+ seeds := []*pkg.LocalPackage{
+ t.bspPkg.LocalPackage,
+ t.compilerPkg,
+ t.target.Package(),
}
- t.Bsp = pkg.NewBspPackage(bspPkg)
- compilerPkg := t.resolveCompiler()
- if compilerPkg == nil {
- if t.Bsp.CompilerName == "" {
- return util.NewNewtError("Compiler package not specified by BSP")
- } else {
- return util.NewNewtError("Compiler package not found: " +
- t.Bsp.CompilerName)
- }
+ if t.loaderPkg != nil {
+ seeds = append(seeds, t.loaderPkg)
+ }
+
+ if t.appPkg != nil {
+ seeds = append(seeds, t.appPkg)
+ }
+
+ if t.testPkg != nil {
+ seeds = append(seeds, t.testPkg)
+ }
+
+ cfgResolution, err := resolve.ResolveCfg(seeds, injectedSettings)
+ if err != nil {
+ return cfgResolution, err
+ }
+
+ return cfgResolution, nil
+}
+
+func (t *TargetBuilder) resolveCfgBuild() (resolve.CfgResolution, error) {
+ return t.resolveCfg(nil)
+}
+
+func (t *TargetBuilder) resolveCfgTest() (resolve.CfgResolution, error) {
+ // Inject the TEST setting into the entire build. This setting
+ // exposes unit test code in each package.
+ return t.resolveCfg(map[string]string{"TEST": "1"})
+}
+
+func (t *TargetBuilder) validateAndWriteCfg(
+ cfgResolution resolve.CfgResolution) error {
+
+ if errText := cfgResolution.ErrorText(); errText != "" {
+ return util.NewNewtError(errText)
}
- t.compilerPkg = compilerPkg
- appPkg := t.target.App()
- targetPkg := t.target.Package()
+ if err := syscfg.EnsureWritten(cfgResolution.Cfg,
+ GeneratedIncludeDir(t.target.Name())); err != nil {
- app, err := NewBuilder(t, "app")
+ return err
+ }
- if err == nil {
- t.App = app
+ return nil
+}
+
+func (t *TargetBuilder) resolvePkgs(cfgResolution resolve.CfgResolution) (
+ []*pkg.LocalPackage, []*pkg.LocalPackage, error) {
+
+ var appPkg *pkg.LocalPackage
+ if t.appPkg != nil {
+ appPkg = t.appPkg
} else {
+ appPkg = t.testPkg
+ }
+
+ return resolve.ResolveSplitPkgs(cfgResolution,
+ t.loaderPkg,
+ appPkg,
+ t.bspPkg.LocalPackage,
+ t.compilerPkg,
+ t.target.Package())
+}
+
+func (t *TargetBuilder) buildSysinit(
+ cfgResolution resolve.CfgResolution) error {
+
+ loaderPkgs, appPkgs, err := t.resolvePkgs(cfgResolution)
+ if err != nil {
return err
}
- loaderPkg := t.target.Loader()
+ srcDir := GeneratedSrcDir(t.target.Name())
+
+ if loaderPkgs != nil {
+ sysinit.EnsureWritten(loaderPkgs, srcDir,
+ pkg.ShortName(t.target.Package()), true)
+ }
- if loaderPkg != nil {
- loader, err := NewBuilder(t, "loader")
+ sysinit.EnsureWritten(appPkgs, srcDir,
+ pkg.ShortName(t.target.Package()), false)
- if err == nil {
- t.Loader = loader
- } else {
- return err
- }
+ return nil
+}
+
+func (t *TargetBuilder) ExportCfg() (resolve.CfgResolution, error) {
+ return t.resolveCfgBuild()
+}
- err = t.Loader.PrepBuild(loaderPkg, bspPkg, targetPkg)
+func (t *TargetBuilder) PrepBuild() error {
+ cfgResolution, err := t.resolveCfgBuild()
+ if err != nil {
+ return err
+ }
+
+ if err := t.validateAndWriteCfg(cfgResolution); err != nil {
+ return err
+ }
+
+ loaderPkgs, appPkgs, err := t.resolvePkgs(cfgResolution)
+ if err != nil {
+ return err
+ }
+
+ if loaderPkgs != nil {
+ t.LoaderBuilder, err = NewBuilder(t, "loader", loaderPkgs,
+ cfgResolution.ApiMap, cfgResolution.Cfg)
if err != nil {
return err
}
+ if err := t.LoaderBuilder.PrepBuild(); err != nil {
+ return err
+ }
- loader_flag := toolchain.NewCompilerInfo()
- loader_flag.Cflags = append(loader_flag.Cflags, "-DSPLIT_LOADER")
- t.Loader.AddCompilerInfo(loader_flag)
+ loaderFlags := toolchain.NewCompilerInfo()
+ loaderFlags.Cflags = append(loaderFlags.Cflags, "-DSPLIT_LOADER")
+ t.LoaderBuilder.AddCompilerInfo(loaderFlags)
t.LoaderList = project.ResetDeps(nil)
}
- bsp_pkg := t.target.Bsp()
-
- err = t.App.PrepBuild(appPkg, bsp_pkg, targetPkg)
+ t.AppBuilder, err = NewBuilder(t, "app", appPkgs,
+ cfgResolution.ApiMap, cfgResolution.Cfg)
if err != nil {
return err
-
}
- if loaderPkg != nil {
- app_flag := toolchain.NewCompilerInfo()
- app_flag.Cflags = append(app_flag.Cflags, "-DSPLIT_APPLICATION")
- t.App.AddCompilerInfo(app_flag)
+ if err := t.AppBuilder.PrepBuild(); err != nil {
+ return err
+ }
+
+ if loaderPkgs != nil {
+ appFlags := toolchain.NewCompilerInfo()
+ appFlags.Cflags = append(appFlags.Cflags, "-DSPLIT_APPLICATION")
+ t.AppBuilder.AddCompilerInfo(appFlags)
}
t.AppList = project.ResetDeps(nil)
+ if err := t.buildSysinit(cfgResolution); err != nil {
+ return err
+ }
+
return nil
}
@@ -146,10 +244,6 @@ func (t *TargetBuilder) Build() error {
var err error
var linkerScript string
- if err = t.target.Validate(true); err != nil {
- return err
- }
-
if err = t.PrepBuild(); err != nil {
return err
}
@@ -157,24 +251,24 @@ func (t *TargetBuilder) Build() error {
/* Build the Apps */
project.ResetDeps(t.AppList)
- if err := t.Bsp.Reload(t.App.Cfg.Features()); err != nil {
+ if err := t.bspPkg.Reload(t.AppBuilder.cfg.Features()); err != nil {
return err
}
- err = t.App.Build()
+ err = t.AppBuilder.Build()
if err != nil {
return err
}
/* if we have no loader, we are done here. All of the rest of this
* function is for split images */
- if t.Loader == nil {
- err = t.App.Link(t.Bsp.LinkerScript)
+ if t.LoaderBuilder == nil {
+ err = t.AppBuilder.Link(t.bspPkg.LinkerScript)
return err
}
/* Link the app as a test (using the normal single image linker script) */
- err = t.App.TestLink(t.Bsp.LinkerScript)
+ err = t.AppBuilder.TestLink(t.bspPkg.LinkerScript)
if err != nil {
return err
}
@@ -182,51 +276,50 @@ func (t *TargetBuilder) Build() error {
/* rebuild the loader */
project.ResetDeps(t.LoaderList)
- if err = t.Bsp.Reload(t.Loader.Cfg.Features()); err != nil {
+ if err = t.bspPkg.Reload(t.LoaderBuilder.cfg.Features()); err != nil {
return err
}
- err = t.Loader.Build()
+ err = t.LoaderBuilder.Build()
if err != nil {
return err
}
/* perform a test link of the loader */
- err = t.Loader.TestLink(t.Bsp.LinkerScript)
+ err = t.LoaderBuilder.TestLink(t.bspPkg.LinkerScript)
if err != nil {
return err
}
/* re-link the loader with app dependencies */
- err, common_pkgs, common_syms := t.RelinkLoader()
+ err, commonPkgs, commonSyms := t.RelinkLoader()
if err != nil {
return err
}
/* The app can ignore these packages next time */
- t.App.RemovePackages(common_pkgs)
- /* add back the BSP package which needs linking in both */
- t.App.AddPackage(t.Bsp.LocalPackage)
+ delete(commonPkgs, t.bspPkg.Name())
+ t.AppBuilder.RemovePackages(commonPkgs)
/* create the special elf to link the app against */
/* its just the elf with a set of symbols removed and renamed */
- err = t.Loader.buildRomElf(common_syms)
+ err = t.LoaderBuilder.buildRomElf(commonSyms)
if err != nil {
return err
}
/* set up the linker elf and linker script for the app */
- t.App.LinkElf = t.Loader.AppLinkerElfPath()
- linkerScript = t.Bsp.Part2LinkerScript
+ t.AppBuilder.linkElf = t.LoaderBuilder.AppLinkerElfPath()
+ linkerScript = t.bspPkg.Part2LinkerScript
if linkerScript == "" {
- return util.NewNewtError("BSP Must specify Linker script ")
+ return util.NewNewtError("BSP must specify linker script ")
}
/* link the app */
- err = t.App.Link(linkerScript)
+ err = t.AppBuilder.Link(linkerScript)
if err != nil {
return err
}
@@ -239,73 +332,86 @@ func (t *TargetBuilder) Build() error {
* shared with the app. Returns a list of the common packages shared
* by the app and loader
*/
-func (t *TargetBuilder) RelinkLoader() (error, map[string]bool, *symbol.SymbolMap) {
+func (t *TargetBuilder) RelinkLoader() (error, map[string]bool,
+ *symbol.SymbolMap) {
/* fetch symbols from the elf and from the libraries themselves */
- err, appLibSym := t.App.ExtractSymbolInfo()
+ log.Debugf("Loader packages:")
+ for _, lpkg := range t.LoaderBuilder.sortedLocalPackages() {
+ log.Debugf(" * %s", lpkg.Name())
+ }
+ log.Debugf("App packages:")
+ for _, lpkg := range t.AppBuilder.sortedLocalPackages() {
+ log.Debugf(" * %s", lpkg.Name())
+ }
+ err, appLibSym := t.AppBuilder.ExtractSymbolInfo()
if err != nil {
return err, nil, nil
}
/* fetch the symbol list from the app temporary elf */
- err, appElfSym := t.App.ParseObjectElf(t.App.AppTempElfPath())
+ err, appElfSym := t.AppBuilder.ParseObjectElf(t.AppBuilder.AppTempElfPath())
if err != nil {
return err, nil, nil
}
/* extract the library symbols and elf symbols from the loader */
- err, loaderLibSym := t.Loader.ExtractSymbolInfo()
+ err, loaderLibSym := t.LoaderBuilder.ExtractSymbolInfo()
if err != nil {
return err, nil, nil
}
- err, loaderElfSym := t.Loader.ParseObjectElf(t.Loader.AppTempElfPath())
+ err, loaderElfSym := t.LoaderBuilder.ParseObjectElf(
+ t.LoaderBuilder.AppTempElfPath())
if err != nil {
return err, nil, nil
}
/* create the set of matching and non-matching symbols */
- err, sm_match, sm_nomatch := symbol.IdenticalUnion(appLibSym,
+ err, smMatch, smNomatch := symbol.IdenticalUnion(appLibSym,
loaderLibSym, true, false)
/* which packages are shared between the two */
- common_pkgs := sm_match.Packages()
- uncommon_pkgs := sm_nomatch.Packages()
+ commonPkgs := smMatch.Packages()
+ uncommonPkgs := smNomatch.Packages()
/* ensure that the loader and app packages are never shared */
- delete(common_pkgs, t.App.appPkg.Name())
- uncommon_pkgs[t.App.appPkg.Name()] = true
- ma := sm_match.FilterPkg(t.App.appPkg.Name())
- sm_match.RemoveMap(ma)
+ delete(commonPkgs, t.AppBuilder.appPkg.Name())
+ uncommonPkgs[t.AppBuilder.appPkg.Name()] = true
+ ma := smMatch.FilterPkg(t.AppBuilder.appPkg.Name())
+ smMatch.RemoveMap(ma)
- delete(common_pkgs, t.Loader.appPkg.Name())
- uncommon_pkgs[t.Loader.appPkg.Name()] = true
- ml := sm_match.FilterPkg(t.Loader.appPkg.Name())
- sm_match.RemoveMap(ml)
+ delete(commonPkgs, t.LoaderBuilder.appPkg.Name())
+ uncommonPkgs[t.LoaderBuilder.appPkg.Name()] = true
+ ml := smMatch.FilterPkg(t.LoaderBuilder.appPkg.Name())
+ smMatch.RemoveMap(ml)
util.StatusMessage(util.VERBOSITY_VERBOSE,
- "Putting %d symbols from %d packages into Loader\n",
- len(*sm_match), len(common_pkgs))
+ "Putting %d symbols from %d packages into loader\n",
+ len(*smMatch), len(commonPkgs))
/* This is worth a special comment. We are building both apps as
* stand-alone apps against the normal linker file, so they will both
* have a Reset_Handler symbol. We need to ignore this here. When
* we build the split app, we use a special linker file which
* uses a different entry point */
- special_sm := symbol.NewSymbolMap()
- special_sm.Add(*symbol.NewElfSymbol("Reset_Handler(app)"))
- special_sm.Add(*symbol.NewElfSymbol("Reset_Handler(loader)"))
+ specialSm := symbol.NewSymbolMap()
+ specialSm.Add(*symbol.NewElfSymbol("Reset_Handler(app)"))
+ specialSm.Add(*symbol.NewElfSymbol("Reset_Handler(loader)"))
var badpkgs []string
- var symbol_str string
- for v, _ := range uncommon_pkgs {
- if t.App.appPkg != nil && t.App.appPkg.Name() != v &&
- t.Loader.appPkg != nil && t.Loader.appPkg.Name() != v {
- trouble := sm_nomatch.FilterPkg(v)
+ var symbolStr string
+ for v, _ := range uncommonPkgs {
+ if t.AppBuilder.appPkg != nil &&
+ t.AppBuilder.appPkg.Name() != v &&
+ t.LoaderBuilder.appPkg != nil &&
+ t.LoaderBuilder.appPkg.Name() != v {
+
+ trouble := smNomatch.FilterPkg(v)
var found bool
for _, sym := range *trouble {
- if _, ok := special_sm.Find(sym.Name); !ok {
+ if _, ok := specialSm.Find(sym.Name); !ok {
if !sym.IsLocal() {
found = true
}
@@ -313,32 +419,33 @@ func (t *TargetBuilder) RelinkLoader() (error, map[string]bool, *symbol.SymbolMa
}
if found {
- symbol_str = (*trouble).String("Non Matching Symbols")
+ symbolStr = (*trouble).String("Non Matching Symbols")
badpkgs = append(badpkgs, v)
- delete(common_pkgs, v)
+ delete(commonPkgs, v)
}
}
}
if len(badpkgs) > 0 {
- errStr := fmt.Sprintf("Common packages with different implementaiton\n %s \n",
+ errStr := fmt.Sprintf(
+ "Common packages with different implementaiton\n %s \n",
strings.Join(badpkgs, "\n "))
- errStr += symbol_str
+ errStr += symbolStr
return util.NewNewtError(errStr), nil, nil
}
/* for each symbol in the elf of the app, if that symbol is in
* a common package, keep that symbol in the loader */
- preserve_elf := symbol.NewSymbolMap()
+ preserveElf := symbol.NewSymbolMap()
/* go through each symbol in the app */
for _, elfsym := range *appElfSym {
name := elfsym.Name
if libsym, ok := (*appLibSym)[name]; ok {
- if _, ok := common_pkgs[libsym.Bpkg]; ok {
+ if _, ok := commonPkgs[libsym.Bpkg]; ok {
/* if its not in the loader elf, add it as undefined */
if _, ok := (*loaderElfSym)[name]; !ok {
- preserve_elf.Add(elfsym)
+ preserveElf.Add(elfsym)
}
}
}
@@ -348,84 +455,53 @@ func (t *TargetBuilder) RelinkLoader() (error, map[string]bool, *symbol.SymbolMa
project.ResetDeps(t.LoaderList)
util.StatusMessage(util.VERBOSITY_VERBOSE,
- "Migrating %d unused symbols into Loader\n", len(*preserve_elf))
+ "Migrating %d unused symbols into Loader\n", len(*preserveElf))
- err = t.Loader.KeepLink(t.Bsp.LinkerScript, preserve_elf)
+ err = t.LoaderBuilder.KeepLink(t.bspPkg.LinkerScript, preserveElf)
if err != nil {
return err, nil, nil
}
- return err, common_pkgs, sm_match
+ return err, commonPkgs, smMatch
}
-func (t *TargetBuilder) Test(p *pkg.LocalPackage) error {
- if err := t.target.Validate(false); err != nil {
- return err
- }
+func (t *TargetBuilder) Test() error {
+ // Inject the SELFTEST setting into the package under test. This setting
+ // indicates that the package needs to provide its own main().
+ t.testPkg.InjectedSettings()["SELFTEST"] = "1"
- if t.Bsp != nil {
- // Already prepped
- return nil
- }
- // Collect the seed packages.
- bspPkg := t.target.Bsp()
- if bspPkg == nil {
- if t.target.BspName == "" {
- return util.NewNewtError("BSP package not specified by target")
- } else {
- return util.NewNewtError("BSP package not found: " +
- t.target.BspName)
- }
+ cfgResolution, err := t.resolveCfgTest()
+ if err != nil {
+ return err
}
- t.Bsp = pkg.NewBspPackage(bspPkg)
- compilerPkg := t.resolveCompiler()
- if compilerPkg == nil {
- if t.Bsp.CompilerName == "" {
- return util.NewNewtError("Compiler package not specified by BSP")
- } else {
- return util.NewNewtError("Compiler package not found: " +
- t.Bsp.CompilerName)
- }
+ if err := t.validateAndWriteCfg(cfgResolution); err != nil {
+ return err
}
- t.compilerPkg = compilerPkg
- targetPkg := t.target.Package()
-
- app, err := NewBuilder(t, "test")
-
- if err == nil {
- t.App = app
- } else {
+ _, appPkgs, err := t.resolvePkgs(cfgResolution)
+ if err != nil {
return err
}
- // A few features are automatically supported when the test command is
- // used:
- // * TEST: ensures that the test code gets compiled.
- // * SELFTEST: indicates that there is no app.
- t.App.injectedSettings["TEST"] = "1"
- p.InjectedSettings()["SELFTEST"] = "1"
-
- t.App.AddPackage(p)
- err = t.App.PrepBuild(nil, bspPkg, targetPkg)
-
+ t.AppBuilder, err = NewBuilder(t, "test", appPkgs,
+ cfgResolution.ApiMap, cfgResolution.Cfg)
if err != nil {
return err
}
+ if err := t.AppBuilder.PrepBuild(); err != nil {
+ return err
+ }
- err = t.App.Test(p)
-
- return err
-}
+ if err := t.buildSysinit(cfgResolution); err != nil {
+ return err
+ }
-func (t *TargetBuilder) resolveCompiler() *pkg.LocalPackage {
- if t.Bsp.CompilerName == "" {
- return nil
+ if err := t.AppBuilder.Test(t.testPkg); err != nil {
+ return err
}
- dep, _ := pkg.NewDependency(t.Bsp.Repo(), t.Bsp.CompilerName)
- mypkg := project.GetProject().ResolveDependency(dep).(*pkg.LocalPackage)
- return mypkg
+
+ return nil
}
func (t *TargetBuilder) Clean() error {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/cli/build_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/build_cmds.go b/newt/cli/build_cmds.go
index 08118cc..7c7fb9d 100644
--- a/newt/cli/build_cmds.go
+++ b/newt/cli/build_cmds.go
@@ -44,8 +44,8 @@ func testablePkgs() map[*pkg.LocalPackage]struct{} {
testablePkgMap := map[*pkg.LocalPackage]struct{}{}
// Create a map of path => lclPkg.
- proj := project.GetProject()
- if proj == nil {
+ proj, err := project.TryGetProject()
+ if err != nil {
return nil
}
@@ -101,13 +101,14 @@ func pkgToUnitTests(pack *pkg.LocalPackage) []*pkg.LocalPackage {
var extraJtagCmd string
func buildRunCmd(cmd *cobra.Command, args []string) {
- if err := project.Initialize(); err != nil {
- NewtUsage(cmd, err)
- }
if len(args) < 1 {
NewtUsage(cmd, nil)
}
+ if _, err := project.TryGetProject(); err != nil {
+ NewtUsage(nil, err)
+ }
+
// Verify that all target names are valid.
_, err := ResolveTargets(args...)
if err != nil {
@@ -131,31 +132,31 @@ func buildRunCmd(cmd *cobra.Command, args []string) {
util.StatusMessage(util.VERBOSITY_DEFAULT, "Building target %s\n",
t.FullName())
- b, err := builder.NewTargetBuilder(t)
+ b, err := builder.NewTargetBuilder(t, nil)
if err != nil {
NewtUsage(nil, err)
}
- err = b.Build()
- if err != nil {
+ if err := b.Build(); err != nil {
NewtUsage(nil, err)
}
- util.StatusMessage(util.VERBOSITY_DEFAULT, "Target successfully built: "+
- "%s\n", targetName)
+ util.StatusMessage(util.VERBOSITY_DEFAULT,
+ "Target successfully built: %s\n", targetName)
/* TODO */
}
}
func cleanRunCmd(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"))
}
+ if _, err := project.TryGetProject(); err != nil {
+ NewtUsage(nil, err)
+ }
+
cleanAll := false
targets := []*target.Target{}
for _, arg := range args {
@@ -181,12 +182,11 @@ func cleanRunCmd(cmd *cobra.Command, args []string) {
}
} else {
for _, t := range targets {
- b, err := builder.NewTargetBuilder(t)
+ b, err := builder.NewTargetBuilder(t, nil)
if err != nil {
- NewtUsage(cmd, err)
+ NewtUsage(nil, err)
}
- err = b.Clean()
- if err != nil {
+ if err := b.Clean(); err != nil {
NewtUsage(cmd, err)
}
}
@@ -208,6 +208,11 @@ func testRunCmd(cmd *cobra.Command, args []string) {
NewtUsage(cmd, nil)
}
+ proj, err := project.TryGetProject()
+ if err != nil {
+ NewtUsage(nil, err)
+ }
+
// Verify and resolve each specified package.
testAll := false
packs := []*pkg.LocalPackage{}
@@ -215,7 +220,7 @@ func testRunCmd(cmd *cobra.Command, args []string) {
if pkgName == "all" {
testAll = true
} else {
- pack, err := ResolvePackage(pkgName)
+ pack, err := proj.ResolvePackage(proj.LocalRepo(), pkgName)
if err != nil {
NewtUsage(cmd, err)
}
@@ -230,8 +235,6 @@ func testRunCmd(cmd *cobra.Command, args []string) {
}
}
- proj := project.GetProject()
-
if testAll {
packItfs := proj.PackagesOfType(pkg.PACKAGE_TYPE_UNITTEST)
packs = make([]*pkg.LocalPackage, len(packItfs))
@@ -284,7 +287,7 @@ func testRunCmd(cmd *cobra.Command, args []string) {
}
}
- b, err := builder.NewTargetBuilder(t)
+ b, err := builder.NewTargetBuilder(t, pack)
if err != nil {
NewtUsage(nil, err)
}
@@ -292,16 +295,7 @@ func testRunCmd(cmd *cobra.Command, args []string) {
util.StatusMessage(util.VERBOSITY_DEFAULT, "Testing package %s\n",
pack.FullName())
- // The package under test needs to be resolved again now that the
- // project has been reset.
- newPack, err := ResolvePackage(pack.FullName())
- if err != nil {
- NewtUsage(nil, util.NewNewtError("Failed to resolve package: "+
- pack.Name()))
- }
- pack = newPack
-
- err = b.Test(pack)
+ err = b.Test()
if err == nil {
passedPkgs = append(passedPkgs, pack)
} else {
@@ -324,73 +318,73 @@ func testRunCmd(cmd *cobra.Command, args []string) {
}
func loadRunCmd(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"))
}
+ if _, err := project.TryGetProject(); err != nil {
+ NewtUsage(nil, err)
+ }
+
t := ResolveTarget(args[0])
if t == nil {
NewtUsage(cmd, util.NewNewtError("Invalid target name: "+args[0]))
}
- b, err := builder.NewTargetBuilder(t)
+ b, err := builder.NewTargetBuilder(t, nil)
if err != nil {
- NewtUsage(cmd, err)
+ NewtUsage(nil, err)
}
- err = b.Load(extraJtagCmd)
- if err != nil {
+ if err := b.Load(extraJtagCmd); err != nil {
NewtUsage(cmd, err)
}
}
func debugRunCmd(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"))
}
+ if _, err := project.TryGetProject(); err != nil {
+ NewtUsage(nil, err)
+ }
+
t := ResolveTarget(args[0])
if t == nil {
NewtUsage(cmd, util.NewNewtError("Invalid target name: "+args[0]))
}
- b, err := builder.NewTargetBuilder(t)
+ b, err := builder.NewTargetBuilder(t, nil)
if err != nil {
- NewtUsage(cmd, err)
+ NewtUsage(nil, err)
}
- err = b.Debug(extraJtagCmd, false)
- if err != nil {
+ if err := b.Debug(extraJtagCmd, false); err != nil {
NewtUsage(cmd, err)
}
}
func sizeRunCmd(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"))
}
+ if _, err := project.TryGetProject(); err != nil {
+ NewtUsage(nil, err)
+ }
+
t := ResolveTarget(args[0])
if t == nil {
NewtUsage(cmd, util.NewNewtError("Invalid target name: "+args[0]))
}
- b, err := builder.NewTargetBuilder(t)
+ b, err := builder.NewTargetBuilder(t, nil)
if err != nil {
- NewtUsage(cmd, err)
+ NewtUsage(nil, err)
}
- err = b.Size()
- if err != nil {
+ if err := b.Size(); err != nil {
NewtUsage(cmd, err)
}
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/cli/complete_cmd.go
----------------------------------------------------------------------
diff --git a/newt/cli/complete_cmd.go b/newt/cli/complete_cmd.go
index 68213da..31de297 100644
--- a/newt/cli/complete_cmd.go
+++ b/newt/cli/complete_cmd.go
@@ -36,8 +36,7 @@ import (
func targetList() []string {
targetNames := []string{}
- err := project.Initialize()
- if err != nil {
+ if _, err := project.TryGetProject(); err != nil {
return targetNames
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/cli/image_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/image_cmds.go b/newt/cli/image_cmds.go
index 50cb7ac..1e04c2c 100644
--- a/newt/cli/image_cmds.go
+++ b/newt/cli/image_cmds.go
@@ -65,13 +65,14 @@ func createImageRunCmd(cmd *cobra.Command, args []string) {
var keyId uint8
var keystr string
- if err := project.Initialize(); err != nil {
- NewtUsage(cmd, err)
- }
if len(args) < 2 {
NewtUsage(cmd, util.NewNewtError("Must specify target and version"))
}
+ if _, err := project.TryGetProject(); err != nil {
+ NewtUsage(nil, err)
+ }
+
targetName := args[0]
t := ResolveTarget(targetName)
if t == nil {
@@ -92,35 +93,35 @@ func createImageRunCmd(cmd *cobra.Command, args []string) {
keystr = args[2]
}
- b, err := builder.NewTargetBuilder(t)
+ b, err := builder.NewTargetBuilder(t, nil)
if err != nil {
- NewtUsage(cmd, err)
- return
+ NewtUsage(nil, err)
}
- err = b.PrepBuild()
- if err != nil {
+ if err := b.PrepBuild(); err != nil {
NewtUsage(cmd, err)
return
}
- var app_img *image.Image
- var loader_img *image.Image
+ var appImg *image.Image
+ var loaderImg *image.Image
- if b.Loader == nil {
- err, app_img = CreateImage(b.App, version, keystr, keyId, nil)
+ if b.LoaderBuilder == nil {
+ err, appImg = CreateImage(b.AppBuilder, version, keystr, keyId, nil)
if err != nil {
NewtUsage(cmd, err)
return
}
} else {
- err, loader_img = CreateImage(b.Loader, version, keystr, keyId, nil)
+ err, loaderImg = CreateImage(b.LoaderBuilder, version, keystr,
+ keyId, nil)
if err != nil {
NewtUsage(cmd, err)
return
}
- err, app_img = CreateImage(b.App, version, keystr, keyId, loader_img)
+ err, appImg = CreateImage(b.AppBuilder, version, keystr, keyId,
+ loaderImg)
if err != nil {
NewtUsage(cmd, err)
return
@@ -128,8 +129,12 @@ func createImageRunCmd(cmd *cobra.Command, args []string) {
}
- build_id := image.CreateBuildId(app_img, loader_img)
- err = image.CreateManifest(b, app_img, loader_img, build_id)
+ buildId := image.CreateBuildId(appImg, loaderImg)
+ if err := image.CreateManifest(b, appImg, loaderImg,
+ buildId); err != nil {
+
+ NewtUsage(nil, err)
+ }
}
func AddImageCommands(cmd *cobra.Command) {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/cli/project_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/project_cmds.go b/newt/cli/project_cmds.go
index 8b4dc43..e1377a8 100644
--- a/newt/cli/project_cmds.go
+++ b/newt/cli/project_cmds.go
@@ -75,10 +75,10 @@ func newRunCmd(cmd *cobra.Command, args []string) {
}
func installRunCmd(cmd *cobra.Command, args []string) {
- if err := project.Initialize(); err != nil {
- NewtUsage(cmd, err)
+ proj, err := project.TryGetProject()
+ if err != nil {
+ NewtUsage(nil, err)
}
- proj := project.GetProject()
interfaces.SetProject(proj)
if err := proj.Install(false, projectForce); err != nil {
@@ -87,10 +87,10 @@ func installRunCmd(cmd *cobra.Command, args []string) {
}
func upgradeRunCmd(cmd *cobra.Command, args []string) {
- if err := project.Initialize(); err != nil {
- NewtUsage(cmd, err)
+ proj, err := project.TryGetProject()
+ if err != nil {
+ NewtUsage(nil, err)
}
- proj := project.GetProject()
interfaces.SetProject(proj)
if err := proj.Upgrade(projectForce); err != nil {
@@ -104,10 +104,10 @@ func infoRunCmd(cmd *cobra.Command, args []string) {
reqRepoName = strings.TrimPrefix(args[0], "@")
}
- if err := project.Initialize(); err != nil {
+ proj, err := project.TryGetProject()
+ if err != nil {
NewtUsage(nil, err)
}
- proj := project.GetProject()
repoNames := []string{}
for repoName, _ := range proj.PackageList() {
@@ -160,7 +160,10 @@ func infoRunCmd(cmd *cobra.Command, args []string) {
}
func syncRunCmd(cmd *cobra.Command, args []string) {
- proj := project.GetProject()
+ proj, err := project.TryGetProject()
+ if err != nil {
+ NewtUsage(nil, err)
+ }
repos := proj.Repos()
ps, err := project.LoadProjectState()
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/cli/run_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/run_cmds.go b/newt/cli/run_cmds.go
index 9d2d2bf..8fa1afb 100644
--- a/newt/cli/run_cmds.go
+++ b/newt/cli/run_cmds.go
@@ -30,25 +30,25 @@ import (
)
func runRunCmd(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"))
}
+ if _, err := project.TryGetProject(); err != nil {
+ NewtUsage(nil, err)
+ }
+
t := ResolveTarget(args[0])
if t == nil {
NewtUsage(cmd, util.NewNewtError("Invalid target name: "+args[0]))
}
- b, err := builder.NewTargetBuilder(t)
+ b, err := builder.NewTargetBuilder(t, nil)
if err != nil {
NewtUsage(nil, err)
}
- err = b.Build()
- if err != nil {
+ if err := b.Build(); err != nil {
NewtUsage(nil, err)
}
@@ -58,48 +58,48 @@ func runRunCmd(cmd *cobra.Command, args []string) {
* will barf if it needs an image for this type of target, instead of
* downloading an older version.
*/
- var app_img *image.Image
- var loader_img *image.Image
+ var appImg *image.Image
+ var loaderImg *image.Image
+
if len(args) > 1 {
- if b.Loader == nil {
- err, app_img = CreateImage(b.App, args[1], "", 0, nil)
+ if b.LoaderBuilder == nil {
+ err, appImg = CreateImage(b.AppBuilder, args[1], "", 0, nil)
if err != nil {
NewtUsage(cmd, err)
}
} else {
- err, loader_img = CreateImage(b.Loader, args[1], "", 0, nil)
+ err, loaderImg = CreateImage(b.LoaderBuilder, args[1], "", 0, nil)
if err != nil {
NewtUsage(cmd, err)
}
- err, app_img = CreateImage(b.App, args[1], "", 0, loader_img)
+ err, appImg = CreateImage(b.AppBuilder, args[1], "", 0, loaderImg)
if err != nil {
NewtUsage(cmd, err)
}
}
} else {
- os.Remove(b.App.AppImgPath())
+ os.Remove(b.AppBuilder.AppImgPath())
- if b.Loader != nil {
- os.Remove(b.Loader.AppImgPath())
+ if b.LoaderBuilder != nil {
+ os.Remove(b.LoaderBuilder.AppImgPath())
}
}
- if app_img != nil {
- build_id := image.CreateBuildId(app_img, loader_img)
+ if appImg != nil {
+ buildId := image.CreateBuildId(appImg, loaderImg)
- err = image.CreateManifest(b, app_img, loader_img, build_id)
- if err != nil {
- NewtUsage(cmd, err)
+ if err := image.CreateManifest(b, appImg, loaderImg,
+ buildId); err != nil {
+
+ NewtUsage(nil, err)
}
}
- err = b.Load(extraJtagCmd)
- if err != nil {
- NewtUsage(cmd, err)
+ if err := b.Load(extraJtagCmd); err != nil {
+ NewtUsage(nil, err)
}
- err = b.Debug(extraJtagCmd, true)
- if err != nil {
- NewtUsage(cmd, err)
+ if err := b.Debug(extraJtagCmd, true); err != nil {
+ NewtUsage(nil, err)
}
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/cli/target_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/target_cmds.go b/newt/cli/target_cmds.go
index dca4163..631aa75 100644
--- a/newt/cli/target_cmds.go
+++ b/newt/cli/target_cmds.go
@@ -71,7 +71,7 @@ func targetContainsUserFiles(t *target.Target) (bool, error) {
}
func pkgVarSliceString(pack *pkg.LocalPackage, key string) string {
- features := pack.Viper.GetStringSlice(key)
+ features := pack.PkgV.GetStringSlice(key)
sort.Strings(features)
var buffer bytes.Buffer
@@ -83,8 +83,8 @@ func pkgVarSliceString(pack *pkg.LocalPackage, key string) string {
}
func targetShowCmd(cmd *cobra.Command, args []string) {
- if err := project.Initialize(); err != nil {
- NewtUsage(cmd, err)
+ if _, err := project.TryGetProject(); err != nil {
+ NewtUsage(nil, err)
}
targetNames := []string{}
if len(args) == 0 {
@@ -143,15 +143,16 @@ func targetShowCmd(cmd *cobra.Command, args []string) {
}
func targetSetCmd(cmd *cobra.Command, args []string) {
- if err := project.Initialize(); err != nil {
- NewtUsage(cmd, err)
- }
if len(args) < 2 {
NewtUsage(cmd,
util.NewNewtError("Must specify at least two arguments "+
"(target-name & k=v) to set"))
}
+ if _, err := project.TryGetProject(); err != nil {
+ NewtUsage(nil, err)
+ }
+
// Parse target name.
t, err := resolveExistingTargetArg(args[0])
if err != nil {
@@ -191,9 +192,9 @@ func targetSetCmd(cmd *cobra.Command, args []string) {
kv[0] = "pkg." + strings.TrimPrefix(kv[0], "target.")
if kv[1] == "" {
// User specified empty value; delete variable.
- t.Package().Viper.Set(kv[0], nil)
+ t.Package().PkgV.Set(kv[0], nil)
} else {
- t.Package().Viper.Set(kv[0], strings.Fields(kv[1]))
+ t.Package().PkgV.Set(kv[0], strings.Fields(kv[1]))
}
} else {
if kv[1] == "" {
@@ -223,19 +224,21 @@ func targetSetCmd(cmd *cobra.Command, args []string) {
}
func targetCreateCmd(cmd *cobra.Command, args []string) {
- if err := project.Initialize(); err != nil {
- NewtUsage(cmd, err)
- }
if len(args) != 1 {
NewtUsage(cmd, util.NewNewtError("Missing target name"))
}
+ proj, err := project.TryGetProject()
+ if err != nil {
+ NewtUsage(nil, err)
+ }
+
pkgName, err := ResolveNewTargetName(args[0])
if err != nil {
NewtUsage(cmd, err)
}
- repo := project.GetProject().LocalRepo()
+ repo := proj.LocalRepo()
pack := pkg.NewLocalPackage(repo, repo.Path()+"/"+pkgName)
pack.SetName(pkgName)
pack.SetType(pkg.PACKAGE_TYPE_TARGET)
@@ -281,14 +284,15 @@ func targetDelOne(t *target.Target) error {
}
func targetDelCmd(cmd *cobra.Command, args []string) {
- if err := project.Initialize(); err != nil {
- NewtUsage(cmd, err)
- }
if len(args) < 1 {
NewtUsage(cmd, util.NewNewtError("Must specify at least one "+
"target to delete"))
}
+ if _, err := project.TryGetProject(); err != nil {
+ NewtUsage(nil, err)
+ }
+
targets, err := ResolveTargets(args...)
if err != nil {
NewtUsage(cmd, err)
@@ -302,14 +306,16 @@ func targetDelCmd(cmd *cobra.Command, args []string) {
}
func targetCopyCmd(cmd *cobra.Command, args []string) {
- if err := project.Initialize(); err != nil {
- NewtUsage(cmd, err)
- }
if len(args) != 2 {
NewtUsage(cmd, util.NewNewtError("Must specify exactly one "+
"source target and one destination target"))
}
+ proj, err := project.TryGetProject()
+ if err != nil {
+ NewtUsage(nil, err)
+ }
+
srcTarget, err := resolveExistingTargetArg(args[0])
if err != nil {
NewtUsage(cmd, err)
@@ -322,7 +328,7 @@ func targetCopyCmd(cmd *cobra.Command, args []string) {
// Copy the source target's base package and adjust the fields which need
// to change.
- dstTarget := srcTarget.Clone(project.GetProject().LocalRepo(), dstName)
+ dstTarget := srcTarget.Clone(proj.LocalRepo(), dstName)
// Save the new target.
err = dstTarget.Save()
@@ -345,10 +351,6 @@ func printSetting(entry syscfg.CfgEntry) {
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 {
@@ -377,7 +379,12 @@ func printPkgCfg(pkgName string, cfg syscfg.Cfg, entries []syscfg.CfgEntry) {
}
}
-func printCfg(cfg syscfg.Cfg) {
+func printCfg(targetName string, cfg syscfg.Cfg) {
+ if errText := cfg.ErrorText(); errText != "" {
+ util.StatusMessage(util.VERBOSITY_DEFAULT, "!!! %s\n\n", errText)
+ }
+
+ util.StatusMessage(util.VERBOSITY_DEFAULT, "Syscfg for %s:\n", targetName)
pkgNameEntryMap := syscfg.EntriesByPkg(cfg)
pkgNames := make([]string, 0, len(pkgNameEntryMap))
@@ -395,28 +402,30 @@ func printCfg(cfg syscfg.Cfg) {
}
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"))
}
+ if _, err := project.TryGetProject(); err != nil {
+ NewtUsage(nil, err)
+ }
+
t, err := resolveExistingTargetArg(args[0])
if err != nil {
NewtUsage(cmd, err)
}
- b, err := builder.NewTargetBuilder(t)
+ b, err := builder.NewTargetBuilder(t, nil)
if err != nil {
NewtUsage(nil, err)
}
- if err := b.PrepBuild(); err != nil {
+ cfgResolution, err := b.ExportCfg()
+ if err != nil {
NewtUsage(nil, err)
}
- printCfg(b.App.Cfg)
+ printCfg(t.Name(), cfgResolution.Cfg)
}
func AddTargetCommands(cmd *cobra.Command) {
@@ -514,7 +523,7 @@ func AddTargetCommands(cmd *cobra.Command) {
configHelpText := "View a target's system configuration."
configCmd := &cobra.Command{
- Use: "config <target-name>",
+ Use: "config",
Short: "View target system configuration",
Long: configHelpText,
Run: targetConfigCmd,
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/cli/util.go
----------------------------------------------------------------------
diff --git a/newt/cli/util.go b/newt/cli/util.go
index 5db85e7..23615bb 100644
--- a/newt/cli/util.go
+++ b/newt/cli/util.go
@@ -149,27 +149,6 @@ func ResolveNewTargetName(name string) (string, error) {
return pkgName, nil
}
-func ResolvePackage(name string) (*pkg.LocalPackage, error) {
- // Trim trailing slash from name. This is necessary when tab
- // completion is used to specify the name.
- name = strings.TrimSuffix(name, "/")
-
- dep, err := pkg.NewDependency(nil, name)
- if err != nil {
- return nil, util.FmtNewtError("invalid package name: %s (%s)", name,
- err.Error())
- }
- if dep == nil {
- return nil, util.NewNewtError("invalid package name: " + name)
- }
- pack := project.GetProject().ResolveDependency(dep)
- if pack == nil {
- return nil, util.NewNewtError("unknown package: " + name)
- }
-
- return pack.(*pkg.LocalPackage), nil
-}
-
func PackageNameList(pkgs []*pkg.LocalPackage) string {
var buffer bytes.Buffer
for i, pack := range pkgs {
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/cli/vars.go
----------------------------------------------------------------------
diff --git a/newt/cli/vars.go b/newt/cli/vars.go
index 45859ea..91fe4f4 100644
--- a/newt/cli/vars.go
+++ b/newt/cli/vars.go
@@ -55,7 +55,7 @@ func settingValues(settingName string) ([]string, error) {
packs := project.GetProject().PackagesOfType(-1)
for _, pack := range packs {
settings :=
- pack.(*pkg.LocalPackage).Viper.GetStringSlice(settingName)
+ pack.(*pkg.LocalPackage).PkgV.GetStringSlice(settingName)
for _, setting := range settings {
settingMap[setting] = struct{}{}
@@ -141,6 +141,11 @@ var varsMap = map[string]func() ([]string, error){
// Returns a slice of valid values for the target variable with the specified
// name. If an invalid target variable is specified, an error is returned.
func VarValues(varName string) ([]string, error) {
+ _, err := project.TryGetProject()
+ if err != nil {
+ return nil, err
+ }
+
fn := varsMap[varName]
if fn == nil {
err := util.NewNewtError(fmt.Sprintf("Unknown setting name: \"%s\"",
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/image/image.go
----------------------------------------------------------------------
diff --git a/newt/image/image.go b/newt/image/image.go
index 52432d9..cc57d3a 100644
--- a/newt/image/image.go
+++ b/newt/image/image.go
@@ -464,7 +464,7 @@ func CreateManifest(t *builder.TargetBuilder, app *Image, loader *Image, build_i
Date: timeStr,
}
- for _, builtPkg := range t.App.Packages {
+ for _, builtPkg := range t.AppBuilder.PkgMap {
imgPkg := &ImageManifestPkg{
Name: builtPkg.Name(),
}
@@ -475,7 +475,7 @@ func CreateManifest(t *builder.TargetBuilder, app *Image, loader *Image, build_i
manifest.Loader = filepath.Base(loader.targetImg)
manifest.LoaderHash = fmt.Sprintf("%x", loader.hash)
- for _, builtPkg := range t.Loader.Packages {
+ for _, builtPkg := range t.LoaderBuilder.PkgMap {
imgPkg := &ImageManifestPkg{
Name: builtPkg.Name(),
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/newt.go
----------------------------------------------------------------------
diff --git a/newt/newt.go b/newt/newt.go
index 7f9f244..de37ad8 100644
--- a/newt/newt.go
+++ b/newt/newt.go
@@ -28,7 +28,6 @@ import (
"mynewt.apache.org/newt/newt/cli"
"mynewt.apache.org/newt/newt/newtutil"
- "mynewt.apache.org/newt/newt/project"
"mynewt.apache.org/newt/util"
)
@@ -121,8 +120,6 @@ func main() {
hold_lvl := log.GetLevel()
log.SetLevel(log.FatalLevel)
- project.Initialize()
-
cli.AddCompleteCommands(cmd)
cli.AddProjectCommands(cmd)
cli.AddTargetCommands(cmd)
@@ -149,5 +146,7 @@ func main() {
}
log.SetLevel(hold_lvl)
- cmd.Execute()
+ if err := cmd.Execute(); err != nil {
+ cli.NewtUsage(nil, err)
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/dd715c24/newt/pkg/bsp_package.go
----------------------------------------------------------------------
diff --git a/newt/pkg/bsp_package.go b/newt/pkg/bsp_package.go
index a50a61a..99fab5f 100644
--- a/newt/pkg/bsp_package.go
+++ b/newt/pkg/bsp_package.go
@@ -35,17 +35,17 @@ type BspPackage struct {
}
func (bsp *BspPackage) Reload(features map[string]bool) error {
- bsp.CompilerName = newtutil.GetStringFeatures(bsp.LocalPackage.Viper,
+ bsp.CompilerName = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
features, "pkg.compiler")
- bsp.Arch = newtutil.GetStringFeatures(bsp.LocalPackage.Viper,
+ bsp.Arch = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
features, "pkg.arch")
- bsp.LinkerScript = newtutil.GetStringFeatures(bsp.LocalPackage.Viper,
+ bsp.LinkerScript = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
features, "pkg.linkerscript")
- bsp.Part2LinkerScript = newtutil.GetStringFeatures(bsp.LocalPackage.Viper,
+ bsp.Part2LinkerScript = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
features, "pkg.part2linkerscript")
- bsp.DownloadScript = newtutil.GetStringFeatures(bsp.LocalPackage.Viper,
+ bsp.DownloadScript = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
features, "pkg.downloadscript")
- bsp.DebugScript = newtutil.GetStringFeatures(bsp.LocalPackage.Viper,
+ bsp.DebugScript = newtutil.GetStringFeatures(bsp.LocalPackage.PkgV,
features, "pkg.debugscript")
if bsp.CompilerName == "" {