in newt/resolve/resolve.go [1167:1296]
func ResolveFull(
loaderSeeds []*pkg.LocalPackage,
appSeeds []*pkg.LocalPackage,
injectedSettings *cfgv.Settings,
flashMap flashmap.FlashMap) (*Resolution, error) {
// First, calculate syscfg and determine which package provides each
// required API. Syscfg and APIs are project-wide; that is, they are
// calculated across the aggregate of all app packages and loader packages
// (if any). The dependency graph for the entire set of packages gets
// calculated here as a byproduct.
allSeeds := append(loaderSeeds, appSeeds...)
r := newResolver(allSeeds, injectedSettings, flashMap)
if err := r.resolveDepsAndCfg(); err != nil {
return nil, err
}
res := newResolution()
res.Cfg = r.cfg
res.LCfg = r.lcfg
res.SysinitCfg = r.sysinitCfg
res.SysdownCfg = r.sysdownCfg
res.PreBuildCmdCfg = r.preBuildCmdCfg
res.PreLinkCmdCfg = r.preLinkCmdCfg
res.PostLinkCmdCfg = r.postLinkCmdCfg
warnMap := map[string]struct{}{}
for _, lines := range r.parseWarnings {
for _, line := range lines {
warnMap[line] = struct{}{}
}
}
for w, _ := range warnMap {
res.ParseWarnings = append(res.ParseWarnings, w)
}
sort.Strings(res.ParseWarnings)
// Determine which package satisfies each API and which APIs are
// unsatisfied.
res.ApiMap, res.UnsatisfiedApis = r.apiResolution()
for api, m := range r.apiConflicts {
c := ApiConflict{
Api: api,
}
for rpkg, _ := range m {
c.Pkgs = append(c.Pkgs, rpkg)
}
res.ApiConflicts = append(res.ApiConflicts, c)
}
res.LpkgRpkgMap = r.pkgMap
res.MasterSet.Rpkgs = r.rpkgSlice()
// We have now resolved all packages. Emit all warnings.
for _, warn := range res.ParseWarnings {
lines := strings.Split(warn, "\n")
for _, line := range lines {
util.OneTimeWarning("%s", line)
}
}
for _, rpkg := range res.MasterSet.Rpkgs {
LogTransientWarning(rpkg.Lpkg)
}
// 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.AppSet.Rpkgs = r.rpkgSlice()
res.LoaderSet = nil
res.Cfg.DetectErrors(flashMap)
return res, nil
}
// Otherwise, we need to resolve dependencies separately for:
// 1. The set of loader packages, and
// 2. The set of app packages.
//
// These need to be resolved separately so that it is possible later to
// determine which packages need to be shared between loader and app.
// 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 _, rpkg := range res.ApiMap {
loaderSeeds = append(loaderSeeds, rpkg.Lpkg)
appSeeds = append(appSeeds, rpkg.Lpkg)
}
// Resolve loader dependencies.
r = newResolver(loaderSeeds, injectedSettings, flashMap)
r.cfg = res.Cfg
var err error
res.LoaderSet.Rpkgs, err = r.resolveDeps()
if err != nil {
return nil, err
}
if err := res.LoaderSet.useMasterPkgs(); 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 _, 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.AppSet.Rpkgs, err = r.resolveDeps()
if err != nil {
return nil, err
}
if err := res.AppSet.useMasterPkgs(); err != nil {
return nil, err
}
res.Cfg.DetectErrors(flashMap)
return res, nil
}