Repository: incubator-mynewt-newt
Updated Branches:
  refs/heads/develop e322f97cd -> 046317aa3


MYNEWT-558 newt - depgraph should show api / hard

The `target dep` and `target revdep` commands only indicated package
names in the dependency graph.  This change enhances the output of these
commands to show what created the dependency in the first place.
Specifically, they now show whether the dependency is "hard" (package
explicitly depends on another) or "soft" (package requires an API; other
package happens to implement that API).  This is useful when trying to
completely remove a package from a build.

In the future, we should also indicate which, if any, syscfg settings
generated a particular dependency.

The fix required a lot of changes to the newt code.  The major change
was to scale back the responsibilities of the pkg.LocalPackage type.
This struct was being used during build and depgraph resolution, and its
client relied on its inheritance of the pkg.Package interface.
Consequently, it was difficult to add new features without breaking
everything or bloating the LocalPackage struct.

Now, instances of LocalPackage get converted to resolve.ResolvePackage
during dependency and API resolution.  Furthermore, builder.BuildPackage
and resolve.ResolvePackage no longer inherit from LocalPackage.
Instead, each contains a pointer to its corresponding LocalPackage or
ResolvePackage.  Since these types never need to be treated as generic
package types, the code is simplified by eliminating these edges from
the inheritance tree.


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

Branch: refs/heads/develop
Commit: e4ac2617615ad95fc5b56591b2576fc0ee978332
Parents: e322f97
Author: Christopher Collins <ccoll...@apache.org>
Authored: Thu Feb 2 07:30:00 2017 -0800
Committer: Christopher Collins <ccoll...@apache.org>
Committed: Sun Feb 5 12:17:47 2017 -0800

----------------------------------------------------------------------
 newt/builder/build.go        |  98 +++++++++--------
 newt/builder/buildpackage.go |  59 +++++------
 newt/builder/buildutil.go    |  32 +++---
 newt/builder/depgraph.go     | 102 +++++++++---------
 newt/builder/library.go      |   2 +-
 newt/builder/load.go         |   2 +-
 newt/builder/paths.go        |  30 +++---
 newt/builder/selftest.go     |  86 ++++++++++-----
 newt/builder/targetbuild.go  |  75 +++++++------
 newt/cli/target_cmds.go      |  26 ++---
 newt/cli/util.go             |  23 ++++
 newt/pkg/localpackage.go     |  32 ------
 newt/pkg/package.go          |   2 -
 newt/resolve/resolve.go      | 218 +++++++++++++++++++++++++-------------
 newt/resolve/resolveutil.go  |  92 ++++++++++++++++
 15 files changed, 538 insertions(+), 341 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/builder/build.go
----------------------------------------------------------------------
diff --git a/newt/builder/build.go b/newt/builder/build.go
index 232a39e..d82d9ff 100644
--- a/newt/builder/build.go
+++ b/newt/builder/build.go
@@ -30,6 +30,7 @@ import (
        "mynewt.apache.org/newt/newt/newtutil"
        "mynewt.apache.org/newt/newt/pkg"
        "mynewt.apache.org/newt/newt/repo"
+       "mynewt.apache.org/newt/newt/resolve"
        "mynewt.apache.org/newt/newt/symbol"
        "mynewt.apache.org/newt/newt/syscfg"
        "mynewt.apache.org/newt/newt/target"
@@ -38,7 +39,7 @@ import (
 )
 
 type Builder struct {
-       PkgMap map[*pkg.LocalPackage]*BuildPackage
+       PkgMap map[*resolve.ResolvePackage]*BuildPackage
 
        apiMap           map[string]*BuildPackage
        appPkg           *BuildPackage
@@ -54,11 +55,15 @@ type Builder struct {
        injectedSettings map[string]string
 }
 
-func NewBuilder(t *TargetBuilder, buildName string, lpkgs []*pkg.LocalPackage,
-       apiMap map[string]*pkg.LocalPackage, cfg syscfg.Cfg) (*Builder, error) {
+func NewBuilder(
+       t *TargetBuilder,
+       buildName string,
+       rpkgs []*resolve.ResolvePackage,
+       apiMap map[string]*resolve.ResolvePackage,
+       cfg syscfg.Cfg) (*Builder, error) {
 
        b := &Builder{
-               PkgMap: make(map[*pkg.LocalPackage]*BuildPackage, len(lpkgs)),
+               PkgMap: make(map[*resolve.ResolvePackage]*BuildPackage, 
len(rpkgs)),
                cfg:    cfg,
 
                buildName:        buildName,
@@ -68,8 +73,8 @@ func NewBuilder(t *TargetBuilder, buildName string, lpkgs 
[]*pkg.LocalPackage,
                injectedSettings: map[string]string{},
        }
 
-       for _, lpkg := range lpkgs {
-               if _, err := b.addPackage(lpkg); err != nil {
+       for _, rpkg := range rpkgs {
+               if _, err := b.addPackage(rpkg); err != nil {
                        return nil, err
                }
        }
@@ -79,15 +84,15 @@ func NewBuilder(t *TargetBuilder, buildName string, lpkgs 
[]*pkg.LocalPackage,
                return nil, err
        }
 
-       for api, lpkg := range apiMap {
-               bpkg := b.PkgMap[lpkg]
+       for api, rpkg := range apiMap {
+               bpkg := b.PkgMap[rpkg]
                if bpkg == nil {
-                       for _, lpkg := range b.sortedLocalPackages() {
-                               log.Debugf("    * %s", lpkg.Name())
+                       for _, rpkg := range b.sortedRpkgs() {
+                               log.Debugf("    * %s", rpkg.Lpkg.Name())
                        }
                        return nil, util.FmtNewtError(
                                "Unexpected unsatisfied API: %s; required by: 
%s", api,
-                               lpkg.Name())
+                               rpkg.Lpkg.Name())
                }
 
                b.apiMap[api] = bpkg
@@ -96,17 +101,19 @@ func NewBuilder(t *TargetBuilder, buildName string, lpkgs 
[]*pkg.LocalPackage,
        return b, nil
 }
 
-func (b *Builder) addPackage(npkg *pkg.LocalPackage) (*BuildPackage, error) {
+func (b *Builder) addPackage(rpkg *resolve.ResolvePackage) (
+       *BuildPackage, error) {
+
        // Don't allow nil entries to the map
-       if npkg == nil {
+       if rpkg == nil {
                panic("Cannot add nil package builder map")
        }
 
-       bpkg := b.PkgMap[npkg]
+       bpkg := b.PkgMap[rpkg]
        if bpkg == nil {
-               bpkg = NewBuildPackage(npkg)
+               bpkg = NewBuildPackage(rpkg)
 
-               switch bpkg.Type() {
+               switch bpkg.rpkg.Lpkg.Type() {
                case pkg.PACKAGE_TYPE_APP:
                        if b.appPkg != nil {
                                return nil, pkgTypeConflictErr(b.appPkg, bpkg)
@@ -132,7 +139,7 @@ func (b *Builder) addPackage(npkg *pkg.LocalPackage) 
(*BuildPackage, error) {
                        b.targetPkg = bpkg
                }
 
-               b.PkgMap[npkg] = bpkg
+               b.PkgMap[rpkg] = bpkg
        }
 
        return bpkg, nil
@@ -140,7 +147,9 @@ func (b *Builder) addPackage(npkg *pkg.LocalPackage) 
(*BuildPackage, error) {
 
 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())
+               pkg.PackageTypeNames[p1.rpkg.Lpkg.Type()],
+               p1.rpkg.Lpkg.Name(),
+               p2.rpkg.Lpkg.Name())
 }
 
 // Recursively compiles all the .c and .s files in the specified directory.
@@ -243,7 +252,8 @@ func (b *Builder) newCompiler(bpkg *BuildPackage,
        c.AddInfo(b.compilerInfo)
 
        if bpkg != nil {
-               log.Debugf("Generating build flags for package %s", 
bpkg.FullName())
+               log.Debugf("Generating build flags for package %s",
+                       bpkg.rpkg.Lpkg.FullName())
                ci, err := bpkg.CompilerInfo(b)
                if err != nil {
                        return nil, err
@@ -266,7 +276,7 @@ func (b *Builder) collectCompileEntriesBpkg(bpkg 
*BuildPackage) (
 
        if len(bpkg.SourceDirectories) > 0 {
                for _, relDir := range bpkg.SourceDirectories {
-                       dir := bpkg.BasePath() + "/" + relDir
+                       dir := bpkg.rpkg.Lpkg.BasePath() + "/" + relDir
                        if util.NodeNotExist(dir) {
                                return nil, util.NewNewtError(fmt.Sprintf(
                                        "Specified source directory %s, does 
not exist.",
@@ -275,7 +285,7 @@ func (b *Builder) collectCompileEntriesBpkg(bpkg 
*BuildPackage) (
                        srcDirs = append(srcDirs, dir)
                }
        } else {
-               srcDir := bpkg.BasePath() + "/src"
+               srcDir := bpkg.rpkg.Lpkg.BasePath() + "/src"
                if util.NodeNotExist(srcDir) {
                        // Nothing to compile.
                        return nil, nil
@@ -302,7 +312,7 @@ func (b *Builder) createArchive(c *toolchain.Compiler,
        bpkg *BuildPackage) error {
 
        // Create a static library ("archive").
-       c.SetSrcDir(bpkg.RelativePath())
+       c.SetSrcDir(bpkg.rpkg.Lpkg.RelativePath())
        archiveFile := b.ArchivePath(bpkg)
        if err := c.CompileArchive(archiveFile); err != nil {
                return err
@@ -314,7 +324,7 @@ func (b *Builder) createArchive(c *toolchain.Compiler,
 func (b *Builder) RemovePackages(cmn map[string]bool) error {
        for pkgName, _ := range cmn {
                for lp, bpkg := range b.PkgMap {
-                       if bpkg.Name() == pkgName {
+                       if bpkg.rpkg.Lpkg.Name() == pkgName {
                                delete(b.PkgMap, lp)
                        }
                }
@@ -387,7 +397,7 @@ func (b *Builder) PrepBuild() error {
 
        // Target flags.
        log.Debugf("Generating build flags for target %s",
-               b.targetPkg.FullName())
+               b.targetPkg.rpkg.Lpkg.FullName())
        targetCi, err := b.targetPkg.CompilerInfo(b)
        if err != nil {
                return err
@@ -396,7 +406,8 @@ func (b *Builder) PrepBuild() error {
 
        // App flags.
        if b.appPkg != nil {
-               log.Debugf("Generating build flags for app %s", 
b.appPkg.FullName())
+               log.Debugf("Generating build flags for app %s",
+                       b.appPkg.rpkg.Lpkg.FullName())
                appCi, err := b.appPkg.CompilerInfo(b)
                if err != nil {
                        return err
@@ -406,7 +417,8 @@ func (b *Builder) PrepBuild() error {
        }
 
        // Bsp flags.
-       log.Debugf("Generating build flags for bsp %s", b.bspPkg.FullName())
+       log.Debugf("Generating build flags for bsp %s",
+               b.bspPkg.rpkg.Lpkg.FullName())
        bspCi, err := b.bspPkg.CompilerInfo(b)
        if err != nil {
                return err
@@ -420,12 +432,12 @@ func (b *Builder) PrepBuild() error {
        bspCi.Cflags = append(bspCi.Cflags, "-DARCH_NAME="+archName+"")
 
        if b.appPkg != nil {
-               appName := filepath.Base(b.appPkg.Name())
+               appName := filepath.Base(b.appPkg.rpkg.Lpkg.Name())
                bspCi.Cflags = append(bspCi.Cflags, 
"-DAPP_"+util.CIdentifier(appName))
                bspCi.Cflags = append(bspCi.Cflags, "-DAPP_NAME="+appName+"")
        }
 
-       bspName := filepath.Base(b.bspPkg.Name())
+       bspName := filepath.Base(b.bspPkg.rpkg.Lpkg.Name())
        bspCi.Cflags = append(bspCi.Cflags, "-DBSP_"+util.CIdentifier(bspName))
        bspCi.Cflags = append(bspCi.Cflags, "-DBSP_NAME="+bspName+"")
 
@@ -433,7 +445,7 @@ func (b *Builder) PrepBuild() error {
 
        // All packages have access to the generated code header directory.
        baseCi.Cflags = append(baseCi.Cflags,
-               "-I"+GeneratedIncludeDir(b.targetPkg.Name()))
+               "-I"+GeneratedIncludeDir(b.targetPkg.rpkg.Lpkg.Name()))
 
        // Note: Compiler flags get added at the end, after the flags for 
library
        // package being built are calculated.
@@ -447,12 +459,14 @@ func (b *Builder) AddCompilerInfo(info 
*toolchain.CompilerInfo) {
 }
 
 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 := pkg.NewLocalPackage(b.targetPkg.rpkg.Lpkg.Repo().(*repo.Repo),
+               GeneratedBaseDir(b.targetPkg.rpkg.Lpkg.Name()))
+       lpkg.SetName(pkg.ShortName(b.targetPkg.rpkg.Lpkg) + "-sysinit-" +
+               b.buildName)
        lpkg.SetType(pkg.PACKAGE_TYPE_GENERATED)
 
-       return b.addPackage(lpkg)
+       rpkg := resolve.NewResolvePkg(lpkg)
+       return b.addPackage(rpkg)
 }
 
 // Runs build jobs while any remain.  On failure, signals the other workers to
@@ -588,9 +602,9 @@ func (b *Builder) TentativeLink(linkerScripts []string) 
error {
 }
 
 func (b *Builder) pkgWithPath(path string) *BuildPackage {
-       for _, p := range b.PkgMap {
-               if p.BasePath() == path {
-                       return p
+       for _, bpkg := range b.PkgMap {
+               if bpkg.rpkg.Lpkg.BasePath() == path {
+                       return bpkg
                }
        }
 
@@ -598,21 +612,21 @@ func (b *Builder) pkgWithPath(path string) *BuildPackage {
 }
 
 func (b *Builder) FetchSymbolMap() (error, *symbol.SymbolMap) {
-       loader_sm := symbol.NewSymbolMap()
+       loaderSm := symbol.NewSymbolMap()
 
-       for _, value := range b.PkgMap {
-               err, sm := b.ParseObjectLibrary(value)
+       for _, bpkg := range b.PkgMap {
+               err, sm := b.ParseObjectLibrary(bpkg)
                if err == nil {
                        util.StatusMessage(util.VERBOSITY_VERBOSE,
-                               "Size of %s Loader Map %d\n", value.Name(), 
len(*sm))
-                       loader_sm, err = loader_sm.Merge(sm)
+                               "Size of %s Loader Map %d\n", 
bpkg.rpkg.Lpkg.Name(), len(*sm))
+                       loaderSm, err = loaderSm.Merge(sm)
                        if err != nil {
                                return err, nil
                        }
                }
        }
 
-       return nil, loader_sm
+       return nil, loaderSm
 }
 
 func (b *Builder) GetTarget() *target.Target {

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/builder/buildpackage.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildpackage.go b/newt/builder/buildpackage.go
index 5071185..e82566f 100644
--- a/newt/builder/buildpackage.go
+++ b/newt/builder/buildpackage.go
@@ -26,22 +26,21 @@ import (
 
        "mynewt.apache.org/newt/newt/newtutil"
        "mynewt.apache.org/newt/newt/pkg"
-       "mynewt.apache.org/newt/newt/project"
+       "mynewt.apache.org/newt/newt/resolve"
        "mynewt.apache.org/newt/newt/syscfg"
        "mynewt.apache.org/newt/newt/toolchain"
        "mynewt.apache.org/newt/util"
 )
 
 type BuildPackage struct {
-       *pkg.LocalPackage
-
-       ci                *toolchain.CompilerInfo
+       rpkg              *resolve.ResolvePackage
        SourceDirectories []string
+       ci                *toolchain.CompilerInfo
 }
 
-func NewBuildPackage(pkg *pkg.LocalPackage) *BuildPackage {
+func NewBuildPackage(rpkg *resolve.ResolvePackage) *BuildPackage {
        bpkg := &BuildPackage{
-               LocalPackage: pkg,
+               rpkg: rpkg,
        }
 
        return bpkg
@@ -58,22 +57,11 @@ func (bpkg *BuildPackage) collectDepsAux(b *Builder,
 
        (*set)[bpkg] = true
 
-       for _, dep := range bpkg.Deps() {
-               if dep.Name == "" {
-                       break
-               }
-
-               // Get pkg structure
-               p := project.GetProject().ResolveDependency(dep)
-               if p == nil {
-                       return util.FmtNewtError("Cannot resolve dependency 
%+v", dep)
-               }
-               dpkg := p.(*pkg.LocalPackage)
-
-               dbpkg := b.PkgMap[dpkg]
+       for _, dep := range bpkg.rpkg.Deps {
+               dbpkg := b.PkgMap[dep.Rpkg]
                if dbpkg == nil {
                        return util.FmtNewtError("Package not found %s; 
required by %s",
-                               dpkg.Name(), bpkg.Name())
+                               dbpkg.rpkg.Lpkg.Name(), bpkg.rpkg.Lpkg.Name())
                }
 
                if err := dbpkg.collectDepsAux(b, set); err != nil {
@@ -140,30 +128,30 @@ func (bpkg *BuildPackage) CompilerInfo(
        }
 
        ci := toolchain.NewCompilerInfo()
-       features := b.cfg.FeaturesForLpkg(bpkg.LocalPackage)
+       features := b.cfg.FeaturesForLpkg(bpkg.rpkg.Lpkg)
 
        // Read each set of flags and expand repo designators ("@<repo-nme>") 
into
        // paths.
-       ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.PkgV, features,
+       ci.Cflags = newtutil.GetStringSliceFeatures(bpkg.rpkg.Lpkg.PkgV, 
features,
                "pkg.cflags")
        expandFlags(ci.Cflags)
 
-       ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.PkgV, features,
+       ci.Lflags = newtutil.GetStringSliceFeatures(bpkg.rpkg.Lpkg.PkgV, 
features,
                "pkg.lflags")
        expandFlags(ci.Lflags)
 
-       ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.PkgV, features,
+       ci.Aflags = newtutil.GetStringSliceFeatures(bpkg.rpkg.Lpkg.PkgV, 
features,
                "pkg.aflags")
        expandFlags(ci.Aflags)
 
        // Package-specific injected settings get specified as C flags on the
        // command line.
-       for k, _ := range bpkg.InjectedSettings() {
+       for k, _ := range bpkg.rpkg.Lpkg.InjectedSettings() {
                ci.Cflags = append(ci.Cflags, syscfg.FeatureToCflag(k))
        }
 
        ci.IgnoreFiles = []*regexp.Regexp{}
-       ignPats := newtutil.GetStringSliceFeatures(bpkg.PkgV,
+       ignPats := newtutil.GetStringSliceFeatures(bpkg.rpkg.Lpkg.PkgV,
                features, "pkg.ign_files")
        for _, str := range ignPats {
                re, err := regexp.Compile(str)
@@ -175,7 +163,7 @@ func (bpkg *BuildPackage) CompilerInfo(
        }
 
        ci.IgnoreDirs = []*regexp.Regexp{}
-       ignPats = newtutil.GetStringSliceFeatures(bpkg.PkgV,
+       ignPats = newtutil.GetStringSliceFeatures(bpkg.rpkg.Lpkg.PkgV,
                features, "pkg.ign_dirs")
        for _, str := range ignPats {
                re, err := regexp.Compile(str)
@@ -186,7 +174,8 @@ func (bpkg *BuildPackage) CompilerInfo(
                ci.IgnoreDirs = append(ci.IgnoreDirs, re)
        }
 
-       bpkg.SourceDirectories = newtutil.GetStringSliceFeatures(bpkg.PkgV,
+       bpkg.SourceDirectories = newtutil.GetStringSliceFeatures(
+               bpkg.rpkg.Lpkg.PkgV,
                features, "pkg.src_dirs")
 
        includePaths, err := bpkg.recursiveIncludePaths(b)
@@ -201,7 +190,7 @@ func (bpkg *BuildPackage) CompilerInfo(
 }
 
 func (bpkg *BuildPackage) findSdkIncludes() []string {
-       sdkDir := bpkg.BasePath() + "/src/ext/"
+       sdkDir := bpkg.rpkg.Lpkg.BasePath() + "/src/ext/"
 
        sdkPathList := []string{}
        err := filepath.Walk(sdkDir,
@@ -221,15 +210,15 @@ func (bpkg *BuildPackage) findSdkIncludes() []string {
 }
 
 func (bpkg *BuildPackage) publicIncludeDirs(bspPkg *pkg.BspPackage) []string {
-       pkgBase := filepath.Base(bpkg.Name())
-       bp := bpkg.BasePath()
+       pkgBase := filepath.Base(bpkg.rpkg.Lpkg.Name())
+       bp := bpkg.rpkg.Lpkg.BasePath()
 
        incls := []string{
                bp + "/include",
                bp + "/include/" + pkgBase + "/arch/" + bspPkg.Arch,
        }
 
-       if bpkg.Type() == pkg.PACKAGE_TYPE_SDK {
+       if bpkg.rpkg.Lpkg.Type() == pkg.PACKAGE_TYPE_SDK {
                incls = append(incls, bspPkg.BasePath()+"/include/bsp/")
 
                sdkIncls := bpkg.findSdkIncludes()
@@ -240,17 +229,17 @@ func (bpkg *BuildPackage) publicIncludeDirs(bspPkg 
*pkg.BspPackage) []string {
 }
 
 func (bpkg *BuildPackage) privateIncludeDirs(b *Builder) []string {
-       srcDir := bpkg.BasePath() + "/src/"
+       srcDir := bpkg.rpkg.Lpkg.BasePath() + "/src/"
 
        incls := []string{}
        incls = append(incls, srcDir)
        incls = append(incls, srcDir+"/arch/"+b.targetBuilder.bspPkg.Arch)
 
-       switch bpkg.Type() {
+       switch bpkg.rpkg.Lpkg.Type() {
        case pkg.PACKAGE_TYPE_SDK:
                // If pkgType == SDK, include all the items in "ext" directly 
into the
                // include path
-               incls = append(incls, b.bspPkg.BasePath()+"/include/bsp/")
+               incls = append(incls, 
b.bspPkg.rpkg.Lpkg.BasePath()+"/include/bsp/")
 
                sdkIncls := bpkg.findSdkIncludes()
                incls = append(incls, sdkIncls...)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/builder/buildutil.go
----------------------------------------------------------------------
diff --git a/newt/builder/buildutil.go b/newt/builder/buildutil.go
index e8299ff..15ab0c2 100644
--- a/newt/builder/buildutil.go
+++ b/newt/builder/buildutil.go
@@ -26,7 +26,7 @@ import (
 
        log "github.com/Sirupsen/logrus"
 
-       "mynewt.apache.org/newt/newt/pkg"
+       "mynewt.apache.org/newt/newt/resolve"
 )
 
 func TestTargetName(testPkgName string) string {
@@ -64,7 +64,7 @@ func (b bpkgSorter) Swap(i, j int) {
        b.bpkgs[i], b.bpkgs[j] = b.bpkgs[j], b.bpkgs[i]
 }
 func (b bpkgSorter) Less(i, j int) bool {
-       return b.bpkgs[i].Name() < b.bpkgs[j].Name()
+       return b.bpkgs[i].rpkg.Lpkg.Name() < b.bpkgs[j].rpkg.Lpkg.Name()
 }
 
 func (b *Builder) sortedBuildPackages() []*BuildPackage {
@@ -80,39 +80,33 @@ func (b *Builder) sortedBuildPackages() []*BuildPackage {
        return sorter.bpkgs
 }
 
-func (b *Builder) sortedLocalPackages() []*pkg.LocalPackage {
+func (b *Builder) sortedRpkgs() []*resolve.ResolvePackage {
        bpkgs := b.sortedBuildPackages()
 
-       lpkgs := make([]*pkg.LocalPackage, len(bpkgs), len(bpkgs))
+       rpkgs := make([]*resolve.ResolvePackage, len(bpkgs), len(bpkgs))
        for i, bpkg := range bpkgs {
-               lpkgs[i] = bpkg.LocalPackage
+               rpkgs[i] = bpkg.rpkg
        }
 
-       return lpkgs
+       return rpkgs
 }
 
-func logDepInfo(builders []*Builder) {
+func logDepInfo(res *resolve.Resolution) {
        // Log API set.
        apis := []string{}
-       apiMap := map[string]*BuildPackage{}
-       for _, b := range builders {
-               if b != nil {
-                       for api, bpkg := range b.apiMap {
-                               apiMap[api] = bpkg
-                               apis = append(apis, api)
-                       }
-               }
+       for api, _ := range res.ApiMap {
+               apis = append(apis, api)
        }
        sort.Strings(apis)
 
        log.Debugf("API set:")
        for _, api := range apis {
-               bpkg := apiMap[api]
-               log.Debugf("    * " + api + " (" + bpkg.FullName() + ")")
+               rpkg := res.ApiMap[api]
+               log.Debugf("    * " + api + " (" + rpkg.Lpkg.FullName() + ")")
        }
 
        // Log dependency graph.
-       dg, err := joinedDepGraph(builders)
+       dg, err := joinedDepGraph(res.Sets())
        if err != nil {
                log.Debugf("Error while constructing dependency graph: %s\n",
                        err.Error())
@@ -121,7 +115,7 @@ func logDepInfo(builders []*Builder) {
        }
 
        // Log reverse dependency graph.
-       rdg, err := joinedRevdepGraph(builders)
+       rdg, err := joinedRevdepGraph(res.Sets())
        if err != nil {
                log.Debugf("Error while constructing reverse dependency graph: 
%s\n",
                        err.Error())

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/builder/depgraph.go
----------------------------------------------------------------------
diff --git a/newt/builder/depgraph.go b/newt/builder/depgraph.go
index 647028e..f38906c 100644
--- a/newt/builder/depgraph.go
+++ b/newt/builder/depgraph.go
@@ -23,18 +23,16 @@ import (
        "bytes"
        "fmt"
 
-       "mynewt.apache.org/newt/newt/pkg"
-       "mynewt.apache.org/newt/newt/project"
-       "mynewt.apache.org/newt/util"
+       "mynewt.apache.org/newt/newt/resolve"
 )
 
-type DepGraph map[*pkg.LocalPackage][]*pkg.LocalPackage
-type graphMap map[*pkg.LocalPackage]map[*pkg.LocalPackage]struct{}
+type DepGraph map[*resolve.ResolvePackage][]*resolve.ResolveDep
+type graphMap map[*resolve.ResolvePackage]map[*resolve.ResolveDep]struct{}
 
-func graphMapAdd(gm graphMap, p *pkg.LocalPackage, c *pkg.LocalPackage) {
+func graphMapAdd(gm graphMap, p *resolve.ResolvePackage, c 
*resolve.ResolveDep) {
        dstGraph := gm[p]
        if dstGraph == nil {
-               dstGraph = map[*pkg.LocalPackage]struct{}{}
+               dstGraph = map[*resolve.ResolveDep]struct{}{}
        }
        dstGraph[c] = struct{}{}
 
@@ -45,42 +43,34 @@ func graphMapToDepGraph(gm graphMap) DepGraph {
        dg := DepGraph{}
 
        for parent, childMap := range gm {
-               dg[parent] = []*pkg.LocalPackage{}
+               dg[parent] = []*resolve.ResolveDep{}
                for child, _ := range childMap {
                        dg[parent] = append(dg[parent], child)
                }
-               pkg.SortLclPkgs(dg[parent])
+               resolve.SortResolveDeps(dg[parent])
        }
 
        return dg
 }
 
-func (b *Builder) depGraph() (DepGraph, error) {
+func depGraph(rs *resolve.ResolveSet) (DepGraph, error) {
        graph := DepGraph{}
 
-       proj := project.GetProject()
-       for parent, _ := range b.PkgMap {
-               graph[parent] = []*pkg.LocalPackage{}
+       for _, parent := range rs.Rpkgs {
+               graph[parent] = []*resolve.ResolveDep{}
 
-               for _, dep := range parent.Deps() {
-                       child := proj.ResolveDependency(dep).(*pkg.LocalPackage)
-                       if child == nil {
-                               return nil, util.FmtNewtError(
-                                       "cannot resolve package \"%s\"; 
depender=\"%s\"",
-                                       dep.String(), parent.FullName())
-                       }
-
-                       graph[parent] = append(graph[parent], child)
+               for _, dep := range parent.Deps {
+                       graph[parent] = append(graph[parent], dep)
                }
 
-               pkg.SortLclPkgs(graph[parent])
+               resolve.SortResolveDeps(graph[parent])
        }
 
        return graph, nil
 }
 
-func (b *Builder) revdepGraph() (DepGraph, error) {
-       graph, err := b.depGraph()
+func revdepGraph(rs *resolve.ResolveSet) (DepGraph, error) {
+       graph, err := depGraph(rs)
        if err != nil {
                return nil, err
        }
@@ -88,7 +78,11 @@ func (b *Builder) revdepGraph() (DepGraph, error) {
        revGm := graphMap{}
        for parent, children := range graph {
                for _, child := range children {
-                       graphMapAdd(revGm, child, parent)
+                       rParent := child.Rpkg
+                       rChild := *child
+                       rChild.Rpkg = parent
+
+                       graphMapAdd(revGm, rParent, &rChild)
                }
        }
 
@@ -101,7 +95,7 @@ func mergeDepGraphs(graphs ...DepGraph) DepGraph {
        for _, graph := range graphs {
                for parent, children := range graph {
                        if gm[parent] == nil {
-                               gm[parent] = map[*pkg.LocalPackage]struct{}{}
+                               gm[parent] = map[*resolve.ResolveDep]struct{}{}
                        }
 
                        for _, child := range children {
@@ -115,11 +109,11 @@ func mergeDepGraphs(graphs ...DepGraph) DepGraph {
        return dg
 }
 
-func joinedDepGraph(builders []*Builder) (DepGraph, error) {
+func joinedDepGraph(rss []*resolve.ResolveSet) (DepGraph, error) {
        finalGraph := DepGraph{}
 
-       for _, b := range builders {
-               graph, err := b.depGraph()
+       for _, rs := range rss {
+               graph, err := depGraph(rs)
                if err != nil {
                        return nil, err
                }
@@ -129,11 +123,11 @@ func joinedDepGraph(builders []*Builder) (DepGraph, 
error) {
        return finalGraph, nil
 }
 
-func joinedRevdepGraph(builders []*Builder) (DepGraph, error) {
+func joinedRevdepGraph(rss []*resolve.ResolveSet) (DepGraph, error) {
        finalGraph := DepGraph{}
 
-       for _, b := range builders {
-               graph, err := b.revdepGraph()
+       for _, rs := range rss {
+               graph, err := revdepGraph(rs)
                if err != nil {
                        return nil, err
                }
@@ -143,24 +137,33 @@ func joinedRevdepGraph(builders []*Builder) (DepGraph, 
error) {
        return finalGraph, nil
 }
 
+func depString(dep *resolve.ResolveDep) string {
+       s := fmt.Sprintf("%s", dep.Rpkg.Lpkg.FullName())
+       if dep.Api != "" {
+               s += fmt.Sprintf("(api:%s)", dep.Api)
+       }
+
+       return s
+}
+
 func DepGraphText(graph DepGraph) string {
-       parents := make([]*pkg.LocalPackage, 0, len(graph))
+       parents := make([]*resolve.ResolvePackage, 0, len(graph))
        for lpkg, _ := range graph {
                parents = append(parents, lpkg)
        }
-       parents = pkg.SortLclPkgs(parents)
+       parents = resolve.SortResolvePkgs(parents)
 
        buffer := bytes.NewBufferString("")
 
        fmt.Fprintf(buffer, "Dependency graph (depender --> [dependees]):")
        for _, parent := range parents {
-               children := graph[parent]
-               fmt.Fprintf(buffer, "\n    * %s --> [", parent.FullName())
+               children := resolve.SortResolveDeps(graph[parent])
+               fmt.Fprintf(buffer, "\n    * %s --> [", parent.Lpkg.FullName())
                for i, child := range children {
                        if i != 0 {
                                fmt.Fprintf(buffer, " ")
                        }
-                       fmt.Fprintf(buffer, "%s", child.FullName())
+                       fmt.Fprintf(buffer, "%s", depString(child))
                }
                fmt.Fprintf(buffer, "]")
        }
@@ -169,23 +172,23 @@ func DepGraphText(graph DepGraph) string {
 }
 
 func RevdepGraphText(graph DepGraph) string {
-       parents := make([]*pkg.LocalPackage, 0, len(graph))
+       parents := make([]*resolve.ResolvePackage, 0, len(graph))
        for lpkg, _ := range graph {
                parents = append(parents, lpkg)
        }
-       parents = pkg.SortLclPkgs(parents)
+       parents = resolve.SortResolvePkgs(parents)
 
        buffer := bytes.NewBufferString("")
 
        fmt.Fprintf(buffer, "Reverse dependency graph (dependee <-- 
[dependers]):")
        for _, parent := range parents {
-               children := graph[parent]
-               fmt.Fprintf(buffer, "\n    * %s <-- [", parent.FullName())
+               children := resolve.SortResolveDeps(graph[parent])
+               fmt.Fprintf(buffer, "\n    * %s <-- [", parent.Lpkg.FullName())
                for i, child := range children {
                        if i != 0 {
                                fmt.Fprintf(buffer, " ")
                        }
-                       fmt.Fprintf(buffer, "%s", child.FullName())
+                       fmt.Fprintf(buffer, "%s", depString(child))
                }
                fmt.Fprintf(buffer, "]")
        }
@@ -195,15 +198,18 @@ func RevdepGraphText(graph DepGraph) string {
 
 // Extracts a new dependency graph containing only the specified parents.
 //
-// @return DepGraph             Filtered dependency graph
-//         []*pkg.LocalPackage  Specified packages that were not parents in
+// @param dg                    The source graph to filter.
+// @param parents               The parent nodes to keep.
+//
+// @return DepGraph             Filtered dependency graph.
+//         []*ResolvePackage    Specified packages that were not parents in
 //                                  original graph.
-func FilterDepGraph(dg DepGraph, parents []*pkg.LocalPackage) (
-       DepGraph, []*pkg.LocalPackage) {
+func FilterDepGraph(dg DepGraph, parents []*resolve.ResolvePackage) (
+       DepGraph, []*resolve.ResolvePackage) {
 
        newDg := DepGraph{}
 
-       var missing []*pkg.LocalPackage
+       var missing []*resolve.ResolvePackage
        for _, p := range parents {
                if dg[p] == nil {
                        missing = append(missing, p)

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/builder/library.go
----------------------------------------------------------------------
diff --git a/newt/builder/library.go b/newt/builder/library.go
index fd6f71c..af3c5b8 100644
--- a/newt/builder/library.go
+++ b/newt/builder/library.go
@@ -162,7 +162,7 @@ func (b *Builder) ParseObjectLibraryFile(bp *BuildPackage,
 
                        /* assign the library */
                        if bp != nil {
-                               (*si).Bpkg = bp.Name()
+                               (*si).Bpkg = bp.rpkg.Lpkg.Name()
                        } else {
                                (*si).Bpkg = "elf"
                        }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/builder/load.go
----------------------------------------------------------------------
diff --git a/newt/builder/load.go b/newt/builder/load.go
index 1cf9a84..eb7396e 100644
--- a/newt/builder/load.go
+++ b/newt/builder/load.go
@@ -171,7 +171,7 @@ func (b *Builder) debugBin(binPath string, extraJtagCmd 
string, reset bool,
                return err
        }
 
-       bspPath := b.bspPkg.BasePath()
+       bspPath := b.bspPkg.rpkg.Lpkg.BasePath()
        binBaseName := binPath
        featureString := b.FeatureString()
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/builder/paths.go
----------------------------------------------------------------------
diff --git a/newt/builder/paths.go b/newt/builder/paths.go
index b57dd2c..5beb6b3 100644
--- a/newt/builder/paths.go
+++ b/newt/builder/paths.go
@@ -123,39 +123,41 @@ func MfgBootDir(mfgPkgName string) string {
 }
 
 func (b *Builder) BinDir() string {
-       return BinDir(b.targetPkg.Name(), b.buildName)
+       return BinDir(b.targetPkg.rpkg.Lpkg.Name(), b.buildName)
 }
 
 func (b *Builder) FileBinDir(pkgName string) string {
-       return FileBinDir(b.targetPkg.Name(), b.buildName, pkgName)
+       return FileBinDir(b.targetPkg.rpkg.Lpkg.Name(), b.buildName, pkgName)
 }
 
 func (b *Builder) PkgBinDir(bpkg *BuildPackage) string {
-       return PkgBinDir(b.targetPkg.Name(), b.buildName, bpkg.Name(), 
bpkg.Type())
+       return PkgBinDir(b.targetPkg.rpkg.Lpkg.Name(), b.buildName, 
bpkg.rpkg.Lpkg.Name(),
+               bpkg.rpkg.Lpkg.Type())
 }
 
 // Generates the path+filename of the specified package's .a file.
 func (b *Builder) ArchivePath(bpkg *BuildPackage) string {
-       return ArchivePath(b.targetPkg.Name(), b.buildName, bpkg.Name(),
-               bpkg.Type())
+       return ArchivePath(b.targetPkg.rpkg.Lpkg.Name(), b.buildName, 
bpkg.rpkg.Lpkg.Name(),
+               bpkg.rpkg.Lpkg.Type())
 }
 
 func (b *Builder) AppTentativeElfPath() string {
-       return b.PkgBinDir(b.appPkg) + "/" + filepath.Base(b.appPkg.Name()) +
+       return b.PkgBinDir(b.appPkg) + "/" + 
filepath.Base(b.appPkg.rpkg.Lpkg.Name()) +
                "_tmp.elf"
 }
 
 func (b *Builder) AppElfPath() string {
-       return AppElfPath(b.targetPkg.Name(), b.buildName, b.appPkg.Name())
+       return AppElfPath(b.targetPkg.rpkg.Lpkg.Name(), b.buildName,
+               b.appPkg.rpkg.Lpkg.Name())
 }
 
 func (b *Builder) AppLinkerElfPath() string {
-       return b.PkgBinDir(b.appPkg) + "/" + filepath.Base(b.appPkg.Name()) +
+       return b.PkgBinDir(b.appPkg) + "/" + 
filepath.Base(b.appPkg.rpkg.Lpkg.Name()) +
                "linker.elf"
 }
 
 func (b *Builder) AppImgPath() string {
-       return b.PkgBinDir(b.appPkg) + "/" + filepath.Base(b.appPkg.Name()) +
+       return b.PkgBinDir(b.appPkg) + "/" + 
filepath.Base(b.appPkg.rpkg.Lpkg.Name()) +
                ".img"
 }
 
@@ -168,14 +170,16 @@ func (b *Builder) AppPath() string {
 }
 
 func (b *Builder) TestExePath(bpkg *BuildPackage) string {
-       return TestExePath(b.targetPkg.Name(), b.buildName, bpkg.Name(),
-               bpkg.Type())
+       return TestExePath(b.targetPkg.rpkg.Lpkg.Name(), b.buildName,
+               bpkg.rpkg.Lpkg.Name(), bpkg.rpkg.Lpkg.Type())
 }
 
 func (b *Builder) ManifestPath() string {
-       return ManifestPath(b.targetPkg.Name(), b.buildName, b.appPkg.Name())
+       return ManifestPath(b.targetPkg.rpkg.Lpkg.Name(), b.buildName,
+               b.appPkg.rpkg.Lpkg.Name())
 }
 
 func (b *Builder) AppBinBasePath() string {
-       return b.PkgBinDir(b.appPkg) + "/" + filepath.Base(b.appPkg.Name())
+       return b.PkgBinDir(b.appPkg) + "/" +
+               filepath.Base(b.appPkg.rpkg.Lpkg.Name())
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/builder/selftest.go
----------------------------------------------------------------------
diff --git a/newt/builder/selftest.go b/newt/builder/selftest.go
index 36781b7..fc7268c 100644
--- a/newt/builder/selftest.go
+++ b/newt/builder/selftest.go
@@ -27,11 +27,28 @@ import (
 
        "mynewt.apache.org/newt/newt/pkg"
        "mynewt.apache.org/newt/newt/project"
+       "mynewt.apache.org/newt/newt/resolve"
        "mynewt.apache.org/newt/util"
 )
 
-func (b *Builder) SelfTestLink(p *pkg.LocalPackage) error {
-       testBpkg := b.PkgMap[p]
+func (b *Builder) getTestBpkg(rpkg *resolve.ResolvePackage) (
+       *BuildPackage, error) {
+
+       testBpkg := b.PkgMap[rpkg]
+       if testBpkg == nil {
+               return nil, util.FmtNewtError("builder missing test package: 
%s",
+                       rpkg.Lpkg.FullName())
+       }
+
+       return testBpkg, nil
+}
+
+func (b *Builder) SelfTestLink(rpkg *resolve.ResolvePackage) error {
+       testBpkg, err := b.getTestBpkg(rpkg)
+       if err != nil {
+               return err
+       }
+
        testPath := b.TestExePath(testBpkg)
        if err := b.link(testPath, nil, nil); err != nil {
                return err
@@ -40,6 +57,16 @@ func (b *Builder) SelfTestLink(p *pkg.LocalPackage) error {
        return nil
 }
 
+func (t *TargetBuilder) getTestRpkg() (*resolve.ResolvePackage, error) {
+       testRpkg := t.res.LpkgRpkgMap[t.testPkg]
+       if testRpkg == nil {
+               return nil, util.FmtNewtError("resolution missing test package: 
%s",
+                       t.testPkg.FullName())
+       }
+
+       return testRpkg, nil
+}
+
 func (t *TargetBuilder) SelfTestCreateExe() error {
        if err := t.PrepBuild(); err != nil {
                return err
@@ -49,7 +76,12 @@ func (t *TargetBuilder) SelfTestCreateExe() error {
                return err
        }
 
-       if err := t.AppBuilder.SelfTestLink(t.testPkg); err != nil {
+       testRpkg, err := t.getTestRpkg()
+       if err != nil {
+               return err
+       }
+
+       if err := t.AppBuilder.SelfTestLink(testRpkg); err != nil {
                return err
        }
 
@@ -61,7 +93,12 @@ func (t *TargetBuilder) SelfTestExecute() error {
                return err
        }
 
-       if err := t.AppBuilder.SelfTestExecute(t.testPkg); err != nil {
+       testRpkg, err := t.getTestRpkg()
+       if err != nil {
+               return err
+       }
+
+       if err := t.AppBuilder.SelfTestExecute(testRpkg); err != nil {
                return err
        }
 
@@ -73,29 +110,27 @@ func (t *TargetBuilder) SelfTestDebug() error {
                return err
        }
 
-       lpkg := t.GetTestPkg()
-       if lpkg == nil {
-               panic("internal error: attempt to debug target builder with no 
test " +
-                       "package")
+       testRpkg, err := t.getTestRpkg()
+       if err != nil {
+               return err
        }
 
-       bpkg := t.AppBuilder.PkgMap[lpkg]
-       if bpkg == nil {
-               panic("internal error: local package \"" + lpkg.FullName() +
-                       "\" not built")
+       testBpkg, err := t.AppBuilder.getTestBpkg(testRpkg)
+       if err != nil {
+               return err
        }
 
        return t.AppBuilder.debugBin(
-               strings.TrimSuffix(t.AppBuilder.TestExePath(bpkg), ".elf"),
+               strings.TrimSuffix(t.AppBuilder.TestExePath(testBpkg), ".elf"),
                "", false, false)
 }
 
-func (b *Builder) testOwner(p *BuildPackage) *BuildPackage {
-       if p.Type() != pkg.PACKAGE_TYPE_UNITTEST {
-               panic("Expected unittest package; got: " + p.Name())
+func (b *Builder) testOwner(bpkg *BuildPackage) *BuildPackage {
+       if bpkg.rpkg.Lpkg.Type() != pkg.PACKAGE_TYPE_UNITTEST {
+               panic("Expected unittest package; got: " + 
bpkg.rpkg.Lpkg.Name())
        }
 
-       curPath := p.BasePath()
+       curPath := bpkg.rpkg.Lpkg.BasePath()
 
        for {
                parentPath := filepath.Dir(curPath)
@@ -104,7 +139,9 @@ func (b *Builder) testOwner(p *BuildPackage) *BuildPackage {
                }
 
                parentPkg := b.pkgWithPath(parentPath)
-               if parentPkg != nil && parentPkg.Type() != 
pkg.PACKAGE_TYPE_UNITTEST {
+               if parentPkg != nil &&
+                       parentPkg.rpkg.Lpkg.Type() != pkg.PACKAGE_TYPE_UNITTEST 
{
+
                        return parentPkg
                }
 
@@ -112,11 +149,10 @@ func (b *Builder) testOwner(p *BuildPackage) 
*BuildPackage {
        }
 }
 
-func (b *Builder) SelfTestExecute(p *pkg.LocalPackage) error {
-       testBpkg := b.PkgMap[p]
-       if testBpkg == nil {
-               panic("internal error; package-under-test \"" + p.FullName() +
-                       "\" not in builder")
+func (b *Builder) SelfTestExecute(testRpkg *resolve.ResolvePackage) error {
+       testBpkg, err := b.getTestBpkg(testRpkg)
+       if err != nil {
+               return err
        }
 
        testPath := b.TestExePath(testBpkg)
@@ -129,8 +165,8 @@ func (b *Builder) SelfTestExecute(p *pkg.LocalPackage) 
error {
        cmd := []string{testPath}
        if _, err := util.ShellCommand(cmd, nil); err != nil {
                newtError := err.(*util.NewtError)
-               newtError.Text = fmt.Sprintf("Test failure (%s):\n%s", p.Name(),
-                       newtError.Text)
+               newtError.Text = fmt.Sprintf("Test failure (%s):\n%s",
+                       testRpkg.Lpkg.Name(), newtError.Text)
                return newtError
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/builder/targetbuild.go
----------------------------------------------------------------------
diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go
index 072e0b8..2bea6ef 100644
--- a/newt/builder/targetbuild.go
+++ b/newt/builder/targetbuild.go
@@ -98,19 +98,6 @@ func NewTargetBuilder(target *target.Target) 
(*TargetBuilder, error) {
        return NewTargetTester(target, nil)
 }
 
-func (t *TargetBuilder) Builders() []*Builder {
-       builders := []*Builder{}
-
-       if t.LoaderBuilder != nil {
-               builders = append(builders, t.LoaderBuilder)
-       }
-       if t.AppBuilder != nil {
-               builders = append(builders, t.AppBuilder)
-       }
-
-       return builders
-}
-
 func (t *TargetBuilder) NewCompiler(dstDir string) (
        *toolchain.Compiler, error) {
 
@@ -217,12 +204,14 @@ func (t *TargetBuilder) generateSysinit() error {
 
        srcDir := GeneratedSrcDir(t.target.Name())
 
-       if t.res.LoaderPkgs != nil {
-               sysinit.EnsureWritten(t.res.LoaderPkgs, srcDir,
+       if t.res.LoaderSet != nil {
+               lpkgs := resolve.RpkgSliceToLpkgSlice(t.res.LoaderSet.Rpkgs)
+               sysinit.EnsureWritten(lpkgs, srcDir,
                        pkg.ShortName(t.target.Package()), true)
        }
 
-       sysinit.EnsureWritten(t.res.AppPkgs, srcDir,
+       lpkgs := resolve.RpkgSliceToLpkgSlice(t.res.AppSet.Rpkgs)
+       sysinit.EnsureWritten(lpkgs, srcDir,
                pkg.ShortName(t.target.Package()), false)
 
        return nil
@@ -262,9 +251,9 @@ func (t *TargetBuilder) PrepBuild() error {
        }
 
        var err error
-       if t.res.LoaderPkgs != nil {
+       if t.res.LoaderSet != nil {
                t.LoaderBuilder, err = NewBuilder(t, BUILD_NAME_LOADER,
-                       t.res.LoaderPkgs, t.res.ApiMap, t.res.Cfg)
+                       t.res.LoaderSet.Rpkgs, t.res.ApiMap, t.res.Cfg)
                if err != nil {
                        return err
                }
@@ -279,7 +268,7 @@ func (t *TargetBuilder) PrepBuild() error {
                t.LoaderList = project.ResetDeps(nil)
        }
 
-       t.AppBuilder, err = NewBuilder(t, BUILD_NAME_APP, t.res.AppPkgs,
+       t.AppBuilder, err = NewBuilder(t, BUILD_NAME_APP, t.res.AppSet.Rpkgs,
                t.res.ApiMap, t.res.Cfg)
        if err != nil {
                return err
@@ -288,7 +277,7 @@ func (t *TargetBuilder) PrepBuild() error {
                return err
        }
 
-       if t.res.LoaderPkgs != nil {
+       if t.res.LoaderSet != nil {
                appFlags := toolchain.NewCompilerInfo()
                appFlags.Cflags = append(appFlags.Cflags, "-DSPLIT_APPLICATION")
                t.AppBuilder.AddCompilerInfo(appFlags)
@@ -296,7 +285,7 @@ func (t *TargetBuilder) PrepBuild() error {
 
        t.AppList = project.ResetDeps(nil)
 
-       logDepInfo(t.Builders())
+       logDepInfo(t.res)
 
        if err := t.generateCode(); err != nil {
                return err
@@ -400,12 +389,12 @@ func (t *TargetBuilder) RelinkLoader() (error, 
map[string]bool,
 
        /* fetch symbols from the elf and from the libraries themselves */
        log.Debugf("Loader packages:")
-       for _, lpkg := range t.LoaderBuilder.sortedLocalPackages() {
-               log.Debugf("    * %s", lpkg.Name())
+       for _, rpkg := range t.LoaderBuilder.sortedRpkgs() {
+               log.Debugf("    * %s", rpkg.Lpkg.Name())
        }
        log.Debugf("App packages:")
-       for _, lpkg := range t.AppBuilder.sortedLocalPackages() {
-               log.Debugf("    * %s", lpkg.Name())
+       for _, rpkg := range t.AppBuilder.sortedRpkgs() {
+               log.Debugf("    * %s", rpkg.Lpkg.Name())
        }
        err, appLibSym := t.AppBuilder.ExtractSymbolInfo()
        if err != nil {
@@ -439,14 +428,14 @@ func (t *TargetBuilder) RelinkLoader() (error, 
map[string]bool,
        uncommonPkgs := smNomatch.Packages()
 
        /* ensure that the loader and app packages are never shared */
-       delete(commonPkgs, t.AppBuilder.appPkg.Name())
-       uncommonPkgs[t.AppBuilder.appPkg.Name()] = true
-       ma := smMatch.FilterPkg(t.AppBuilder.appPkg.Name())
+       delete(commonPkgs, t.AppBuilder.appPkg.rpkg.Lpkg.Name())
+       uncommonPkgs[t.AppBuilder.appPkg.rpkg.Lpkg.Name()] = true
+       ma := smMatch.FilterPkg(t.AppBuilder.appPkg.rpkg.Lpkg.Name())
        smMatch.RemoveMap(ma)
 
-       delete(commonPkgs, t.LoaderBuilder.appPkg.Name())
-       uncommonPkgs[t.LoaderBuilder.appPkg.Name()] = true
-       ml := smMatch.FilterPkg(t.LoaderBuilder.appPkg.Name())
+       delete(commonPkgs, t.LoaderBuilder.appPkg.rpkg.Lpkg.Name())
+       uncommonPkgs[t.LoaderBuilder.appPkg.rpkg.Lpkg.Name()] = true
+       ml := smMatch.FilterPkg(t.LoaderBuilder.appPkg.rpkg.Lpkg.Name())
        smMatch.RemoveMap(ml)
 
        util.StatusMessage(util.VERBOSITY_VERBOSE,
@@ -457,9 +446,9 @@ func (t *TargetBuilder) RelinkLoader() (error, 
map[string]bool,
        var symbolStr string
        for v, _ := range uncommonPkgs {
                if t.AppBuilder.appPkg != nil &&
-                       t.AppBuilder.appPkg.Name() != v &&
+                       t.AppBuilder.appPkg.rpkg.Lpkg.Name() != v &&
                        t.LoaderBuilder.appPkg != nil &&
-                       t.LoaderBuilder.appPkg.Name() != v {
+                       t.LoaderBuilder.appPkg.rpkg.Lpkg.Name() != v {
 
                        trouble := smNomatch.FilterPkg(v)
 
@@ -551,15 +540,15 @@ func (t *TargetBuilder) createManifest() error {
        }
 
        rm := image.NewRepoManager()
-       for _, lpkg := range t.AppBuilder.sortedLocalPackages() {
+       for _, rpkg := range t.AppBuilder.sortedRpkgs() {
                manifest.Pkgs = append(manifest.Pkgs,
-                       rm.GetImageManifestPkg(lpkg))
+                       rm.GetImageManifestPkg(rpkg.Lpkg))
        }
 
        if t.LoaderBuilder != nil {
-               for _, lpkg := range t.LoaderBuilder.sortedLocalPackages() {
+               for _, rpkg := range t.LoaderBuilder.sortedRpkgs() {
                        manifest.LoaderPkgs = append(manifest.LoaderPkgs,
-                               rm.GetImageManifestPkg(lpkg))
+                               rm.GetImageManifestPkg(rpkg.Lpkg))
                }
        }
 
@@ -676,9 +665,17 @@ func (t *TargetBuilder) CreateImages(version string,
 }
 
 func (t *TargetBuilder) CreateDepGraph() (DepGraph, error) {
-       return joinedDepGraph(t.Builders())
+       if err := t.ensureResolved(); err != nil {
+               return nil, err
+       }
+
+       return joinedDepGraph(t.res.Sets())
 }
 
 func (t *TargetBuilder) CreateRevdepGraph() (DepGraph, error) {
-       return joinedRevdepGraph(t.Builders())
+       if err := t.ensureResolved(); err != nil {
+               return nil, err
+       }
+
+       return joinedRevdepGraph(t.res.Sets())
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/cli/target_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/target_cmds.go b/newt/cli/target_cmds.go
index ded8183..54511fa 100644
--- a/newt/cli/target_cmds.go
+++ b/newt/cli/target_cmds.go
@@ -615,7 +615,8 @@ func targetDepCmd(cmd *cobra.Command, args []string) {
                NewtUsage(cmd, err)
        }
 
-       if err := b.PrepBuild(); err != nil {
+       res, err := b.Resolve()
+       if err != nil {
                NewtUsage(nil, err)
        }
 
@@ -626,17 +627,17 @@ func targetDepCmd(cmd *cobra.Command, args []string) {
 
        // If user specified any package names, only include specified packages.
        if len(args) > 1 {
-               lpkgs, err := ResolvePackages(args[1:])
+               rpkgs, err := ResolveRpkgs(res, args[1:])
                if err != nil {
                        NewtUsage(cmd, err)
                }
 
-               var missingLpkgs []*pkg.LocalPackage
-               dg, missingLpkgs = builder.FilterDepGraph(dg, lpkgs)
-               for _, lpkg := range missingLpkgs {
+               var missingRpkgs []*resolve.ResolvePackage
+               dg, missingRpkgs = builder.FilterDepGraph(dg, rpkgs)
+               for _, rpkg := range missingRpkgs {
                        util.StatusMessage(util.VERBOSITY_QUIET,
                                "Warning: Package \"%s\" not included in target 
\"%s\"\n",
-                               lpkg.FullName(), b.GetTarget().FullName())
+                               rpkg.Lpkg.FullName(), b.GetTarget().FullName())
                }
        }
 
@@ -658,7 +659,8 @@ func targetRevdepCmd(cmd *cobra.Command, args []string) {
                NewtUsage(cmd, err)
        }
 
-       if err := b.PrepBuild(); err != nil {
+       res, err := b.Resolve()
+       if err != nil {
                NewtUsage(nil, err)
        }
 
@@ -669,17 +671,17 @@ func targetRevdepCmd(cmd *cobra.Command, args []string) {
 
        // If user specified any package names, only include specified packages.
        if len(args) > 1 {
-               lpkgs, err := ResolvePackages(args[1:])
+               rpkgs, err := ResolveRpkgs(res, args[1:])
                if err != nil {
                        NewtUsage(cmd, err)
                }
 
-               var missingLpkgs []*pkg.LocalPackage
-               dg, missingLpkgs = builder.FilterDepGraph(dg, lpkgs)
-               for _, lpkg := range missingLpkgs {
+               var missingRpkgs []*resolve.ResolvePackage
+               dg, missingRpkgs = builder.FilterDepGraph(dg, rpkgs)
+               for _, rpkg := range missingRpkgs {
                        util.StatusMessage(util.VERBOSITY_QUIET,
                                "Warning: Package \"%s\" not included in target 
\"%s\"\n",
-                               lpkg.FullName(), b.GetTarget().FullName())
+                               rpkg.Lpkg.FullName(), b.GetTarget().FullName())
                }
        }
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/cli/util.go
----------------------------------------------------------------------
diff --git a/newt/cli/util.go b/newt/cli/util.go
index 0ab578e..e9c0b4c 100644
--- a/newt/cli/util.go
+++ b/newt/cli/util.go
@@ -35,6 +35,7 @@ import (
        "mynewt.apache.org/newt/newt/newtutil"
        "mynewt.apache.org/newt/newt/pkg"
        "mynewt.apache.org/newt/newt/project"
+       "mynewt.apache.org/newt/newt/resolve"
        "mynewt.apache.org/newt/newt/target"
        "mynewt.apache.org/newt/util"
 )
@@ -296,6 +297,28 @@ func ResolvePackages(pkgNames []string) 
([]*pkg.LocalPackage, error) {
        return lpkgs, nil
 }
 
+func ResolveRpkgs(res *resolve.Resolution, pkgNames []string) (
+       []*resolve.ResolvePackage, error) {
+
+       lpkgs, err := ResolvePackages(pkgNames)
+       if err != nil {
+               return nil, err
+       }
+
+       rpkgs := []*resolve.ResolvePackage{}
+       for _, lpkg := range lpkgs {
+               rpkg := res.LpkgRpkgMap[lpkg]
+               if rpkg == nil {
+                       return nil, util.FmtNewtError("Unexpected error; local 
package "+
+                               "%s lacks a corresponding resolve package", 
lpkg.FullName())
+               }
+
+               rpkgs = append(rpkgs, rpkg)
+       }
+
+       return rpkgs, nil
+}
+
 func TargetBuilderForTargetOrUnittest(pkgName string) (
        *builder.TargetBuilder, error) {
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/pkg/localpackage.go
----------------------------------------------------------------------
diff --git a/newt/pkg/localpackage.go b/newt/pkg/localpackage.go
index b34bd59..8c935b1 100644
--- a/newt/pkg/localpackage.go
+++ b/newt/pkg/localpackage.go
@@ -61,9 +61,6 @@ type LocalPackage struct {
        // General information about the package
        desc *PackageDesc
 
-       // Dependencies for this package
-       deps map[string]*Dependency
-
        // Package init function name and stage.  These are used to generate the
        // sysinit C file.
        init map[string]int
@@ -89,7 +86,6 @@ func NewLocalPackage(r *repo.Repo, pkgDir string) 
*LocalPackage {
                SyscfgV:          viper.New(),
                repo:             r,
                basePath:         filepath.ToSlash(filepath.Clean(pkgDir)),
-               deps:             map[string]*Dependency{},
                init:             map[string]int{},
                injectedSettings: map[string]string{},
        }
@@ -196,34 +192,6 @@ func (pkg *LocalPackage) AddCfgFilename(cfgFilename 
string) {
        pkg.cfgFilenames = append(pkg.cfgFilenames, cfgFilename)
 }
 
-func (pkg *LocalPackage) HasDep(searchDep *Dependency) bool {
-       return pkg.deps[searchDep.String()] != nil
-}
-
-func (pkg *LocalPackage) AddDep(dep *Dependency) bool {
-       if pkg.deps[dep.String()] != nil {
-               return false
-       }
-
-       pkg.deps[dep.String()] = dep
-       return true
-}
-
-func (pkg *LocalPackage) Deps() []*Dependency {
-       names := make([]string, 0, len(pkg.deps))
-       for name, _ := range pkg.deps {
-               names = append(names, name)
-       }
-       sort.Strings(names)
-
-       deps := make([]*Dependency, len(names))
-       for i, name := range names {
-               deps[i] = pkg.deps[name]
-       }
-
-       return deps
-}
-
 func (pkg *LocalPackage) readDesc(v *viper.Viper) (*PackageDesc, error) {
        pdesc := &PackageDesc{}
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/pkg/package.go
----------------------------------------------------------------------
diff --git a/newt/pkg/package.go b/newt/pkg/package.go
index 03795cb..d5d9403 100644
--- a/newt/pkg/package.go
+++ b/newt/pkg/package.go
@@ -75,8 +75,6 @@ type Package interface {
        Hash() (string, error)
        // Description of this package
        Desc() *PackageDesc
-       // Dependency list for this package
-       Deps() []*Dependency
        // APIs exported by this package
        Apis() []string
        // APIs required by this package

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/resolve/resolve.go
----------------------------------------------------------------------
diff --git a/newt/resolve/resolve.go b/newt/resolve/resolve.go
index 916f38c..c4a1d38 100644
--- a/newt/resolve/resolve.go
+++ b/newt/resolve/resolve.go
@@ -42,8 +42,19 @@ type Resolver struct {
        cfg              syscfg.Cfg
 }
 
+type ResolveDep struct {
+       // Package being depended on.
+       Rpkg *ResolvePackage
+
+       // Name of API that generated the dependency; "" if a hard dependency.
+       Api string
+
+       // XXX: slice of syscfg settings that generated this dependency.
+}
+
 type ResolvePackage struct {
-       *pkg.LocalPackage
+       Lpkg *pkg.LocalPackage
+       Deps map[*ResolvePackage]*ResolveDep
 
        // Keeps track of API requirements and whether they are satisfied.
        reqApiMap map[string]bool
@@ -52,14 +63,23 @@ type ResolvePackage struct {
        apisSatisfied bool
 }
 
+type ResolveSet struct {
+       // Parent resoluion.  Contains this ResolveSet.
+       Res *Resolution
+
+       // All seed pacakges and their dependencies.
+       Rpkgs []*ResolvePackage
+}
+
 // The result of resolving a target's configuration, APIs, and dependencies.
 type Resolution struct {
        Cfg             syscfg.Cfg
-       ApiMap          map[string]*pkg.LocalPackage
-       UnsatisfiedApis map[string][]*pkg.LocalPackage
+       ApiMap          map[string]*ResolvePackage
+       UnsatisfiedApis map[string][]*ResolvePackage
 
-       LoaderPkgs []*pkg.LocalPackage
-       AppPkgs    []*pkg.LocalPackage
+       LpkgRpkgMap map[*pkg.LocalPackage]*ResolvePackage
+       LoaderSet   *ResolveSet
+       AppSet      *ResolveSet
 }
 
 func newResolver(
@@ -86,23 +106,80 @@ func newResolver(
        return r
 }
 
-func newResolvePkg(lpkg *pkg.LocalPackage) *ResolvePackage {
+func newResolution() *Resolution {
+       r := &Resolution{
+               ApiMap:          map[string]*ResolvePackage{},
+               UnsatisfiedApis: map[string][]*ResolvePackage{},
+       }
+
+       r.LoaderSet = &ResolveSet{Res: r}
+       r.AppSet = &ResolveSet{Res: r}
+
+       return r
+}
+
+func (res *Resolution) Sets() []*ResolveSet {
+       rss := []*ResolveSet{}
+
+       if res.LoaderSet != nil {
+               rss = append(rss, res.LoaderSet)
+       }
+       if res.AppSet != nil {
+               rss = append(rss, res.AppSet)
+       }
+
+       return rss
+}
+
+func NewResolvePkg(lpkg *pkg.LocalPackage) *ResolvePackage {
        return &ResolvePackage{
-               LocalPackage: lpkg,
-               reqApiMap:    map[string]bool{},
+               Lpkg:      lpkg,
+               reqApiMap: map[string]bool{},
+               Deps:      map[*ResolvePackage]*ResolveDep{},
        }
 }
 
-func (r *Resolver) lpkgSlice() []*pkg.LocalPackage {
-       lpkgs := make([]*pkg.LocalPackage, len(r.pkgMap))
+func (r *Resolver) resolveDep(dep *pkg.Dependency) (*pkg.LocalPackage, error) {
+       proj := project.GetProject()
+
+       lpkg := proj.ResolveDependency(dep).(*pkg.LocalPackage)
+       if lpkg == nil {
+               return nil, util.FmtNewtError("Could not resolve package 
dependency: "+
+                       "%s; depender: %s", dep.String(), dep.Name)
+       }
+
+       return lpkg, nil
+}
+
+// @return                      true if rhe package's dependency list was
+//                                  modified.
+func (rpkg *ResolvePackage) AddDep(apiPkg *ResolvePackage, api string) bool {
+       if dep := rpkg.Deps[apiPkg]; dep != nil {
+               if dep.Api != "" && api == "" {
+                       dep.Api = api
+                       return true
+               } else {
+                       return false
+               }
+       } else {
+               rpkg.Deps[apiPkg] = &ResolveDep{
+                       Rpkg: apiPkg,
+                       Api:  api,
+               }
+               return true
+       }
+}
+
+func (r *Resolver) rpkgSlice() []*ResolvePackage {
+       rpkgs := make([]*ResolvePackage, len(r.pkgMap))
 
        i := 0
        for _, rpkg := range r.pkgMap {
-               lpkgs[i] = rpkg.LocalPackage
+               rpkgs[i] = rpkg
                i++
        }
 
-       return lpkgs
+       return rpkgs
 }
 
 func (r *Resolver) apiSlice() []string {
@@ -117,14 +194,18 @@ func (r *Resolver) apiSlice() []string {
        return apis
 }
 
-// @return bool                                        true if this is a new 
package.
-func (r *Resolver) addPkg(lpkg *pkg.LocalPackage) bool {
+// @return ResolvePackage              The rpkg corresponding to the specified 
lpkg.
+//                                  This is a new package if a package was
+//                                  added; old if it was already present.
+//         bool                                        true if this is a new 
package.
+func (r *Resolver) addPkg(lpkg *pkg.LocalPackage) (*ResolvePackage, bool) {
        if rpkg := r.pkgMap[lpkg]; rpkg != nil {
-               return false
+               return rpkg, false
        }
 
-       r.pkgMap[lpkg] = newResolvePkg(lpkg)
-       return true
+       rpkg := NewResolvePkg(lpkg)
+       r.pkgMap[lpkg] = rpkg
+       return rpkg, true
 }
 
 // @return bool                 true if this is a new API.
@@ -137,7 +218,7 @@ func (r *Resolver) addApi(apiString string, rpkg 
*ResolvePackage) bool {
                if curRpkg != rpkg {
                        util.StatusMessage(util.VERBOSITY_QUIET,
                                "Warning: API conflict: %s (%s <-> %s)\n", 
apiString,
-                               curRpkg.Name(), rpkg.Name())
+                               curRpkg.Lpkg.Name(), rpkg.Lpkg.Name())
                }
                return false
        }
@@ -146,6 +227,8 @@ func (r *Resolver) addApi(apiString string, rpkg 
*ResolvePackage) bool {
 // 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.
+//
+// @return bool                 true if the API is now satisfied.
 func (r *Resolver) satisfyApi(rpkg *ResolvePackage, reqApi string) bool {
        depRpkg := r.apis[reqApi]
        if depRpkg == nil {
@@ -160,7 +243,7 @@ func (r *Resolver) satisfyApi(rpkg *ResolvePackage, reqApi 
string) bool {
        rpkg.depsResolved = false
 
        log.Debugf("API requirement satisfied; pkg=%s API=(%s, %s)",
-               rpkg.Name(), reqApi, depRpkg.FullName())
+               rpkg.Lpkg.Name(), reqApi, depRpkg.Lpkg.FullName())
 
        return true
 }
@@ -174,11 +257,11 @@ func (r *Resolver) satisfyApis(rpkg *ResolvePackage) bool 
{
        rpkg.apisSatisfied = true
        newDeps := false
 
-       features := r.cfg.FeaturesForLpkg(rpkg.LocalPackage)
+       features := r.cfg.FeaturesForLpkg(rpkg.Lpkg)
 
        // 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,
+       reqApis := newtutil.GetStringSliceFeatures(rpkg.Lpkg.PkgV, features,
                "pkg.req_apis")
        for _, reqApi := range reqApis {
                reqStatus := rpkg.reqApiMap[reqApi]
@@ -204,39 +287,34 @@ func (r *Resolver) satisfyApis(rpkg *ResolvePackage) bool 
{
 //                                  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)
+       features := r.cfg.FeaturesForLpkg(rpkg.Lpkg)
 
        changed := false
-       newDeps := newtutil.GetStringSliceFeatures(rpkg.PkgV, features, 
"pkg.deps")
+       newDeps := newtutil.GetStringSliceFeatures(rpkg.Lpkg.PkgV, features,
+               "pkg.deps")
        for _, newDepStr := range newDeps {
-               newDep, err := pkg.NewDependency(rpkg.Repo(), newDepStr)
+               newDep, err := pkg.NewDependency(rpkg.Lpkg.Repo(), newDepStr)
                if err != nil {
                        return false, err
                }
 
-               lpkg, ok := proj.ResolveDependency(newDep).(*pkg.LocalPackage)
-               if !ok {
-                       return false,
-                               util.FmtNewtError("Could not resolve package 
dependency: "+
-                                       "%s; depender: %s", newDep.String(), 
rpkg.FullName())
-               }
-
-               if r.addPkg(lpkg) {
-                       changed = true
+               lpkg, err := r.resolveDep(newDep)
+               if err != nil {
+                       return false, err
                }
 
-               if rpkg.AddDep(newDep) {
+               depRpkg, _ := r.addPkg(lpkg)
+               if rpkg.AddDep(depRpkg, "") {
                        changed = true
                }
        }
 
        // 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")
+       apis := newtutil.GetStringSliceFeatures(rpkg.Lpkg.PkgV, features,
+               "pkg.apis")
        for _, api := range apis {
-               newApi := r.addApi(api, rpkg)
-               if newApi {
+               if r.addApi(api, rpkg) {
                        changed = true
                }
        }
@@ -278,7 +356,7 @@ func (r *Resolver) resolvePkg(rpkg *ResolvePackage) (bool, 
error) {
 
 // @return                      changed,err
 func (r *Resolver) reloadCfg() (bool, error) {
-       lpkgs := r.lpkgSlice()
+       lpkgs := RpkgSliceToLpkgSlice(r.rpkgSlice())
        apis := r.apiSlice()
 
        // Determine which features have been detected so far.  The feature map 
is
@@ -330,7 +408,7 @@ func (r *Resolver) resolveDepsOnce() (bool, error) {
        return newDeps, nil
 }
 
-func (r *Resolver) resolveDeps() ([]*pkg.LocalPackage, error) {
+func (r *Resolver) resolveDeps() ([]*ResolvePackage, error) {
        if _, err := r.resolveDepsOnce(); err != nil {
                return nil, err
        }
@@ -340,8 +418,8 @@ func (r *Resolver) resolveDeps() ([]*pkg.LocalPackage, 
error) {
                return nil, err
        }
 
-       lpkgs := r.lpkgSlice()
-       return lpkgs, nil
+       rpkgs := r.rpkgSlice()
+       return rpkgs, nil
 }
 
 func (r *Resolver) resolveDepsAndCfg() error {
@@ -393,15 +471,8 @@ func (r *Resolver) resolveApiDeps() error {
        for _, rpkg := range r.pkgMap {
                for api, _ := range rpkg.reqApiMap {
                        apiPkg := r.apis[api]
-                       if apiPkg == nil {
-                               //return util.FmtNewtError(
-                               //"Unsatisfied API at unexpected time: %s", api)
-                       } else {
-
-                               rpkg.AddDep(&pkg.Dependency{
-                                       Name: apiPkg.Name(),
-                                       Repo: apiPkg.Repo().Name(),
-                               })
+                       if apiPkg != nil {
+                               rpkg.AddDep(apiPkg, api)
                        }
                }
        }
@@ -410,26 +481,26 @@ func (r *Resolver) resolveApiDeps() error {
 }
 
 func (r *Resolver) apiResolution() (
-       map[string]*pkg.LocalPackage,
-       map[string][]*pkg.LocalPackage) {
+       map[string]*ResolvePackage,
+       map[string][]*ResolvePackage) {
 
-       apiMap := make(map[string]*pkg.LocalPackage, len(r.apis))
+       apiMap := make(map[string]*ResolvePackage, len(r.apis))
        anyUnsatisfied := false
        for api, rpkg := range r.apis {
                if rpkg == nil {
                        anyUnsatisfied = true
                } else {
-                       apiMap[api] = rpkg.LocalPackage
+                       apiMap[api] = rpkg
                }
        }
 
-       unsatisfied := map[string][]*pkg.LocalPackage{}
+       unsatisfied := map[string][]*ResolvePackage{}
        if anyUnsatisfied {
                for _, rpkg := range r.pkgMap {
                        for api, satisfied := range rpkg.reqApiMap {
                                if !satisfied {
                                        slice := unsatisfied[api]
-                                       slice = append(slice, rpkg.LocalPackage)
+                                       slice = append(slice, rpkg)
                                        unsatisfied[api] = slice
                                }
                        }
@@ -458,7 +529,7 @@ func ResolveFull(
                return nil, err
        }
 
-       res := &Resolution{}
+       res := newResolution()
        res.Cfg = r.cfg
        if err := r.resolveApiDeps(); err != nil {
                return nil, err
@@ -466,14 +537,17 @@ func ResolveFull(
 
        // Determine which package satisfies each API and which APIs are
        // unsatisfied.
-       apiMap := map[string]*pkg.LocalPackage{}
+       apiMap := map[string]*ResolvePackage{}
        apiMap, res.UnsatisfiedApis = r.apiResolution()
 
+       res.LpkgRpkgMap = r.pkgMap
+
        // If there is no loader, then the set of all packages is just the app
        // packages.  We already resolved the necessary dependency information 
when
        // syscfg was calculated above.
        if loaderSeeds == nil {
-               res.AppPkgs = r.lpkgSlice()
+               res.AppSet.Rpkgs = r.rpkgSlice()
+               res.LoaderSet = nil
                return res, nil
        }
 
@@ -486,9 +560,9 @@ func ResolveFull(
 
        // It is OK if the app requires an API that is supplied by the loader.
        // Ensure each set of packages has access to the API-providers.
-       for _, lpkg := range apiMap {
-               loaderSeeds = append(loaderSeeds, lpkg)
-               appSeeds = append(appSeeds, lpkg)
+       for _, rpkg := range apiMap {
+               loaderSeeds = append(loaderSeeds, rpkg.Lpkg)
+               appSeeds = append(appSeeds, rpkg.Lpkg)
        }
 
        // Resolve loader dependencies.
@@ -497,23 +571,23 @@ func ResolveFull(
 
        var err error
 
-       res.LoaderPkgs, err = r.resolveDeps()
+       res.LoaderSet.Rpkgs, err = r.resolveDeps()
        if err != nil {
                return nil, err
        }
 
        // Resolve app dependencies.  The app automtically gets all the packages
        // from the loader except for the loader-app-package.
-       for _, lpkg := range res.LoaderPkgs {
-               if lpkg.Type() != pkg.PACKAGE_TYPE_APP {
-                       appSeeds = append(appSeeds, lpkg)
+       for _, rpkg := range res.LoaderSet.Rpkgs {
+               if rpkg.Lpkg.Type() != pkg.PACKAGE_TYPE_APP {
+                       appSeeds = append(appSeeds, rpkg.Lpkg)
                }
        }
 
        r = newResolver(appSeeds, injectedSettings, flashMap)
        r.cfg = res.Cfg
 
-       res.AppPkgs, err = r.resolveDeps()
+       res.AppSet.Rpkgs, err = r.resolveDeps()
        if err != nil {
                return nil, err
        }
@@ -535,10 +609,10 @@ func (res *Resolution) ErrorText() string {
                for _, api := range apiNames {
                        str += fmt.Sprintf("    * %s, required by: ", api)
 
-                       pkgs := res.UnsatisfiedApis[api]
-                       pkgNames := make([]string, len(pkgs))
-                       for i, lpkg := range pkgs {
-                               pkgNames[i] = lpkg.Name()
+                       rpkgs := res.UnsatisfiedApis[api]
+                       pkgNames := make([]string, len(rpkgs))
+                       for i, rpkg := range rpkgs {
+                               pkgNames[i] = rpkg.Lpkg.Name()
                        }
                        sort.Strings(pkgNames)
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/e4ac2617/newt/resolve/resolveutil.go
----------------------------------------------------------------------
diff --git a/newt/resolve/resolveutil.go b/newt/resolve/resolveutil.go
new file mode 100644
index 0000000..23884d3
--- /dev/null
+++ b/newt/resolve/resolveutil.go
@@ -0,0 +1,92 @@
+/**
+* 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 (
+       "sort"
+
+       "mynewt.apache.org/newt/newt/pkg"
+)
+
+type rpkgSorter struct {
+       pkgs []*ResolvePackage
+}
+
+func (s rpkgSorter) Len() int {
+       return len(s.pkgs)
+}
+func (s rpkgSorter) Swap(i, j int) {
+       s.pkgs[i], s.pkgs[j] = s.pkgs[j], s.pkgs[i]
+}
+func (s rpkgSorter) Less(i, j int) bool {
+       return s.pkgs[i].Lpkg.FullName() < s.pkgs[j].Lpkg.FullName()
+}
+
+func SortResolvePkgs(pkgs []*ResolvePackage) []*ResolvePackage {
+       sorter := rpkgSorter{
+               pkgs: make([]*ResolvePackage, 0, len(pkgs)),
+       }
+
+       for _, p := range pkgs {
+               sorter.pkgs = append(sorter.pkgs, p)
+       }
+
+       sort.Sort(sorter)
+       return sorter.pkgs
+}
+
+type rdepSorter struct {
+       deps []*ResolveDep
+}
+
+func (s rdepSorter) Len() int {
+       return len(s.deps)
+}
+func (s rdepSorter) Swap(i, j int) {
+       s.deps[i], s.deps[j] = s.deps[j], s.deps[i]
+}
+
+func (s rdepSorter) Less(i, j int) bool {
+       return s.deps[i].Rpkg.Lpkg.FullName() < s.deps[j].Rpkg.Lpkg.FullName()
+}
+func SortResolveDeps(deps []*ResolveDep) []*ResolveDep {
+       sorter := rdepSorter{
+               deps: make([]*ResolveDep, 0, len(deps)),
+       }
+
+       for _, d := range deps {
+               sorter.deps = append(sorter.deps, d)
+       }
+
+       sort.Sort(sorter)
+       return sorter.deps
+}
+
+func RpkgSliceToLpkgSlice(rpkgs []*ResolvePackage) []*pkg.LocalPackage {
+       lpkgs := make([]*pkg.LocalPackage, len(rpkgs))
+
+       i := 0
+       for _, rpkg := range rpkgs {
+               lpkgs[i] = rpkg.Lpkg
+               i++
+       }
+
+       return lpkgs
+}

Reply via email to