func (t *TargetBuilder) extraADirs() []string {
	return []string{
		UserPreLinkSrcDir(t.target.FullName()),
	}
}
extraADirs returns a slice of extra directories that should be used at link
time.  .a files in these directores are used as input to the link (in
addition to .a files produced by building packages).
package builder
import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"strings"
	log "github.com/sirupsen/logrus"
	"github.com/apache/mynewt-artifact/flash"
	"github.com/apache/mynewt-artifact/sec"
	"mynewt.apache.org/newt/newt/flashmap"
	"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/target"
	"mynewt.apache.org/newt/newt/toolchain"
	"mynewt.apache.org/newt/util"
)
type TargetBuilder struct {
	target      *target.Target
	bspPkg      *pkg.BspPackage
	compilerPkg *pkg.LocalPackage
	appPkg      *pkg.LocalPackage
	loaderPkg   *pkg.LocalPackage
	testPkg     *pkg.LocalPackage
	AppBuilder *Builder
	AppList    interfaces.PackageList
	LoaderBuilder *Builder
	LoaderList    interfaces.PackageList
	keyFile          string
	injectedSettings map[string]string
	res *resolve.Resolution
}
func NewTargetTester(target *target.Target,
	testPkg *pkg.LocalPackage) (*TargetBuilder, error) {
	if err := target.Validate(testPkg == nil); err != nil {
		return nil, err
	}
	bspPkg, err := pkg.NewBspPackage(target.Bsp())
	if err != nil {
		return nil, err
	}
	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(),
		keyFile:          target.KeyFile,
		testPkg:          testPkg,
		injectedSettings: map[string]string{},
	}
	return t, nil
}
func NewTargetBuilder(target *target.Target) (*TargetBuilder, error) {
	return NewTargetTester(target, nil)
}
func (t *TargetBuilder) BspPkg() *pkg.BspPackage {
	return t.bspPkg
}
func (t *TargetBuilder) NewCompiler(dstDir string, buildProfile string) (
	*toolchain.Compiler, error) {
	if buildProfile == "" {
		buildProfile = t.target.BuildProfile
	}
	c, err := toolchain.NewCompiler(
		t.compilerPkg.BasePath(), dstDir, buildProfile)
	return c, err
}
func (t *TargetBuilder) injectNewtSettings() {
	t.InjectSetting("NEWT_FEATURE_LOGCFG", "1")
	t.InjectSetting("NEWT_FEATURE_SYSDOWN", "1")
}
func (t *TargetBuilder) injectBuildSettings() {
	t.InjectSetting("ARCH_NAME", "\""+t.bspPkg.Arch+"\"")
	t.InjectSetting("ARCH_"+util.CIdentifier(t.bspPkg.Arch), "1")
	if t.appPkg != nil {
		appName := filepath.Base(t.appPkg.Name())
		t.InjectSetting("APP_NAME", "\""+appName+"\"")
		t.InjectSetting("APP_"+util.CIdentifier(appName), "1")
	}
	bspName := filepath.Base(t.bspPkg.Name())
	t.InjectSetting("BSP_NAME", "\""+bspName+"\"")
	t.InjectSetting("BSP_"+util.CIdentifier(bspName), "1")
	tgtName := filepath.Base(t.target.Name())
	t.InjectSetting("TARGET_NAME", "\""+tgtName+"\"")
	t.InjectSetting("TARGET_"+util.CIdentifier(tgtName), "1")
}
func (t *TargetBuilder) resolveTransientPkgs(lps []*pkg.LocalPackage) {
	for i, lp := range lps {
		resolved := t.target.ResolvePackageName(lp.FullName())
		if resolved != lp {
			resolve.LogTransientWarning(lp)
			lps[i] = resolved
		}
	}
}
func (t *TargetBuilder) ensureResolved() error {
	if t.res != nil {
		return nil
	}
	t.injectNewtSettings()
	t.injectBuildSettings()
	var loaderSeeds []*pkg.LocalPackage
	if t.loaderPkg != nil {
		loaderSeeds = []*pkg.LocalPackage{
			t.target.LoaderYml(),
			t.target.BspYml(),
			t.compilerPkg,
			t.target.Package(),
		}
		t.resolveTransientPkgs(loaderSeeds)
		t.loaderPkg.InjectedSettings()["SPLIT_LOADER"] = "1"
		if t.appPkg != nil {
			t.appPkg.InjectedSettings()["SPLIT_APPLICATION"] = "1"
		}
		t.InjectSetting("SPLIT_IMAGE", "1")
	}
	appSeeds := []*pkg.LocalPackage{
		t.target.BspYml(),
		t.compilerPkg,
		t.target.Package(),
	}
	t.resolveTransientPkgs(appSeeds)
	if t.appPkg != nil {
		appSeeds = append(appSeeds, t.target.AppYml())
	}
	if t.testPkg != nil {
		t.InjectSetting("TEST", "1")
		t.InjectSetting("SELFTEST", "1")
		appSeeds = append(appSeeds, t.testPkg)
	}
	var err error
	t.res, err = resolve.ResolveFull(
		loaderSeeds, appSeeds, t.injectedSettings, t.bspPkg.FlashMap)
	if err != nil {
		return err
	}
	env := BasicEnvVars("", t.bspPkg)
	keys := make([]string, 0, len(env))
	for k, _ := range env {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	log.Debugf("exporting environment variables:")
	for _, k := range keys {
		v := env[k]
		log.Debugf("    %s=%s", k, env[k])
		err := os.Setenv(k, v)
		if err != nil {
			return util.FmtNewtError(
				"failed to set env var %s=%s: %s", k, v, err.Error())
		}
	}
	return nil
}
func (t *TargetBuilder) Resolve() (*resolve.Resolution, error) {
	if err := t.ensureResolved(); err != nil {
		return nil, err
	}
	return t.res, nil
}
func (t *TargetBuilder) validateAndWriteCfg() error {
	if err := t.ensureResolved(); err != nil {
		return err
	}
	if errText := t.res.ErrorText(); errText != "" {
		return util.NewNewtError(errText)
	}
	warningText := strings.TrimSpace(t.res.WarningText())
	if warningText != "" {
		log.Debug(warningText)
	}
	for _, line := range t.res.DeprecatedWarning() {
		log.Warn(line)
	}
	incDir := GeneratedIncludeDir(t.target.FullName())
	srcDir := GeneratedSrcDir(t.target.FullName())
	if err := syscfg.EnsureWritten(t.res.Cfg, incDir); err != nil {
		return err
	}
	if err := t.res.LCfg.EnsureWritten(incDir); err != nil {
		return err
	}
	if t.res.LoaderSet != nil {
		lpkgs := resolve.RpkgSliceToLpkgSlice(t.res.LoaderSet.Rpkgs)
		if err := t.res.SysinitCfg.EnsureWritten(lpkgs, srcDir,
			pkg.ShortName(t.target.Package()), true); err != nil {
			return err
		}
	}
	lpkgs := resolve.RpkgSliceToLpkgSlice(t.res.AppSet.Rpkgs)
	if err := t.res.SysinitCfg.EnsureWritten(lpkgs, srcDir,
		pkg.ShortName(t.target.Package()), false); err != nil {
		return err
	}
	if t.res.LoaderSet != nil {
		lpkgs := resolve.RpkgSliceToLpkgSlice(t.res.LoaderSet.Rpkgs)
		if err := t.res.SysdownCfg.EnsureWritten(lpkgs, srcDir,
			pkg.ShortName(t.target.Package()), true); err != nil {
			return err
		}
	}
	lpkgs = resolve.RpkgSliceToLpkgSlice(t.res.AppSet.Rpkgs)
	if err := t.res.SysdownCfg.EnsureWritten(lpkgs, srcDir,
		pkg.ShortName(t.target.Package()), false); err != nil {
		return err
	}
	if err := flashmap.EnsureFlashMapWritten(
		t.bspPkg.FlashMap,
		srcDir,
		incDir,
		pkg.ShortName(t.target.Package())); err != nil {
		return err
	}
	return nil
}