This is an automated email from the ASF dual-hosted git repository. ccollins pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-newt.git
commit 8f35dc970558a7743cada22be28f0888edaf6abe Author: Christopher Collins <ccoll...@apache.org> AuthorDate: Thu Sep 19 10:05:26 2019 -0500 Separate env var generation from builder Before commit: a `Builder` object was required to calculate the environment variables to pass to external scripts. This is a nuissance when no `Builder` is available (e.g., when loading an mfgimage, or for the upcomimg per-package commands feature). After commit: Environment variables are divided into three sets (basic, settings, slot). The sets are divided according to the inputs required to generate them. Now the appropriate variables can be calculated without a `Builder` object. --- newt/builder/buildutil.go | 134 ++++++++++++++++++++++++++++++++++++++++++++-- newt/builder/load.go | 89 ++++++++++-------------------- 2 files changed, 159 insertions(+), 64 deletions(-) diff --git a/newt/builder/buildutil.go b/newt/builder/buildutil.go index 6f23783..e06bd12 100644 --- a/newt/builder/buildutil.go +++ b/newt/builder/buildutil.go @@ -22,24 +22,29 @@ package builder import ( "bytes" "sort" + "strconv" "strings" log "github.com/sirupsen/logrus" "mynewt.apache.org/newt/newt/parse" + "mynewt.apache.org/newt/newt/pkg" + "mynewt.apache.org/newt/newt/project" "mynewt.apache.org/newt/newt/resolve" + "mynewt.apache.org/newt/util" ) func TestTargetName(testPkgName string) string { return strings.Replace(testPkgName, "/", "_", -1) } -func (b *Builder) FeatureString() string { +// FeatureString converts a syscfg map to a string. The string is a +// space-separate list of "enabled" settings. +func FeatureString(settings map[string]string) string { var buffer bytes.Buffer - settingMap := b.cfg.SettingValues() - featureSlice := make([]string, 0, len(settingMap)) - for k, v := range settingMap { + featureSlice := make([]string, 0, len(settings)) + for k, v := range settings { if parse.ValueIsTrue(v) { featureSlice = append(featureSlice, k) } @@ -53,6 +58,7 @@ func (b *Builder) FeatureString() string { buffer.WriteString(feature) } + return buffer.String() } @@ -126,3 +132,123 @@ func logDepInfo(res *resolve.Resolution) { log.Debugf("%s", RevdepGraphText(rdg)) } } + +// binBasePath calculates the relative path of the "application binary" +// directory. Examples: +// * bin/targets/my_blinky_sim/app +// * bin/targets/splitty-nrf52dk/loader +func (b *Builder) binBasePath() (string, error) { + if b.appPkg == nil { + return "", util.NewNewtError("app package not specified") + } + + // Convert the binary path from absolute to relative. This is required for + // Windows compatibility. + return util.TryRelPath(b.AppBinBasePath()), nil +} + +// BasicEnvVars calculates the basic set of environment variables passed to all +// external scripts. `binBase` is the result of calling `binBasePath()`. +func BasicEnvVars(binBase string, bspPkg *pkg.BspPackage) map[string]string { + coreRepo := project.GetProject().FindRepo("apache-mynewt-core") + bspPath := bspPkg.BasePath() + + return map[string]string{ + "CORE_PATH": coreRepo.Path(), + "BSP_PATH": bspPath, + "BIN_BASENAME": binBase, + "BIN_ROOT": BinRoot(), + "MYNEWT_PROJECT_ROOT": ProjectRoot(), + } +} + +// SettingsEnvVars calculates the syscfg set of environment variables required +// by image loading scripts. +func SettingsEnvVars(settings map[string]string) map[string]string { + env := map[string]string{} + + // Add all syscfg settings to the environment with the MYNEWT_VAL_ prefix. + for k, v := range settings { + env["MYNEWT_VAL_"+k] = v + } + + if parse.ValueIsTrue(settings["BOOT_LOADER"]) { + env["BOOT_LOADER"] = "1" + } + + env["FEATURES"] = FeatureString(settings) + + return env +} + +// SlotEnvVars calculates the image-slot set of environment variables required +// by image loading scripts. Pass a negative `imageSlot` value if the target +// is a boot loader. +func SlotEnvVars(bspPkg *pkg.BspPackage, + imageSlot int) (map[string]string, error) { + + env := map[string]string{} + + var flashTargetArea string + if imageSlot < 0 { + flashTargetArea = "FLASH_AREA_BOOTLOADER" + } else { + env["IMAGE_SLOT"] = strconv.Itoa(imageSlot) + switch imageSlot { + case 0: + flashTargetArea = "FLASH_AREA_IMAGE_0" + case 1: + flashTargetArea = "FLASH_AREA_IMAGE_1" + default: + return nil, util.FmtNewtError( + "invalid image slot: have=%d want=0or1", imageSlot) + } + } + + tgtArea := bspPkg.FlashMap.Areas[flashTargetArea] + if tgtArea.Name == "" { + return nil, util.FmtNewtError( + "No flash target area %s", flashTargetArea) + } + + env["FLASH_OFFSET"] = "0x" + strconv.FormatInt(int64(tgtArea.Offset), 16) + env["FLASH_AREA_SIZE"] = "0x" + strconv.FormatInt(int64(tgtArea.Size), 16) + + return env, nil +} + +// EnvVars calculates the full set of environment variables passed to external +// scripts. +func (b *Builder) EnvVars(imageSlot int) (map[string]string, error) { + bspPkg := b.targetBuilder.bspPkg + settings := b.cfg.SettingValues() + + binBasePath, err := b.binBasePath() + if err != nil { + return nil, err + } + + // Calculate all three sets of environment variables: basic, settings, and + // slot. Then merge the three sets into one. + + env := BasicEnvVars(binBasePath, bspPkg) + setEnv := SettingsEnvVars(settings) + + if parse.ValueIsTrue(settings["BOOT_LOADER"]) { + imageSlot = -1 + } + + slotEnv, err := SlotEnvVars(bspPkg, imageSlot, settings) + if err != nil { + return nil, err + } + + for k, v := range setEnv { + env[k] = v + } + for k, v := range slotEnv { + env[k] = v + } + + return env, nil +} diff --git a/newt/builder/load.go b/newt/builder/load.go index 9d76060..940a934 100644 --- a/newt/builder/load.go +++ b/newt/builder/load.go @@ -24,11 +24,9 @@ import ( "os" "os/signal" "sort" - "strconv" "strings" "syscall" - "mynewt.apache.org/newt/newt/parse" "mynewt.apache.org/newt/newt/pkg" "mynewt.apache.org/newt/newt/project" "mynewt.apache.org/newt/util" @@ -117,40 +115,36 @@ func RunOptionalCheck(checkScript string, env []string) error { return nil } -func Load(binBaseName string, bspPkg *pkg.BspPackage, +func Load(binBasePath string, bspPkg *pkg.BspPackage, extraEnvSettings map[string]string) error { if bspPkg.DownloadScript == "" { return nil } - bspPath := bspPkg.BasePath() + env := BasicEnvVars(binBasePath, bspPkg) + for k, v := range extraEnvSettings { + env[k] = v + } - sortedKeys := make([]string, 0, len(extraEnvSettings)) - for k, _ := range extraEnvSettings { + sortedKeys := make([]string, 0, len(env)) + for k, _ := range env { sortedKeys = append(sortedKeys, k) } sort.Strings(sortedKeys) - env := []string{} + envSlice := []string{} for _, key := range sortedKeys { - env = append(env, fmt.Sprintf("%s=%s", key, extraEnvSettings[key])) + envSlice = append(envSlice, fmt.Sprintf("%s=%s", key, env[key])) } - coreRepo := project.GetProject().FindRepo("apache-mynewt-core") - env = append(env, fmt.Sprintf("CORE_PATH=%s", coreRepo.Path())) - env = append(env, fmt.Sprintf("BSP_PATH=%s", bspPath)) - env = append(env, fmt.Sprintf("BIN_BASENAME=%s", binBaseName)) - env = append(env, fmt.Sprintf("BIN_ROOT=%s", BinRoot())) - env = append(env, fmt.Sprintf("MYNEWT_PROJECT_ROOT=%s", ProjectRoot())) - - RunOptionalCheck(bspPkg.OptChkScript, env) - // bspPath, binBaseName are passed in command line for backwards + RunOptionalCheck(bspPkg.OptChkScript, envSlice) + // bspPath, binBasePath are passed in command line for backwards // compatibility cmd := []string{ bspPkg.DownloadScript, - bspPath, - binBaseName, + bspPkg.BasePath(), + binBasePath, } util.StatusMessage(util.VERBOSITY_VERBOSE, "Load command: %s\n", @@ -159,7 +153,7 @@ func Load(binBaseName string, bspPkg *pkg.BspPackage, for _, v := range env { util.StatusMessage(util.VERBOSITY_VERBOSE, "* %s\n", v) } - if _, err := util.ShellCommand(cmd, env); err != nil { + if _, err := util.ShellCommand(cmd, envSlice); err != nil { return err } util.StatusMessage(util.VERBOSITY_VERBOSE, "Successfully loaded image.\n") @@ -178,50 +172,27 @@ func (b *Builder) Load(imageSlot int, extraJtagCmd string) error { return err } - envSettings := map[string]string{ - "IMAGE_SLOT": strconv.Itoa(imageSlot), - "FEATURES": b.FeatureString(), + env, err := b.EnvVars(imageSlot) + if err != nil { + return err } + if extraJtagCmd != "" { - envSettings["EXTRA_JTAG_CMD"] = extraJtagCmd + env["EXTRA_JTAG_CMD"] = extraJtagCmd } - settings := b.cfg.SettingValues() - var flashTargetArea string - if parse.ValueIsTrue(settings["BOOT_LOADER"]) { - envSettings["BOOT_LOADER"] = "1" - - flashTargetArea = "FLASH_AREA_BOOTLOADER" + if _, ok := env["BOOT_LOADER"]; ok { util.StatusMessage(util.VERBOSITY_DEFAULT, "Loading bootloader\n") } else { - if imageSlot == 0 { - flashTargetArea = "FLASH_AREA_IMAGE_0" - } else if imageSlot == 1 { - flashTargetArea = "FLASH_AREA_IMAGE_1" - } util.StatusMessage(util.VERBOSITY_DEFAULT, "Loading %s image into slot %d\n", b.buildName, imageSlot+1) } - bspPkg := b.targetBuilder.bspPkg - tgtArea := bspPkg.FlashMap.Areas[flashTargetArea] - if tgtArea.Name == "" { - return util.NewNewtError(fmt.Sprintf("No flash target area %s\n", - flashTargetArea)) - } - envSettings["FLASH_OFFSET"] = "0x" + strconv.FormatInt(int64(tgtArea.Offset), 16) - envSettings["FLASH_AREA_SIZE"] = "0x" + strconv.FormatInt(int64(tgtArea.Size), 16) - - // Add all syscfg settings to the environment with the MYNEWT_VAL_ prefix. - for k, v := range settings { - envSettings["MYNEWT_VAL_"+k] = v - } - // Convert the binary path from absolute to relative. This is required for // compatibility with unix-in-windows environemnts (e.g., cygwin). binPath := util.TryRelPath(b.AppBinBasePath()) - if err := Load(binPath, b.targetBuilder.bspPkg, envSettings); err != nil { + if err := Load(binPath, b.targetBuilder.bspPkg, env); err != nil { return err } @@ -250,15 +221,15 @@ func (b *Builder) debugBin(binPath string, extraJtagCmd string, reset bool, } bspPath := b.bspPkg.rpkg.Lpkg.BasePath() - binBaseName := binPath - featureString := b.FeatureString() + binBasePath := binPath + featureString := FeatureString(b.cfg.SettingValues()) bspPkg := b.targetBuilder.bspPkg coreRepo := project.GetProject().FindRepo("apache-mynewt-core") envSettings := []string{ fmt.Sprintf("CORE_PATH=%s", coreRepo.Path()), fmt.Sprintf("BSP_PATH=%s", bspPath), - fmt.Sprintf("BIN_BASENAME=%s", binBaseName), + fmt.Sprintf("BIN_BASENAME=%s", binBasePath), fmt.Sprintf("FEATURES=%s", featureString), fmt.Sprintf("MYNEWT_PROJECT_ROOT=%s", ProjectRoot()), } @@ -276,10 +247,10 @@ func (b *Builder) debugBin(binPath string, extraJtagCmd string, reset bool, os.Chdir(project.GetProject().Path()) RunOptionalCheck(bspPkg.OptChkScript, envSettings) - // bspPath, binBaseName are passed in command line for backwards + // bspPath, binBasePath are passed in command line for backwards // compatibility cmdLine := []string{ - b.targetBuilder.bspPkg.DebugScript, bspPath, binBaseName, + b.targetBuilder.bspPkg.DebugScript, bspPath, binBasePath, } fmt.Printf("%s\n", cmdLine) @@ -287,12 +258,10 @@ func (b *Builder) debugBin(binPath string, extraJtagCmd string, reset bool, } func (b *Builder) Debug(extraJtagCmd string, reset bool, noGDB bool) error { - if b.appPkg == nil { - return util.NewNewtError("app package not specified") + binPath, err := b.binBasePath() + if err != nil { + return err } - // Convert the binary path from absolute to relative. This is required for - // Windows compatibility. - binPath := util.TryRelPath(b.AppBinBasePath()) return b.debugBin(binPath, extraJtagCmd, reset, noGDB) }