http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/builder/paths.go ---------------------------------------------------------------------- diff --git a/newt/builder/paths.go b/newt/builder/paths.go deleted file mode 100644 index 5beb6b3..0000000 --- a/newt/builder/paths.go +++ /dev/null @@ -1,185 +0,0 @@ -/** - * 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 builder - -import ( - "path/filepath" - - "mynewt.apache.org/newt/newt/interfaces" - "mynewt.apache.org/newt/newt/pkg" - "mynewt.apache.org/newt/newt/project" - "mynewt.apache.org/newt/util" -) - -const BUILD_NAME_APP = "app" -const BUILD_NAME_LOADER = "loader" - -func BinRoot() string { - return project.GetProject().Path() + "/bin" -} - -func TargetBinDir(targetName string) string { - return BinRoot() + "/" + targetName -} - -func GeneratedBaseDir(targetName string) string { - return BinRoot() + "/" + targetName + "/generated" -} - -func GeneratedSrcDir(targetName string) string { - return GeneratedBaseDir(targetName) + "/src" -} - -func GeneratedIncludeDir(targetName string) string { - return GeneratedBaseDir(targetName) + "/include" -} - -func GeneratedBinDir(targetName string) string { - return GeneratedBaseDir(targetName) + "/bin" -} - -func SysinitArchivePath(targetName string) string { - return GeneratedBinDir(targetName) + "/sysinit.a" -} - -func PkgSyscfgPath(pkgPath string) string { - return pkgPath + "/" + pkg.SYSCFG_YAML_FILENAME -} - -func BinDir(targetName string, buildName string) string { - return BinRoot() + "/" + targetName + "/" + buildName -} - -func FileBinDir(targetName string, buildName string, pkgName string) string { - return BinDir(targetName, buildName) + "/" + pkgName -} - -func PkgBinDir(targetName string, buildName string, pkgName string, - pkgType interfaces.PackageType) string { - - switch pkgType { - case pkg.PACKAGE_TYPE_GENERATED: - return GeneratedBinDir(targetName) - default: - return FileBinDir(targetName, buildName, pkgName) - } -} - -func ArchivePath(targetName string, buildName string, pkgName string, - pkgType interfaces.PackageType) string { - - filename := util.FilenameFromPath(pkgName) + ".a" - return PkgBinDir(targetName, buildName, pkgName, pkgType) + "/" + filename -} - -func AppElfPath(targetName string, buildName string, appName string) string { - return FileBinDir(targetName, buildName, appName) + "/" + - filepath.Base(appName) + ".elf" -} - -func AppBinPath(targetName string, buildName string, appName string) string { - return AppElfPath(targetName, buildName, appName) + ".bin" -} - -func TestExePath(targetName string, buildName string, pkgName string, - pkgType interfaces.PackageType) string { - - return PkgBinDir(targetName, buildName, pkgName, pkgType) + "/" + - TestTargetName(pkgName) + ".elf" -} - -func ManifestPath(targetName string, buildName string, pkgName string) string { - return FileBinDir(targetName, buildName, pkgName) + "/manifest.json" -} - -func AppImgPath(targetName string, buildName string, appName string) string { - return FileBinDir(targetName, buildName, appName) + "/" + - filepath.Base(appName) + ".img" -} - -func MfgBinDir(mfgPkgName string) string { - return BinRoot() + "/" + mfgPkgName -} - -func MfgBootDir(mfgPkgName string) string { - return MfgBinDir(mfgPkgName) + "/bootloader" -} - -func (b *Builder) BinDir() string { - return BinDir(b.targetPkg.rpkg.Lpkg.Name(), b.buildName) -} - -func (b *Builder) FileBinDir(pkgName string) string { - return FileBinDir(b.targetPkg.rpkg.Lpkg.Name(), b.buildName, pkgName) -} - -func (b *Builder) PkgBinDir(bpkg *BuildPackage) string { - 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.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.rpkg.Lpkg.Name()) + - "_tmp.elf" -} - -func (b *Builder) AppElfPath() string { - 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.rpkg.Lpkg.Name()) + - "linker.elf" -} - -func (b *Builder) AppImgPath() string { - return b.PkgBinDir(b.appPkg) + "/" + filepath.Base(b.appPkg.rpkg.Lpkg.Name()) + - ".img" -} - -func (b *Builder) AppBinPath() string { - return b.AppElfPath() + ".bin" -} - -func (b *Builder) AppPath() string { - return b.PkgBinDir(b.appPkg) + "/" -} - -func (b *Builder) TestExePath(bpkg *BuildPackage) string { - 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.rpkg.Lpkg.Name(), b.buildName, - b.appPkg.rpkg.Lpkg.Name()) -} - -func (b *Builder) AppBinBasePath() string { - return b.PkgBinDir(b.appPkg) + "/" + - filepath.Base(b.appPkg.rpkg.Lpkg.Name()) -}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/builder/selftest.go ---------------------------------------------------------------------- diff --git a/newt/builder/selftest.go b/newt/builder/selftest.go deleted file mode 100644 index fc7268c..0000000 --- a/newt/builder/selftest.go +++ /dev/null @@ -1,174 +0,0 @@ -/** - * 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 builder - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - "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) 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 - } - - 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 - } - - if err := t.AppBuilder.Build(); err != nil { - return err - } - - testRpkg, err := t.getTestRpkg() - if err != nil { - return err - } - - if err := t.AppBuilder.SelfTestLink(testRpkg); err != nil { - return err - } - - return nil -} - -func (t *TargetBuilder) SelfTestExecute() error { - if err := t.SelfTestCreateExe(); err != nil { - return err - } - - testRpkg, err := t.getTestRpkg() - if err != nil { - return err - } - - if err := t.AppBuilder.SelfTestExecute(testRpkg); err != nil { - return err - } - - return nil -} - -func (t *TargetBuilder) SelfTestDebug() error { - if err := t.PrepBuild(); err != nil { - return err - } - - testRpkg, err := t.getTestRpkg() - if err != nil { - return err - } - - testBpkg, err := t.AppBuilder.getTestBpkg(testRpkg) - if err != nil { - return err - } - - return t.AppBuilder.debugBin( - strings.TrimSuffix(t.AppBuilder.TestExePath(testBpkg), ".elf"), - "", false, false) -} - -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 := bpkg.rpkg.Lpkg.BasePath() - - for { - parentPath := filepath.Dir(curPath) - if parentPath == project.GetProject().BasePath || parentPath == "." { - return nil - } - - parentPkg := b.pkgWithPath(parentPath) - if parentPkg != nil && - parentPkg.rpkg.Lpkg.Type() != pkg.PACKAGE_TYPE_UNITTEST { - - return parentPkg - } - - curPath = parentPath - } -} - -func (b *Builder) SelfTestExecute(testRpkg *resolve.ResolvePackage) error { - testBpkg, err := b.getTestBpkg(testRpkg) - if err != nil { - return err - } - - testPath := b.TestExePath(testBpkg) - if err := os.Chdir(filepath.Dir(testPath)); err != nil { - return err - } - - util.StatusMessage(util.VERBOSITY_DEFAULT, "Executing test: %s\n", - testPath) - cmd := []string{testPath} - if _, err := util.ShellCommand(cmd, nil); err != nil { - newtError := err.(*util.NewtError) - newtError.Text = fmt.Sprintf("Test failure (%s):\n%s", - testRpkg.Lpkg.Name(), newtError.Text) - return newtError - } - - return nil -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/builder/size.go ---------------------------------------------------------------------- diff --git a/newt/builder/size.go b/newt/builder/size.go deleted file mode 100644 index 7cdcc45..0000000 --- a/newt/builder/size.go +++ /dev/null @@ -1,534 +0,0 @@ -/** - * 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 builder - -import ( - "bufio" - "fmt" - "os" - "path/filepath" - "sort" - "strconv" - "strings" - - "mynewt.apache.org/newt/newt/image" - "mynewt.apache.org/newt/util" -) - -/* - * These are different memory regions as specified in linker script. - */ -type MemSection struct { - Name string - Offset uint64 - EndOff uint64 -} -type MemSectionArray []*MemSection - -var globalMemSections map[string]*MemSection - -func (array MemSectionArray) Len() int { - return len(array) -} - -func (array MemSectionArray) Less(i, j int) bool { - return array[i].Offset < array[j].Offset -} - -func (array MemSectionArray) Swap(i, j int) { - array[i], array[j] = array[j], array[i] -} - -func MakeMemSection(name string, off uint64, size uint64) *MemSection { - memsection := &MemSection{ - Name: name, - Offset: off, - EndOff: off + size, - } - return memsection -} - -func (m *MemSection) PartOf(addr uint64) bool { - if addr >= m.Offset && addr < m.EndOff { - return true - } else { - return false - } -} - -/* - * Info about specific symbol size - */ -type SymbolData struct { - Name string - ObjName string /* Which object file it came from */ - Sizes map[string]uint32 /* Sizes indexed by mem section name */ -} - -type SymbolDataArray []*SymbolData - -/* - * We accumulate the size of libraries to elements in this. - */ -type PkgSize struct { - Name string - Sizes map[string]uint32 /* Sizes indexed by mem section name */ - Syms map[string]*SymbolData /* Symbols indexed by symbol name */ -} - -type PkgSizeArray []*PkgSize - -func (array PkgSizeArray) Len() int { - return len(array) -} - -func (array PkgSizeArray) Less(i, j int) bool { - return array[i].Name < array[j].Name -} - -func (array PkgSizeArray) Swap(i, j int) { - array[i], array[j] = array[j], array[i] -} - -func (array SymbolDataArray) Len() int { - return len(array) -} - -func (array SymbolDataArray) Less(i, j int) bool { - return array[i].Name < array[j].Name -} - -func (array SymbolDataArray) Swap(i, j int) { - array[i], array[j] = array[j], array[i] -} - -func MakeSymbolData(name string, objName string) *SymbolData { - sym := &SymbolData{ - Name: name, - ObjName: objName, - } - sym.Sizes = make(map[string]uint32) - for _, sec := range globalMemSections { - sym.Sizes[sec.Name] = 0 - } - return sym -} - -func MakePkgSize(name string) *PkgSize { - pkgSize := &PkgSize{ - Name: name, - } - pkgSize.Sizes = make(map[string]uint32) - for _, sec := range globalMemSections { - pkgSize.Sizes[sec.Name] = 0 - } - pkgSize.Syms = make(map[string]*SymbolData) - return pkgSize -} - -func (ps *PkgSize) addSymSize(symName string, objName string, size uint32, addr uint64) { - for _, section := range globalMemSections { - if section.PartOf(addr) { - name := section.Name - size32 := uint32(size) - if size32 > 0 { - sym := ps.Syms[symName] - if sym == nil { - sym = MakeSymbolData(symName, objName) - ps.Syms[symName] = sym - } - ps.Sizes[name] += size32 - sym.Sizes[name] += size32 - } - break - } - } -} - -/* - * Go through GCC generated mapfile, and collect info about symbol sizes - */ -func ParseMapFileSizes(fileName string) (map[string]*PkgSize, error) { - var state int = 0 - - file, err := os.Open(fileName) - if err != nil { - return nil, util.NewNewtError("Mapfile failed: " + err.Error()) - } - - var symName string = "" - - globalMemSections = make(map[string]*MemSection) - pkgSizes := make(map[string]*PkgSize) - scanner := bufio.NewScanner(file) - for scanner.Scan() { - switch state { - case 0: - if strings.Contains(scanner.Text(), "Memory Configuration") { - state = 1 - } - case 1: - if strings.Contains(scanner.Text(), "Origin") { - state = 2 - } - case 2: - if strings.Contains(scanner.Text(), "*default*") { - state = 3 - continue - } - array := strings.Fields(scanner.Text()) - offset, err := strconv.ParseUint(array[1], 0, 64) - if err != nil { - return nil, util.NewNewtError("Can't parse mem info") - } - size, err := strconv.ParseUint(array[2], 0, 64) - if err != nil { - return nil, util.NewNewtError("Can't parse mem info") - } - globalMemSections[array[0]] = MakeMemSection(array[0], offset, - size) - case 3: - if strings.Contains(scanner.Text(), - "Linker script and memory map") { - state = 4 - } - case 4: - var addrStr string = "" - var sizeStr string = "" - var srcFile string = "" - - if strings.Contains(scanner.Text(), "/DISCARD/") || - strings.HasPrefix(scanner.Text(), "OUTPUT(") { - /* - * After this there is only discarded symbols - */ - state = 5 - continue - } - - array := strings.Fields(scanner.Text()) - switch len(array) { - case 1: - /* - * section name on it's own, e.g. - * *(.text*) - * - * section name + symbol name, e.g. - * .text.Reset_Handler - * - * ignore these for now - */ - symName = array[0] - continue - case 2: - /* - * Either stuff from beginning to first useful data e.g. - * END GROUP - * - * or address of symbol + symbol name, e.g. - * 0x00000000080002c8 SystemInit - * - * or section names with multiple input things, e.g. - * *(.ARM.extab* .gnu.linkonce.armextab.*) - * - * or space set aside in linker script e.g. - * 0x0000000020002e80 0x400 - * (that's the initial stack) - * - * ignore these for now - */ - continue - case 3: - /* - * address, size, and name of file, e.g. - * 0x000000000800bb04 0x1050 /Users/marko/foo/tadpole/hw//mcu/stm/stm32f3xx/bin/blinky_f3/libstm32f3xx.a(stm32f30x_syscfg.o) - * - * padding, or empty areas defined in linker script: - * *fill* 0x000000000800cb71 0x3 - * - * output section name, location, size, e.g.: - * .bss 0x0000000020000ab0 0x23d0 - */ - /* - * Record addr, size and name to find library. - */ - if array[0] == "*fill*" { - addrStr = array[1] - sizeStr = array[2] - srcFile = array[0] - symName = array[0] - } else { - addrStr = array[0] - sizeStr = array[1] - srcFile = array[2] - } - case 4: - /* - * section, address, size, name of file, e.g. - * COMMON 0x0000000020002d28 0x8 /Users/marko/foo/tadpole/libs//os/bin/blinky_f3/libos.a(os_arch_arm.o) - * - * linker script symbol definitions: - * 0x0000000020002e80 _ebss = . - * - * crud, e.g.: - * 0x8 (size before relaxing) - */ - symName = array[0] - addrStr = array[1] - sizeStr = array[2] - srcFile = array[3] - default: - continue - } - addr, err := strconv.ParseUint(addrStr, 0, 64) - if err != nil { - continue - } - size, err := strconv.ParseUint(sizeStr, 0, 64) - if err != nil { - continue - } - if size == 0 { - continue - } - tmpStrArr := strings.Split(srcFile, "(") - srcLib := tmpStrArr[0] - objName := "" - if srcLib != "*fill*" { - tmpStrArr = strings.Split(tmpStrArr[1], ")") - objName = tmpStrArr[0] - } - tmpStrArr = strings.Split(symName, ".") - if len(tmpStrArr) > 2 { - if tmpStrArr[1] == "rodata" && tmpStrArr[2] == "str1" { - symName = ".rodata.str1" - } else { - symName = tmpStrArr[2] - } - } - pkgSize := pkgSizes[srcLib] - if pkgSize == nil { - pkgSize = MakePkgSize(srcLib) - pkgSizes[srcLib] = pkgSize - } - pkgSize.addSymSize(symName, objName, uint32(size), addr) - symName = ".unknown" - default: - } - } - file.Close() - for name, section := range globalMemSections { - util.StatusMessage(util.VERBOSITY_VERBOSE, "Mem %s: 0x%x-0x%x\n", - name, section.Offset, section.EndOff) - } - - return pkgSizes, nil -} - -/* - * Return a printable string containing size data for the libraries - */ -func PrintSizes(libs map[string]*PkgSize) error { - /* - * Order sections by offset, and display lib sizes in that order. - */ - memSections := make(MemSectionArray, len(globalMemSections)) - var i int = 0 - for _, sec := range globalMemSections { - memSections[i] = sec - i++ - } - sort.Sort(memSections) - - /* - * Order libraries by name, and display them in that order. - */ - pkgSizes := make(PkgSizeArray, len(libs)) - i = 0 - for _, es := range libs { - pkgSizes[i] = es - i++ - } - sort.Sort(pkgSizes) - - for _, sec := range memSections { - fmt.Printf("%7s ", sec.Name) - } - fmt.Printf("\n") - for _, es := range pkgSizes { - for i := 0; i < len(memSections); i++ { - fmt.Printf("%7d ", es.Sizes[memSections[i].Name]) - } - fmt.Printf("%s\n", filepath.Base(es.Name)) - } - - return nil -} - -func (t *TargetBuilder) Size() error { - - err := t.PrepBuild() - - if err != nil { - return err - } - - fmt.Printf("Size of Application Image: %s\n", t.AppBuilder.buildName) - err = t.AppBuilder.Size() - - if err == nil { - if t.LoaderBuilder != nil { - fmt.Printf("Size of Loader Image: %s\n", t.LoaderBuilder.buildName) - err = t.LoaderBuilder.Size() - } - } - - return err -} - -func (b *Builder) FindPkgNameByArName(arName string) string { - for rpkg, bpkg := range b.PkgMap { - if b.ArchivePath(bpkg) == arName { - return rpkg.Lpkg.FullName() - } - } - return filepath.Base(arName) -} - -func (b *Builder) PkgSizes() (*image.ImageManifestSizeCollector, error) { - if b.appPkg == nil { - return nil, util.NewNewtError("app package not specified for this target") - } - - if b.targetBuilder.bspPkg.Arch == "sim" { - return nil, util.NewNewtError("'newt size' not supported for sim targets") - } - mapFile := b.AppElfPath() + ".map" - - libs, err := ParseMapFileSizes(mapFile) - if err != nil { - return nil, err - } - - /* - * Order libraries by name. - */ - pkgSizes := make(PkgSizeArray, len(libs)) - i := 0 - for _, es := range libs { - pkgSizes[i] = es - i++ - } - sort.Sort(pkgSizes) - - c := image.NewImageManifestSizeCollector() - for _, es := range pkgSizes { - p := c.AddPkg(b.FindPkgNameByArName(es.Name)) - - /* - * Order symbols by name. - */ - symbols := make(SymbolDataArray, len(es.Syms)) - i := 0 - for _, sym := range es.Syms { - symbols[i] = sym - i++ - } - sort.Sort(symbols) - for _, sym := range symbols { - for area, areaSz := range sym.Sizes { - if areaSz != 0 { - p.AddSymbol(sym.ObjName, sym.Name, area, areaSz) - } - } - } - } - - return c, nil -} - -func (b *Builder) Size() error { - if b.appPkg == nil { - return util.NewNewtError("app package not specified for this target") - } - - err := b.targetBuilder.PrepBuild() - if err != nil { - return err - } - if b.targetBuilder.bspPkg.Arch == "sim" { - fmt.Println("'newt size' not supported for sim targets.") - return nil - } - mapFile := b.AppElfPath() + ".map" - - pkgSizes, err := ParseMapFileSizes(mapFile) - if err != nil { - return err - } - err = PrintSizes(pkgSizes) - if err != nil { - return err - } - - c, err := b.newCompiler(b.appPkg, b.FileBinDir(b.AppElfPath())) - if err != nil { - return err - } - - fmt.Printf("\nobjsize\n") - output, err := c.PrintSize(b.AppElfPath()) - if err != nil { - return err - } - fmt.Printf("%s", output) - - return nil -} - -func (t *TargetBuilder) SizeReport(ram, flash bool) error { - - err := t.PrepBuild() - - if err != nil { - return err - } - - fmt.Printf("Size of Application Image: %s\n", t.AppBuilder.buildName) - err = t.AppBuilder.SizeReport(ram, flash) - - if err == nil { - if t.LoaderBuilder != nil { - fmt.Printf("Size of Loader Image: %s\n", t.LoaderBuilder.buildName) - err = t.LoaderBuilder.SizeReport(ram, flash) - } - } - - return err -} - -func (b *Builder) SizeReport(ram, flash bool) error { - srcBase := b.targetBuilder.GetTarget().App().Repo().Path() + "/" - err := SizeReport(b.AppElfPath(), srcBase, ram, flash) - if err != nil { - return util.NewNewtError(err.Error()) - } - return nil -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/builder/size_report.go ---------------------------------------------------------------------- diff --git a/newt/builder/size_report.go b/newt/builder/size_report.go deleted file mode 100644 index 5c9fa02..0000000 --- a/newt/builder/size_report.go +++ /dev/null @@ -1,332 +0,0 @@ -/** - * 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 builder - -import ( - "bufio" - "fmt" - "mynewt.apache.org/newt/util" - "os" - "os/exec" - "strconv" - "strings" -) - -func runNmCommand(elfFilePath string) ([]byte, error) { - var ( - cmdOut []byte - err error - ) - cmdName := "arm-none-eabi-nm" - cmdArgs := []string{elfFilePath, "-S", "-l", "--size-sort", "--radix=d"} - - if cmdOut, err = exec.Command(cmdName, cmdArgs...).Output(); err != nil { - fmt.Fprintln(os.Stderr, "There was an error running nm command: ", err) - os.Exit(1) - } - - return cmdOut, err -} - -func runObjdumpCommand(elfFilePath string, params string) ([]byte, error) { - var ( - cmdOut []byte - err error - ) - cmdName := "arm-none-eabi-objdump" - cmdArgs := []string{params, elfFilePath} - if cmdOut, err = exec.Command(cmdName, cmdArgs...).Output(); err != nil { - fmt.Fprintln(os.Stderr, "There was an error running objdump command: ", - err) - os.Exit(1) - } - - return cmdOut, err -} - -func loadSymbolsAndPaths(elfFilePath, pathToStrip string) (map[string]string, - error) { - symbolsPath := make(map[string]string) - - nmOut, err := runNmCommand(elfFilePath) - if err != nil { - return nil, err - } - - lines := strings.Split(string(nmOut), "\n") - - for _, line := range lines { - fields := strings.Fields(strings.Replace(line, "\t", " ", -1)) - if len(fields) < 4 { - continue - } - var path string - - if len(fields) < 5 { - path = "(other)" - } else { - path = strings.Split(fields[4], ":")[0] - } - if pathToStrip != "" { - if strings.Contains(path, pathToStrip) { - path = strings.Replace(path, pathToStrip, "", -1) - } else { - path = "(other)" - } - } - symbolsPath[fields[3]] = path - } - return symbolsPath, nil -} - -func MakeSymbol(name string, section string, size uint64) *Symbol { - symbol := &Symbol{ - name, - section, - size, - } - return symbol -} - -type MemoryRegion struct { - Name string - Offset uint64 - EndOff uint64 - TotalSize uint64 - SectionNames map[string]struct{} - NamesSizes map[string]uint64 -} - -func MakeMemoryRegion() *MemoryRegion { - section := &MemoryRegion{ - "", 0, 0, 0, - make(map[string]struct{}), - make(map[string]uint64), - } - return section -} - -func (m *MemoryRegion) PartOf(addr uint64) bool { - return addr >= m.Offset && addr < m.EndOff -} - -func loadSymbolsAndSections(elfFilePath string) (map[string]*Symbol, error) { - objdumpOut, err := runObjdumpCommand(elfFilePath, "-tw") - if err != nil { - return nil, err - } - - lines := strings.Split(string(objdumpOut), "\n") - symbols := make(map[string]*Symbol) - for _, line := range lines { - fields := strings.Fields(strings.Replace(line, "\t", " ", -1)) - - if len(fields) == 5 { - size, err := strconv.ParseUint(fields[3], 16, 64) - if err != nil { - continue - } - symbols[fields[4]] = MakeSymbol(fields[4], fields[2], size) - } else if len(fields) == 6 { - size, err := strconv.ParseUint(fields[4], 16, 64) - if err != nil { - continue - } - symbols[fields[5]] = MakeSymbol(fields[5], fields[3], size) - } - - } - - return symbols, nil -} - -func generateMemoryRegions(elfFilePath string) (*MemoryRegion, *MemoryRegion, - error) { - - mapFile := elfFilePath + ".map" - flashRegion, ramRegion, err := parseMapFileRegions(mapFile) - if err != nil { - return nil, nil, err - } - - objdumpOut, err := runObjdumpCommand(elfFilePath, "-hw") - if err != nil { - return nil, nil, err - } - - lines := strings.Split(string(objdumpOut), "\n") - for _, line := range lines { - fields := strings.Fields(line) - if len(fields) < 7 { - continue - } - size, err := strconv.ParseUint(fields[2], 16, 64) - if err != nil { - continue - } - address, err := strconv.ParseUint(fields[3], 16, 64) - if err != nil { - continue - } - - if flashRegion.PartOf(address) { - flashRegion.TotalSize += size - flashRegion.SectionNames[fields[1]] = struct{}{} - flashRegion.NamesSizes[fields[1]] = size - continue - } - - if ramRegion.PartOf(address) { - ramRegion.TotalSize += size - ramRegion.SectionNames[fields[1]] = struct{}{} - ramRegion.NamesSizes[fields[1]] = size - continue - } - } - - return flashRegion, ramRegion, nil -} - -/* - * Go through GCC generated mapfile, and collect info about symbol sizes - */ -func parseMapFileRegions(fileName string) (*MemoryRegion, *MemoryRegion, - error) { - var state int = 0 - - file, err := os.Open(fileName) - if err != nil { - return nil, nil, err - } - - flashRegion := MakeMemoryRegion() - ramRegion := MakeMemoryRegion() - - scanner := bufio.NewScanner(file) - for scanner.Scan() { - switch state { - case 0: - if strings.Contains(scanner.Text(), "Memory Configuration") { - state = 1 - } - case 1: - if strings.Contains(scanner.Text(), "Origin") { - state = 2 - } - case 2: - if strings.Contains(scanner.Text(), "*default*") { - state = 3 - continue - } - array := strings.Fields(scanner.Text()) - offset, err := strconv.ParseUint(array[1], 0, 64) - if err != nil { - continue - } - size, err := strconv.ParseUint(array[2], 0, 64) - if err != nil { - continue - } - if strings.EqualFold(array[0], "flash") { - flashRegion.Name = array[0] - flashRegion.Offset = offset - flashRegion.EndOff = offset + size - } else if strings.EqualFold(array[0], "ram") { - ramRegion.Name = array[0] - ramRegion.Offset = offset - ramRegion.EndOff = offset + size - } - case 3: - fallthrough - default: - return flashRegion, ramRegion, nil - } - - } - return flashRegion, flashRegion, nil -} - -func logMemoryRegionStats(flashRegion, ramRegion *MemoryRegion) { - util.StatusMessage(util.VERBOSITY_VERBOSE, "%-10s 0x%08x-0x%08x\n", - "Mem FLASH:", flashRegion.Offset, flashRegion.EndOff) - util.StatusMessage(util.VERBOSITY_VERBOSE, "%-10s 0x%08x-0x%08x\n", - "Mem RAM:", ramRegion.Offset, ramRegion.EndOff) - util.StatusMessage(util.VERBOSITY_VERBOSE, "\n") - util.StatusMessage(util.VERBOSITY_VERBOSE, "Mem: FLASH\n") - util.StatusMessage(util.VERBOSITY_VERBOSE, "%-20s %10s\n", "Name", "Size") - for sectionName, size := range flashRegion.NamesSizes { - util.StatusMessage(util.VERBOSITY_VERBOSE, "%-20s %10d\n", - sectionName, size) - } - util.StatusMessage(util.VERBOSITY_VERBOSE, "%-20s %10d\n", "Total", - flashRegion.TotalSize) - util.StatusMessage(util.VERBOSITY_VERBOSE, "\n") - util.StatusMessage(util.VERBOSITY_VERBOSE, "Mem: RAM\n") - util.StatusMessage(util.VERBOSITY_VERBOSE, "%-20s %10s\n", "Name", "Size") - for sectionName, size := range ramRegion.NamesSizes { - util.StatusMessage(util.VERBOSITY_VERBOSE, "%-20s %10d\n", - sectionName, size) - } - util.StatusMessage(util.VERBOSITY_VERBOSE, "%-20s %10d\n", "Total", - ramRegion.TotalSize) - util.StatusMessage(util.VERBOSITY_VERBOSE, "\n") -} - -func SizeReport(elfFilePath, srcBase string, ram bool, flash bool) error { - symbolsPath, err := loadSymbolsAndPaths(elfFilePath, srcBase) - if err != nil { - return err - } - loadedSectionSizes, err := loadSymbolsAndSections(elfFilePath) - if err != nil { - return err - } - flashRegion, ramRegion, err := generateMemoryRegions(elfFilePath) - if err != nil { - return err - } - - logMemoryRegionStats(flashRegion, ramRegion) - - startPath := "." - - if flash { - flashNodes := newFolder(startPath) - for _, symbol := range loadedSectionSizes { - if _, ok := flashRegion.SectionNames[symbol.Section]; ok { - flashNodes.addSymbol(symbol, symbolsPath[symbol.Name]) - } - } - fmt.Println("FLASH report:") - fmt.Printf("%v", flashNodes.ToString(flashRegion.TotalSize)) - } - - if ram { - ramNodes := newFolder(startPath) - for _, symbol := range loadedSectionSizes { - if _, ok := ramRegion.SectionNames[symbol.Section]; ok { - ramNodes.addSymbol(symbol, symbolsPath[symbol.Name]) - } - } - fmt.Println("RAM report:") - fmt.Printf("%v", ramNodes.ToString(ramRegion.TotalSize)) - } - return nil -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/builder/symbol_tree.go ---------------------------------------------------------------------- diff --git a/newt/builder/symbol_tree.go b/newt/builder/symbol_tree.go deleted file mode 100644 index 2318da1..0000000 --- a/newt/builder/symbol_tree.go +++ /dev/null @@ -1,195 +0,0 @@ -/** - * 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 builder - -import ( - "fmt" - "sort" - "strings" -) - -type Symbol struct { - Name string - Section string - Size uint64 -} - -type File struct { - Name string - Symbols map[string]*Symbol -} - -type Folder struct { - Name string - Files map[string]*File - Folders map[string]*Folder -} - -func newFolder(name string) *Folder { - return &Folder{name, make(map[string]*File), make(map[string]*Folder)} -} - -func newFile(name string) *File { - return &File{name, make(map[string]*Symbol)} -} - -func (f *File) sumSize() uint64 { - var sum uint64 - for _, symbol := range f.Symbols { - sum += symbol.Size - } - return sum -} - -func (f *Folder) sumSize() uint64 { - var sum uint64 - for _, folder := range f.Folders { - sum += folder.sumSize() - } - - for _, file := range f.Files { - sum += file.sumSize() - } - return sum -} - -func (f *Folder) getFolder(name string) *Folder { - if nextF, ok := f.Folders[name]; ok { - return nextF - } else { - f.Folders[name] = newFolder(name) - return f.Folders[name] - } - return &Folder{} // cannot happen -} - -func (f *Folder) getFile(name string) *File { - if nextF, ok := f.Files[name]; ok { - return nextF - } else { - f.Files[name] = newFile(name) - return f.Files[name] - } - return &File{} // cannot happen -} - -func (f *File) getSymbol(name string) *Symbol { - if nextF, ok := f.Symbols[name]; ok { - return nextF - } else { - f.Symbols[name] = &Symbol{name, "", 0} - return f.Symbols[name] - } - return &Symbol{} // cannot happen -} - -func (f *Folder) addFolder(path []string) *Folder { - if len(path) == 1 { - // last segment == new folder - return f.getFolder(path[0]) - } else { - return f.getFolder(path[0]).addFolder(path[1:]) - } -} - -func (f *Folder) addFile(path []string) *File { - if len(path) == 1 { - // last segment == file - return f.getFile(path[0]) - } else { - return f.getFolder(path[0]).addFile(path[1:]) - } -} - -func (f *Folder) addSymbol(symbol *Symbol, path string) *Symbol { - segments := strings.Split(path, "/") - file := f.addFile(segments) - sym := file.getSymbol(symbol.Name) - sym.Section = symbol.Section - sym.Size += symbol.Size - return sym -} - -var outputFormatting string = "%-59s %9d %8.2f%%\n" - -func (f *File) String(indent string, level int, total uint64) string { - var str string - if f.sumSize() <= 0 { - return "" - } - size := f.sumSize() - percent := 100 * float64(size) / float64(total) - str += fmt.Sprintf(outputFormatting, strings.Repeat(indent, level)+ - f.Name, size, percent) - - var sorted []string - for symName := range f.Symbols { - sorted = append(sorted, symName) - } - sort.Strings(sorted) - for _, sym := range sorted { - size := f.Symbols[sym].Size - percent := 100 * float64(size) / float64(total) - if f.Symbols[sym].Size > 0 { - str += fmt.Sprintf(outputFormatting, - strings.Repeat(indent, level+1)+ f.Symbols[sym].Name, - size, percent) - } - } - return str -} - -func (f *Folder) StringRec(indent string, level int, total uint64) string { - var str string - - var sorted []string - for folderName := range f.Folders { - sorted = append(sorted, folderName) - } - for fileName := range f.Files { - sorted = append(sorted, fileName) - } - sort.Strings(sorted) - - for _, name := range sorted { - if folder, ok := f.Folders[name]; ok { - size := folder.sumSize() - percent := 100 * float64(size) / float64(total) - str += fmt.Sprintf(outputFormatting, - strings.Repeat(indent, level)+folder.Name, size, percent) - str += folder.StringRec(indent, level+1, total) - } else { - str += f.Files[name].String(indent, level, total) - } - } - return str -} - -func (f *Folder) ToString(total uint64) string { - indent := " " - var str string - str += fmt.Sprintf("%-59s %9s %9s\n", "Path", "Size", "%") - str += strings.Repeat("=", 79) + "\n" - str += f.StringRec(indent, 0, total) - str += strings.Repeat("=", 79) + "\n" - str += fmt.Sprintf("%-59s %9d %9s\n", - "Total symbol size (i.e. excluding padding, etc.)", f.sumSize(), "") - return str -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/builder/targetbuild.go ---------------------------------------------------------------------- diff --git a/newt/builder/targetbuild.go b/newt/builder/targetbuild.go deleted file mode 100644 index 9c5dc1e..0000000 --- a/newt/builder/targetbuild.go +++ /dev/null @@ -1,818 +0,0 @@ -/** - * 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 builder - -import ( - "encoding/json" - "fmt" - "io/ioutil" - "os" - "path/filepath" - "sort" - "strings" - "time" - - log "github.com/Sirupsen/logrus" - - "mynewt.apache.org/newt/newt/flash" - "mynewt.apache.org/newt/newt/image" - "mynewt.apache.org/newt/newt/interfaces" - "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/symbol" - "mynewt.apache.org/newt/newt/syscfg" - "mynewt.apache.org/newt/newt/sysinit" - "mynewt.apache.org/newt/newt/target" - "mynewt.apache.org/newt/newt/toolchain" - "mynewt.apache.org/newt/util" -) - -type TargetBuilder struct { - 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 - - 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(), - testPkg: testPkg, - injectedSettings: map[string]string{}, - } - - return t, nil -} - -func NewTargetBuilder(target *target.Target) (*TargetBuilder, error) { - return NewTargetTester(target, nil) -} - -func (t *TargetBuilder) NewCompiler(dstDir string) ( - *toolchain.Compiler, error) { - - c, err := toolchain.NewCompiler( - t.compilerPkg.BasePath(), - dstDir, - t.target.BuildProfile) - - return c, err -} - -func (t *TargetBuilder) ensureResolved() error { - if t.res != nil { - return nil - } - - var loaderSeeds []*pkg.LocalPackage - if t.loaderPkg != nil { - loaderSeeds = []*pkg.LocalPackage{ - t.loaderPkg, - t.bspPkg.LocalPackage, - t.compilerPkg, - t.target.Package(), - } - - // For split images, inject the SPLIT_[...] settings into the - // corresponding app packages. This ensures that: - // * The app packages know they are part of a split image during - // dependency resolution. - // * The app source files receive "-DSPLIT_[...]=1" command line - // arguments during compilation. - t.loaderPkg.InjectedSettings()["SPLIT_LOADER"] = "1" - if t.appPkg != nil { - t.appPkg.InjectedSettings()["SPLIT_APPLICATION"] = "1" - } - - // Inject the SPLIT_IMAGE setting into the entire target. All packages - // now know that they are part of a split image build. - t.injectedSettings["SPLIT_IMAGE"] = "1" - } - - appSeeds := []*pkg.LocalPackage{ - t.bspPkg.LocalPackage, - t.compilerPkg, - t.target.Package(), - } - - if t.appPkg != nil { - appSeeds = append(appSeeds, t.appPkg) - } - - if t.testPkg != nil { - // A few features are automatically supported when the test command is - // used: - // * TEST: lets packages know that this is a test app - // * SELFTEST: indicates that the "newt test" command is used; - // causes a package to define a main() function. - t.injectedSettings["TEST"] = "1" - t.injectedSettings["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 - } - - 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 != "" { - for _, line := range strings.Split(warningText, "\n") { - log.Debugf(line) - } - } - - if err := syscfg.EnsureWritten(t.res.Cfg, - GeneratedIncludeDir(t.target.Name())); err != nil { - - return err - } - - return nil -} - -func (t *TargetBuilder) generateSysinit() error { - if err := t.ensureResolved(); err != nil { - return err - } - - srcDir := GeneratedSrcDir(t.target.Name()) - - if t.res.LoaderSet != nil { - lpkgs := resolve.RpkgSliceToLpkgSlice(t.res.LoaderSet.Rpkgs) - sysinit.EnsureWritten(lpkgs, srcDir, - pkg.ShortName(t.target.Package()), true) - } - - lpkgs := resolve.RpkgSliceToLpkgSlice(t.res.AppSet.Rpkgs) - sysinit.EnsureWritten(lpkgs, srcDir, - pkg.ShortName(t.target.Package()), false) - - return nil -} - -func (t *TargetBuilder) generateFlashMap() error { - return t.bspPkg.FlashMap.EnsureWritten( - GeneratedSrcDir(t.target.Name()), - GeneratedIncludeDir(t.target.Name()), - pkg.ShortName(t.target.Package())) -} - -func (t *TargetBuilder) generateCode() error { - if err := t.generateSysinit(); err != nil { - return err - } - - if err := t.generateFlashMap(); err != nil { - return err - } - - return nil -} - -func (t *TargetBuilder) PrepBuild() error { - if err := t.ensureResolved(); err != nil { - return err - } - - flashErrText := t.bspPkg.FlashMap.ErrorText() - if flashErrText != "" { - return util.NewNewtError(flashErrText) - } - - if err := t.validateAndWriteCfg(); err != nil { - return err - } - - var err error - if t.res.LoaderSet != nil { - t.LoaderBuilder, err = NewBuilder(t, BUILD_NAME_LOADER, - t.res.LoaderSet.Rpkgs, t.res.ApiMap, t.res.Cfg) - if err != nil { - return err - } - if err := t.LoaderBuilder.PrepBuild(); err != nil { - return err - } - - loaderFlags := toolchain.NewCompilerInfo() - loaderFlags.Cflags = append(loaderFlags.Cflags, "-DSPLIT_LOADER") - t.LoaderBuilder.AddCompilerInfo(loaderFlags) - - t.LoaderList = project.ResetDeps(nil) - } - - t.AppBuilder, err = NewBuilder(t, BUILD_NAME_APP, t.res.AppSet.Rpkgs, - t.res.ApiMap, t.res.Cfg) - if err != nil { - return err - } - if err := t.AppBuilder.PrepBuild(); err != nil { - return err - } - - if t.res.LoaderSet != nil { - appFlags := toolchain.NewCompilerInfo() - appFlags.Cflags = append(appFlags.Cflags, "-DSPLIT_APPLICATION") - t.AppBuilder.AddCompilerInfo(appFlags) - } - - t.AppList = project.ResetDeps(nil) - - logDepInfo(t.res) - - if err := t.generateCode(); err != nil { - return err - } - - return nil -} - -func (t *TargetBuilder) buildLoader() error { - /* Tentatively link the app (using the normal single image linker script) */ - if err := t.AppBuilder.TentativeLink(t.bspPkg.LinkerScripts); err != nil { - return err - } - - /* rebuild the loader */ - project.ResetDeps(t.LoaderList) - - if err := t.bspPkg.Reload(t.LoaderBuilder.cfg.Features()); err != nil { - return err - } - - if err := t.LoaderBuilder.Build(); err != nil { - return err - } - - /* Tentatively link the loader */ - if err := t.LoaderBuilder.TentativeLink(t.bspPkg.LinkerScripts); err != nil { - return err - } - - /* re-link the loader with app dependencies */ - err, commonPkgs, commonSyms := t.RelinkLoader() - if err != nil { - return err - } - - /* The app can ignore these packages next time */ - delete(commonPkgs, t.bspPkg.Name()) - t.AppBuilder.RemovePackages(commonPkgs) - - /* create the special elf to link the app against */ - /* its just the elf with a set of symbols removed and renamed */ - err = t.LoaderBuilder.buildRomElf(commonSyms) - if err != nil { - return err - } - - /* set up the linker elf and linker script for the app */ - t.AppBuilder.linkElf = t.LoaderBuilder.AppLinkerElfPath() - - return nil - -} - -func (t *TargetBuilder) Build() error { - if err := t.PrepBuild(); err != nil { - return err - } - - /* Build the Apps */ - project.ResetDeps(t.AppList) - - if err := t.bspPkg.Reload(t.AppBuilder.cfg.Features()); err != nil { - return err - } - - if err := t.AppBuilder.Build(); err != nil { - return err - } - - var linkerScripts []string - if t.LoaderBuilder == nil { - linkerScripts = t.bspPkg.LinkerScripts - } else { - if err := t.buildLoader(); err != nil { - return err - } - linkerScripts = t.bspPkg.Part2LinkerScripts - } - - /* Link the app. */ - if err := t.AppBuilder.Link(linkerScripts); err != nil { - return err - } - - /* Create manifest. */ - if err := t.createManifest(); err != nil { - return err - } - - return nil -} - -/* - * This function re-links the loader adding symbols from libraries - * shared with the app. Returns a list of the common packages shared - * by the app and loader - */ -func (t *TargetBuilder) RelinkLoader() (error, map[string]bool, - *symbol.SymbolMap) { - - /* fetch symbols from the elf and from the libraries themselves */ - log.Debugf("Loader packages:") - for _, rpkg := range t.LoaderBuilder.sortedRpkgs() { - log.Debugf(" * %s", rpkg.Lpkg.Name()) - } - log.Debugf("App packages:") - for _, rpkg := range t.AppBuilder.sortedRpkgs() { - log.Debugf(" * %s", rpkg.Lpkg.Name()) - } - err, appLibSym := t.AppBuilder.ExtractSymbolInfo() - if err != nil { - return err, nil, nil - } - - /* fetch the symbol list from the app temporary elf */ - err, appElfSym := t.AppBuilder.ParseObjectElf(t.AppBuilder.AppTentativeElfPath()) - if err != nil { - return err, nil, nil - } - - /* extract the library symbols and elf symbols from the loader */ - err, loaderLibSym := t.LoaderBuilder.ExtractSymbolInfo() - if err != nil { - return err, nil, nil - } - - err, loaderElfSym := t.LoaderBuilder.ParseObjectElf( - t.LoaderBuilder.AppTentativeElfPath()) - if err != nil { - return err, nil, nil - } - - /* create the set of matching and non-matching symbols */ - err, smMatch, smNomatch := symbol.IdenticalUnion(appLibSym, - loaderLibSym, true, false) - - /* which packages are shared between the two */ - commonPkgs := smMatch.Packages() - uncommonPkgs := smNomatch.Packages() - - /* ensure that the loader and app packages are never shared */ - 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.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, - "Putting %d symbols from %d packages into loader\n", - len(*smMatch), len(commonPkgs)) - - var badpkgs []string - var symbolStr string - for v, _ := range uncommonPkgs { - if t.AppBuilder.appPkg != nil && - t.AppBuilder.appPkg.rpkg.Lpkg.Name() != v && - t.LoaderBuilder.appPkg != nil && - t.LoaderBuilder.appPkg.rpkg.Lpkg.Name() != v { - - trouble := smNomatch.FilterPkg(v) - - var found bool - for _, sym := range *trouble { - if !sym.IsLocal() { - found = true - } - } - - if found { - symbolStr = (*trouble).String("Non Matching Symbols") - badpkgs = append(badpkgs, v) - delete(commonPkgs, v) - } - } - } - - if len(badpkgs) > 0 { - errStr := fmt.Sprintf( - "Common packages with different implementation\n %s\n", - strings.Join(badpkgs, "\n ")) - errStr += symbolStr - return util.NewNewtError(errStr), nil, nil - } - - /* for each symbol in the elf of the app, if that symbol is in - * a common package, keep that symbol in the loader */ - preserveElf := symbol.NewSymbolMap() - - /* go through each symbol in the app */ - for _, elfsym := range *appElfSym { - name := elfsym.Name - if libsym, ok := (*appLibSym)[name]; ok { - if _, ok := commonPkgs[libsym.Bpkg]; ok { - /* if its not in the loader elf, add it as undefined */ - if _, ok := (*loaderElfSym)[name]; !ok { - preserveElf.Add(elfsym) - } - } - } - } - - /* re-link loader */ - project.ResetDeps(t.LoaderList) - - util.StatusMessage(util.VERBOSITY_VERBOSE, - "Migrating %d unused symbols into Loader\n", len(*preserveElf)) - - err = t.LoaderBuilder.KeepLink(t.bspPkg.LinkerScripts, preserveElf) - - if err != nil { - return err, nil, nil - } - return err, commonPkgs, smMatch -} - -func (t *TargetBuilder) GetTarget() *target.Target { - return t.target -} - -func (t *TargetBuilder) GetTestPkg() *pkg.LocalPackage { - return t.testPkg -} - -func (t *TargetBuilder) InjectSetting(key string, value string) { - t.injectedSettings[key] = value -} - -func readManifest(path string) (*image.ImageManifest, error) { - content, err := ioutil.ReadFile(path) - if err != nil { - return nil, util.ChildNewtError(err) - } - - manifest := &image.ImageManifest{} - if err := json.Unmarshal(content, &manifest); err != nil { - return nil, util.FmtNewtError( - "Failure decoding manifest with path \"%s\": %s", err.Error()) - } - - return manifest, nil -} - -func (t *TargetBuilder) createManifest() error { - manifest := &image.ImageManifest{ - Date: time.Now().Format(time.RFC3339), - Name: t.GetTarget().FullName(), - } - - rm := image.NewRepoManager() - for _, rpkg := range t.AppBuilder.sortedRpkgs() { - manifest.Pkgs = append(manifest.Pkgs, - rm.GetImageManifestPkg(rpkg.Lpkg)) - } - - if t.LoaderBuilder != nil { - for _, rpkg := range t.LoaderBuilder.sortedRpkgs() { - manifest.LoaderPkgs = append(manifest.LoaderPkgs, - rm.GetImageManifestPkg(rpkg.Lpkg)) - } - } - - manifest.Repos = rm.AllRepos() - - vars := t.GetTarget().Vars - keys := make([]string, 0, len(vars)) - for k := range vars { - keys = append(keys, k) - } - sort.Strings(keys) - for _, k := range keys { - manifest.TgtVars = append(manifest.TgtVars, k+"="+vars[k]) - } - syscfgKV := t.GetTarget().Package().SyscfgV.GetStringMapString("syscfg.vals") - if len(syscfgKV) > 0 { - tgtSyscfg := fmt.Sprintf("target.syscfg=%s", - syscfg.KeyValueToStr(syscfgKV)) - manifest.TgtVars = append(manifest.TgtVars, tgtSyscfg) - } - - c, err := t.AppBuilder.PkgSizes() - if err == nil { - manifest.PkgSizes = c.Pkgs - } - if t.LoaderBuilder != nil { - c, err = t.LoaderBuilder.PkgSizes() - if err == nil { - manifest.LoaderPkgSizes = c.Pkgs - } - } - file, err := os.Create(t.AppBuilder.ManifestPath()) - if err != nil { - return util.FmtNewtError("Cannot create manifest file %s: %s", - t.AppBuilder.ManifestPath(), err.Error()) - } - defer file.Close() - - buffer, err := json.MarshalIndent(manifest, "", " ") - if err != nil { - return util.FmtNewtError("Cannot encode manifest: %s", err.Error()) - } - _, err = file.Write(buffer) - if err != nil { - return util.FmtNewtError("Cannot write manifest file: %s", - err.Error()) - } - - return nil -} - -// Reads an existing manifest file and augments it with image fields: -// * Image version -// * App image path -// * App image hash -// * Loader image path -// * Loader image hash -// * Build ID -func (t *TargetBuilder) augmentManifest( - appImg *image.Image, - loaderImg *image.Image, - buildId []byte) error { - - manifest, err := readManifest(t.AppBuilder.ManifestPath()) - if err != nil { - return err - } - - manifest.Version = appImg.Version.String() - manifest.ImageHash = fmt.Sprintf("%x", appImg.Hash) - manifest.Image = filepath.Base(appImg.TargetImg) - - if loaderImg != nil { - manifest.Loader = filepath.Base(loaderImg.TargetImg) - manifest.LoaderHash = fmt.Sprintf("%x", loaderImg.Hash) - } - - manifest.BuildID = fmt.Sprintf("%x", buildId) - - file, err := os.Create(t.AppBuilder.ManifestPath()) - if err != nil { - return util.FmtNewtError("Cannot create manifest file %s: %s", - t.AppBuilder.ManifestPath(), err.Error()) - } - defer file.Close() - - buffer, err := json.MarshalIndent(manifest, "", " ") - if err != nil { - return util.FmtNewtError("Cannot encode manifest: %s", err.Error()) - } - _, err = file.Write(buffer) - if err != nil { - return util.FmtNewtError("Cannot write manifest file: %s", - err.Error()) - } - - return nil -} - -// Calculates the size of a single boot trailer. This is the amount of flash -// that must be reserved at the end of each image slot. -func (t *TargetBuilder) bootTrailerSize() int { - var minWriteSz int - - entry, ok := t.res.Cfg.Settings["MCU_FLASH_MIN_WRITE_SIZE"] - if !ok { - util.StatusMessage(util.VERBOSITY_DEFAULT, - "* Warning: target does not define MCU_FLASH_MIN_WRITE_SIZE "+ - "setting; assuming a value of 1.\n") - minWriteSz = 1 - } else { - val, err := util.AtoiNoOct(entry.Value) - if err != nil { - util.StatusMessage(util.VERBOSITY_DEFAULT, - "* Warning: target specifies invalid non-integer "+ - "MCU_FLASH_MIN_WRITE_SIZE setting; assuming a "+ - "value of 1.\n") - minWriteSz = 1 - } else { - minWriteSz = val - } - } - - /* Mynewt boot trailer format: - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * ~ MAGIC (16 octets) ~ - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * ~ ~ - * ~ Swap status (128 * min-write-size * 3) ~ - * ~ ~ - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Copy done | 0xff padding (up to min-write-sz - 1) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | Image OK | 0xff padding (up to min-write-sz - 1) | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - - tsize := 16 + // Magic. - 128*minWriteSz*3 + // Swap status. - minWriteSz + // Copy done. - minWriteSz // Image Ok. - - log.Debugf("Min-write-size=%d; boot-trailer-size=%d", minWriteSz, tsize) - - return tsize -} - -// Calculates the size of the largest image that can be written to each image -// slot. -func (t *TargetBuilder) maxImgSizes() []int { - sz0 := t.bspPkg.FlashMap.Areas[flash.FLASH_AREA_NAME_IMAGE_0].Size - sz1 := t.bspPkg.FlashMap.Areas[flash.FLASH_AREA_NAME_IMAGE_1].Size - trailerSz := t.bootTrailerSize() - - return []int{ - sz0 - trailerSz, - sz1 - trailerSz, - } -} - -// Verifies that each already-built image leaves enough room for a boot trailer -// a the end of its slot. -func (t *TargetBuilder) verifyImgSizes(li *image.Image, ai *image.Image) error { - maxSizes := t.maxImgSizes() - - errLines := []string{} - if li != nil { - if overflow := int(li.TotalSize) - maxSizes[0]; overflow > 0 { - errLines = append(errLines, - fmt.Sprintf("loader overflows slot-0 by %d bytes "+ - "(image=%d max=%d)", - overflow, li.TotalSize, maxSizes[0])) - } - if overflow := int(ai.TotalSize) - maxSizes[1]; overflow > 0 { - errLines = append(errLines, - fmt.Sprintf("app overflows slot-1 by %d bytes "+ - "(image=%d max=%d)", - overflow, ai.TotalSize, maxSizes[1])) - - } - } else { - if overflow := int(ai.TotalSize) - maxSizes[0]; overflow > 0 { - errLines = append(errLines, - fmt.Sprintf("app overflows slot-0 by %d bytes "+ - "(image=%d max=%d)", - overflow, ai.TotalSize, maxSizes[0])) - } - } - - if len(errLines) > 0 { - if !newtutil.NewtForce { - return util.NewNewtError(strings.Join(errLines, "; ")) - } else { - for _, e := range errLines { - util.StatusMessage(util.VERBOSITY_QUIET, - "* Warning: %s (ignoring due to force flag)\n", e) - } - } - } - - return nil -} - -// @return app-image, loader-image, error -func (t *TargetBuilder) CreateImages(version string, - keystr string, keyId uint8) (*image.Image, *image.Image, error) { - - if err := t.Build(); err != nil { - return nil, nil, err - } - - var err error - var appImg *image.Image - var loaderImg *image.Image - - if t.LoaderBuilder != nil { - loaderImg, err = t.LoaderBuilder.CreateImage(version, keystr, keyId, - nil) - if err != nil { - return nil, nil, err - } - } - - appImg, err = t.AppBuilder.CreateImage(version, keystr, keyId, loaderImg) - if err != nil { - return nil, nil, err - } - - buildId := image.CreateBuildId(appImg, loaderImg) - if err := t.augmentManifest(appImg, loaderImg, buildId); err != nil { - return nil, nil, err - } - - if err := t.verifyImgSizes(loaderImg, appImg); err != nil { - return nil, nil, err - } - - return appImg, loaderImg, nil -} - -func (t *TargetBuilder) CreateDepGraph() (DepGraph, error) { - if err := t.ensureResolved(); err != nil { - return nil, err - } - - return depGraph(t.res.MasterSet) -} - -func (t *TargetBuilder) CreateRevdepGraph() (DepGraph, error) { - if err := t.ensureResolved(); err != nil { - return nil, err - } - - return revdepGraph(t.res.MasterSet) -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/cli/build_cmds.go ---------------------------------------------------------------------- diff --git a/newt/cli/build_cmds.go b/newt/cli/build_cmds.go deleted file mode 100644 index 5fb7944..0000000 --- a/newt/cli/build_cmds.go +++ /dev/null @@ -1,478 +0,0 @@ -/** - * 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 cli - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/spf13/cobra" - "mynewt.apache.org/newt/newt/builder" - "mynewt.apache.org/newt/newt/pkg" - "mynewt.apache.org/newt/newt/project" - "mynewt.apache.org/newt/newt/target" - "mynewt.apache.org/newt/util" -) - -const TARGET_TEST_NAME = "unittest" - -var testablePkgMap map[*pkg.LocalPackage]struct{} - -func testablePkgs() map[*pkg.LocalPackage]struct{} { - if testablePkgMap != nil { - return testablePkgMap - } - - testablePkgMap := map[*pkg.LocalPackage]struct{}{} - - // Create a map of path => lclPkg. - proj, err := project.TryGetProject() - if err != nil { - return nil - } - - allPkgs := proj.PackagesOfType(-1) - pathLpkgMap := make(map[string]*pkg.LocalPackage, len(allPkgs)) - for _, p := range allPkgs { - lpkg := p.(*pkg.LocalPackage) - pathLpkgMap[lpkg.BasePath()] = lpkg - } - - // Add all unit test packages to the testable package map. - testPkgs := proj.PackagesOfType(pkg.PACKAGE_TYPE_UNITTEST) - for _, p := range testPkgs { - lclPack := p.(*pkg.LocalPackage) - testablePkgMap[lclPack] = struct{}{} - } - - // Next add first ancestor of each test package. - for _, testPkgItf := range testPkgs { - testPkg := testPkgItf.(*pkg.LocalPackage) - for cur := filepath.Dir(testPkg.BasePath()); cur != proj.BasePath; cur = filepath.Dir(cur) { - lpkg := pathLpkgMap[cur] - if lpkg != nil && lpkg.Type() != pkg.PACKAGE_TYPE_UNITTEST { - testablePkgMap[lpkg] = struct{}{} - break - } - } - } - - return testablePkgMap -} - -func pkgToUnitTests(pack *pkg.LocalPackage) []*pkg.LocalPackage { - // If the user specified a unittest package, just test that one. - if pack.Type() == pkg.PACKAGE_TYPE_UNITTEST { - return []*pkg.LocalPackage{pack} - } - - // Otherwise, return all the package's direct descendants that are unit - // test packages. - result := []*pkg.LocalPackage{} - srcPath := pack.BasePath() - for p, _ := range testablePkgs() { - if p.Type() == pkg.PACKAGE_TYPE_UNITTEST && - filepath.Dir(p.BasePath()) == srcPath { - - result = append(result, p) - } - } - - return result -} - -var extraJtagCmd string -var noGDB_flag bool - -func buildRunCmd(cmd *cobra.Command, args []string) { - if len(args) < 1 { - NewtUsage(cmd, nil) - } - - TryGetProject() - - // Verify and resolve each specified package. - targets, all, err := ResolveTargetsOrAll(args...) - if err != nil { - NewtUsage(cmd, err) - } - - if all { - // Collect all targets that specify an app package. - targets = []*target.Target{} - for _, name := range targetList() { - t := ResolveTarget(name) - if t != nil && t.AppName != "" { - targets = append(targets, t) - } - } - } - - for i, _ := range targets { - // Reset the global state for the next build. - // XXX: It is not good that this is necessary. This is certainly going - // to bite us... - if i > 0 { - if err := ResetGlobalState(); err != nil { - NewtUsage(nil, err) - } - } - - // Look up the target by name. This has to be done a second time here - // now that the project has been reset. - t := ResolveTarget(targets[i].Name()) - if t == nil { - NewtUsage(nil, util.NewNewtError("Failed to resolve target: "+ - targets[i].Name())) - } - - util.StatusMessage(util.VERBOSITY_DEFAULT, "Building target %s\n", - t.FullName()) - - b, err := builder.NewTargetBuilder(t) - if err != nil { - NewtUsage(nil, err) - } - - if err := b.Build(); err != nil { - NewtUsage(nil, err) - } - - util.StatusMessage(util.VERBOSITY_DEFAULT, - "Target successfully built: %s\n", t.Name()) - } -} - -func cleanDir(path string) { - util.StatusMessage(util.VERBOSITY_VERBOSE, - "Cleaning directory %s\n", path) - - err := os.RemoveAll(path) - if err != nil { - NewtUsage(nil, util.NewNewtError(err.Error())) - } -} - -func cleanRunCmd(cmd *cobra.Command, args []string) { - if len(args) < 1 { - NewtUsage(cmd, util.NewNewtError("Must specify target")) - } - - TryGetProject() - - cleanAll := false - targets := []*target.Target{} - for _, arg := range args { - if arg == TARGET_KEYWORD_ALL { - cleanAll = true - } else { - t, _, err := ResolveTargetOrUnittest(arg) - if err != nil { - NewtUsage(cmd, err) - } - targets = append(targets, t) - } - } - - if cleanAll { - cleanDir(builder.BinRoot()) - } else { - for _, t := range targets { - cleanDir(builder.TargetBinDir(t.Name())) - } - } -} - -func pkgnames(pkgs []*pkg.LocalPackage) string { - s := "" - - for _, p := range pkgs { - s += p.Name() + " " - } - - return s -} - -func testRunCmd(cmd *cobra.Command, args []string, exclude string) { - if len(args) < 1 { - NewtUsage(cmd, nil) - } - - proj := TryGetProject() - - // Verify and resolve each specified package. - testAll := false - packs := []*pkg.LocalPackage{} - for _, pkgName := range args { - if pkgName == "all" { - testAll = true - } else { - pack, err := proj.ResolvePackage(proj.LocalRepo(), pkgName) - if err != nil { - NewtUsage(cmd, err) - } - - testPkgs := pkgToUnitTests(pack) - if len(testPkgs) == 0 { - NewtUsage(nil, util.FmtNewtError("Package %s contains no "+ - "unit tests", pack.FullName())) - } - - packs = append(packs, testPkgs...) - } - } - - if testAll { - packItfs := proj.PackagesOfType(pkg.PACKAGE_TYPE_UNITTEST) - packs = make([]*pkg.LocalPackage, len(packItfs)) - for i, p := range packItfs { - packs[i] = p.(*pkg.LocalPackage) - } - - packs = pkg.SortLclPkgs(packs) - } - - if len(exclude) > 0 { - // filter out excluded tests - orig := packs - packs = packs[:0] - excls := strings.Split(exclude, ",") - packLoop: - for _, pack := range orig { - for _, excl := range excls { - if pack.Name() == excl || strings.HasPrefix(pack.Name(), excl+"/") { - continue packLoop - } - } - packs = append(packs, pack) - } - } - - if len(packs) == 0 { - NewtUsage(nil, util.NewNewtError("No testable packages found")) - } - - passedPkgs := []*pkg.LocalPackage{} - failedPkgs := []*pkg.LocalPackage{} - for _, pack := range packs { - // Reset the global state for the next test. - if err := ResetGlobalState(); err != nil { - NewtUsage(nil, err) - } - - t, err := ResolveUnittest(pack.Name()) - if err != nil { - NewtUsage(nil, err) - } - - b, err := builder.NewTargetTester(t, pack) - if err != nil { - NewtUsage(nil, err) - } - - util.StatusMessage(util.VERBOSITY_DEFAULT, "Testing package %s\n", - pack.FullName()) - - err = b.SelfTestExecute() - if err == nil { - passedPkgs = append(passedPkgs, pack) - } else { - newtError := err.(*util.NewtError) - util.StatusMessage(util.VERBOSITY_QUIET, newtError.Text) - failedPkgs = append(failedPkgs, pack) - } - } - - passStr := fmt.Sprintf("Passed tests: [%s]", PackageNameList(passedPkgs)) - failStr := fmt.Sprintf("Failed tests: [%s]", PackageNameList(failedPkgs)) - - if len(failedPkgs) > 0 { - NewtUsage(nil, util.FmtNewtError("Test failure(s):\n%s\n%s", passStr, - failStr)) - } else { - util.StatusMessage(util.VERBOSITY_DEFAULT, "%s\n", passStr) - util.StatusMessage(util.VERBOSITY_DEFAULT, "All tests passed\n") - } -} - -func loadRunCmd(cmd *cobra.Command, args []string) { - if len(args) < 1 { - NewtUsage(cmd, util.NewNewtError("Must specify target")) - } - - TryGetProject() - - t := ResolveTarget(args[0]) - if t == nil { - NewtUsage(cmd, util.NewNewtError("Invalid target name: "+args[0])) - } - - b, err := builder.NewTargetBuilder(t) - if err != nil { - NewtUsage(nil, err) - } - - if err := b.Load(extraJtagCmd); err != nil { - NewtUsage(cmd, err) - } -} - -func debugRunCmd(cmd *cobra.Command, args []string) { - if len(args) < 1 { - NewtUsage(cmd, util.NewNewtError("Must specify target")) - } - - TryGetProject() - - t := ResolveTarget(args[0]) - if t == nil { - NewtUsage(cmd, util.NewNewtError("Invalid target name: "+args[0])) - } - - b, err := builder.NewTargetBuilder(t) - if err != nil { - NewtUsage(nil, err) - } - - if err := b.Debug(extraJtagCmd, false, noGDB_flag); err != nil { - NewtUsage(cmd, err) - } -} - -func sizeRunCmd(cmd *cobra.Command, args []string, ram bool, flash bool) { - if len(args) < 1 { - NewtUsage(cmd, util.NewNewtError("Must specify target")) - } - - TryGetProject() - - t := ResolveTarget(args[0]) - if t == nil { - NewtUsage(cmd, util.NewNewtError("Invalid target name: "+args[0])) - } - - b, err := builder.NewTargetBuilder(t) - if err != nil { - NewtUsage(nil, err) - } - - if ram || flash { - if err := b.SizeReport(ram, flash); err != nil { - NewtUsage(cmd, err) - } - return - } - - if err := b.Size(); err != nil { - NewtUsage(cmd, err) - } -} - -func AddBuildCommands(cmd *cobra.Command) { - buildCmd := &cobra.Command{ - Use: "build <target-name> [target-names...]", - Short: "Build one or more targets", - Run: buildRunCmd, - } - - cmd.AddCommand(buildCmd) - AddTabCompleteFn(buildCmd, func() []string { - return append(targetList(), "all") - }) - - cleanCmd := &cobra.Command{ - Use: "clean <target-name> [target-names...] | all", - Short: "Delete build artifacts for one or more targets", - Run: cleanRunCmd, - } - - cmd.AddCommand(cleanCmd) - AddTabCompleteFn(cleanCmd, func() []string { - return append(append(targetList(), unittestList()...), "all") - }) - - var exclude string - testCmd := &cobra.Command{ - Use: "test <package-name> [package-names...] | all", - Short: "Executes unit tests for one or more packages", - Run: func(cmd *cobra.Command, args []string) { - testRunCmd(cmd, args, exclude) - }, - } - testCmd.Flags().StringVarP(&exclude, "exclude", "e", "", "Comma separated list of packages to exclude") - cmd.AddCommand(testCmd) - AddTabCompleteFn(testCmd, func() []string { - return append(testablePkgList(), "all", "allexcept") - }) - - loadHelpText := "Load application image on to the board for <target-name>" - - loadCmd := &cobra.Command{ - Use: "load <target-name>", - Short: "Load built target to board", - Long: loadHelpText, - Run: loadRunCmd, - } - - cmd.AddCommand(loadCmd) - AddTabCompleteFn(loadCmd, targetList) - - loadCmd.PersistentFlags().StringVarP(&extraJtagCmd, "extrajtagcmd", "", "", - "Extra commands to send to JTAG software") - - debugHelpText := "Open a debugger session for <target-name>" - - debugCmd := &cobra.Command{ - Use: "debug <target-name>", - Short: "Open debugger session to target", - Long: debugHelpText, - Run: debugRunCmd, - } - - debugCmd.PersistentFlags().StringVarP(&extraJtagCmd, "extrajtagcmd", "", - "", "Extra commands to send to JTAG software") - debugCmd.PersistentFlags().BoolVarP(&noGDB_flag, "noGDB", "n", false, - "Do not start GDB from command line") - - cmd.AddCommand(debugCmd) - AddTabCompleteFn(debugCmd, targetList) - - sizeHelpText := "Calculate the size of target components specified by " + - "<target-name>." - - var ram, flash bool - sizeCmd := &cobra.Command{ - Use: "size <target-name>", - Short: "Size of target components", - Long: sizeHelpText, - Run: func(cmd *cobra.Command, args []string) { - sizeRunCmd(cmd, args, ram, flash) - }, - } - - sizeCmd.Flags().BoolVarP(&ram, "ram", "R", false, "Print RAM statistics") - sizeCmd.Flags().BoolVarP(&flash, "flash", "F", false, - "Print FLASH statistics") - - cmd.AddCommand(sizeCmd) - AddTabCompleteFn(sizeCmd, targetList) -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/cli/complete_cmd.go ---------------------------------------------------------------------- diff --git a/newt/cli/complete_cmd.go b/newt/cli/complete_cmd.go deleted file mode 100644 index ae3d39e..0000000 --- a/newt/cli/complete_cmd.go +++ /dev/null @@ -1,252 +0,0 @@ -/** - * 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 cli - -import ( - "fmt" - "os" - "regexp" - "sort" - "strings" - - "mynewt.apache.org/newt/newt/pkg" - "mynewt.apache.org/newt/newt/project" - - "github.com/spf13/cobra" - "github.com/spf13/pflag" -) - -type TabCompleteFn func() []string - -var tabCompleteEntries = map[*cobra.Command]TabCompleteFn{} - -func AddTabCompleteFn(cmd *cobra.Command, cb TabCompleteFn) { - if cmd.ValidArgs != nil || tabCompleteEntries[cmd] != nil { - panic("tab completion values generated twice for command " + - cmd.Name()) - } - - tabCompleteEntries[cmd] = cb -} - -func GenerateTabCompleteValues() { - for cmd, cb := range tabCompleteEntries { - cmd.ValidArgs = cb() - } -} - -func pkgNameList(filterCb func(*pkg.LocalPackage) bool) []string { - names := []string{} - - proj, err := project.TryGetProject() - if err != nil { - return names - } - - for _, pack := range proj.PackagesOfType(-1) { - if filterCb(pack.(*pkg.LocalPackage)) { - names = append(names, pack.FullName()) - } - } - - sort.Strings(names) - return names -} - -func targetList() []string { - targetNames := pkgNameList(func(pack *pkg.LocalPackage) bool { - return pack.Type() == pkg.PACKAGE_TYPE_TARGET && - !strings.HasSuffix(pack.Name(), "/unittest") - }) - - // Remove "targets/" prefix. - for i, _ := range targetNames { - targetNames[i] = strings.TrimPrefix( - targetNames[i], TARGET_DEFAULT_DIR+"/") - } - - return targetNames -} - -/* @return A slice of all testable package names. */ -func testablePkgList() []string { - packs := testablePkgs() - names := make([]string, 0, len(packs)) - for pack, _ := range packs { - if pack.Type() != pkg.PACKAGE_TYPE_UNITTEST { - names = append(names, pack.FullName()) - } - } - - return names -} - -func unittestList() []string { - return pkgNameList(func(pack *pkg.LocalPackage) bool { - return pack.Type() == pkg.PACKAGE_TYPE_UNITTEST - }) -} - -func mfgList() []string { - targetNames := pkgNameList(func(pack *pkg.LocalPackage) bool { - return pack.Type() == pkg.PACKAGE_TYPE_MFG - }) - - // Remove "targets/" prefix. - for i, _ := range targetNames { - targetNames[i] = strings.TrimPrefix( - targetNames[i], MFG_DEFAULT_DIR+"/") - } - - return targetNames -} - -func completeRunCmd(cmd *cobra.Command, args []string) { - cmd_line := os.Getenv("COMP_LINE") - - if cmd_line == "" { - fmt.Println("This command is intended to be used as part of " + - " bash autocomplete. Its not intended to be called directly from " + - " the command line ") - return - } - - root_cmd := cmd.Root() - - args = strings.Split(cmd_line, " ") - found_cmd, _, _ := root_cmd.Find(args[1:]) - if found_cmd == nil { - return - } - - /* this is worth a long comment. We have to find a command line - * with the flags removed. To do this, I look at the command - * path for the command without flags, and remove anything that - * doesn't match */ - found_args := strings.Split(found_cmd.CommandPath(), " ") - last_arg := found_args[len(found_args)-1] - - /* what is remaining after the last parsed argument */ - ind := strings.Index(cmd_line, last_arg) - ind += len(last_arg) - extra_str := cmd_line[ind:] - - if len(extra_str) == 0 { - /* this matched an exact command with no space afterwards. There - * is no autocomplete except this command (to add a space) */ - fmt.Println(found_cmd.Name()) - return - } - - /* skip flags for now. This just removes them */ - /* skip over complete flags. So the current bash autocomplete will - * not complete flags */ - cmd.Flags().VisitAll(func(flag *pflag.Flag) { - flg := fmt.Sprintf("--%s", flag.Name) - if flag.Value.Type() == "bool" { - /* skip the flag */ - r := regexp.MustCompile(flg + "[\\W]+") - extra_str = r.ReplaceAllString(extra_str, "") - } else if flag.Value.Type() == "string" { - /* skip the string and the next word */ - r := regexp.MustCompile(flg + "[\\W]+[^\\W]+[\\W]+") - extra_str = r.ReplaceAllString(extra_str, "") - } - - sflg := fmt.Sprintf("-%s", flag.Shorthand) - if flag.Value.Type() == "bool" { - /* skip the flag */ - r := regexp.MustCompile(sflg + "[\\W]+") - extra_str = r.ReplaceAllString(extra_str, "") - } else if flag.Value.Type() == "string" { - /* skip the string and the next word */ - r := regexp.MustCompile(sflg + "[\\W]+[^\\W]+[\\W]+") - extra_str = r.ReplaceAllString(extra_str, "") - } - }) - - if len(extra_str) == 0 { - /* this matched an exact command with no space afterwards. There - * is no autocomplete except this command (to add a space) */ - return - } - - extra_str = strings.TrimLeft(extra_str, " ") - - /* give flag hints if the person asks for them */ - showShort := strings.HasPrefix(extra_str, "-") && - !strings.HasPrefix(extra_str, "--") - - showLong := strings.HasPrefix(extra_str, "--") || - extra_str == "-" - - if showLong { - r := regexp.MustCompile("^--[^\\W]+") - partial_flag := r.FindString(extra_str) - cmd.Flags().VisitAll(func(flag *pflag.Flag) { - flg := fmt.Sprintf("--%s", flag.Name) - if strings.HasPrefix(flg, partial_flag) { - fmt.Println(flg) - } - }) - } - - if showShort { - r := regexp.MustCompile("^-[^\\W]+") - partial_flag := r.FindString(extra_str) - cmd.Flags().VisitAll(func(flag *pflag.Flag) { - if len(flag.Shorthand) > 0 { - flg := fmt.Sprintf("-%s", flag.Shorthand) - if strings.HasPrefix(flg, partial_flag) { - fmt.Println(flg) - } - } - }) - } - - /* dump out valid arguments */ - for _, c := range found_cmd.ValidArgs { - if strings.HasPrefix(c, extra_str) { - fmt.Printf("%s\n", c) - } - } - - /* dump out possible sub commands */ - for _, child_cmd := range found_cmd.Commands() { - if strings.HasPrefix(child_cmd.Name(), extra_str) { - fmt.Printf("%s\n", child_cmd.Name()) - } - } -} - -func AddCompleteCommands(cmd *cobra.Command) { - - completeCmd := &cobra.Command{ - Use: "complete", - Short: "", - Long: "", - Run: completeRunCmd, - Hidden: true, - } - - /* silence errors on the complete command because we have partial flags */ - completeCmd.SilenceErrors = true - cmd.AddCommand(completeCmd) -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/cli/image_cmds.go ---------------------------------------------------------------------- diff --git a/newt/cli/image_cmds.go b/newt/cli/image_cmds.go deleted file mode 100644 index 5a19c63..0000000 --- a/newt/cli/image_cmds.go +++ /dev/null @@ -1,95 +0,0 @@ -/** - * 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 cli - -import ( - "strconv" - - "github.com/spf13/cobra" - "mynewt.apache.org/newt/newt/builder" - "mynewt.apache.org/newt/newt/newtutil" - "mynewt.apache.org/newt/util" -) - -func createImageRunCmd(cmd *cobra.Command, args []string) { - var keyId uint8 - var keystr string - - if len(args) < 2 { - NewtUsage(cmd, util.NewNewtError("Must specify target and version")) - } - - TryGetProject() - - targetName := args[0] - t := ResolveTarget(targetName) - if t == nil { - NewtUsage(cmd, util.NewNewtError("Invalid target name: "+targetName)) - } - - version := args[1] - - if len(args) > 2 { - if len(args) > 3 { - keyId64, err := strconv.ParseUint(args[3], 10, 8) - if err != nil { - NewtUsage(cmd, - util.NewNewtError("Key ID must be between 0-255")) - } - keyId = uint8(keyId64) - } - keystr = args[2] - } - - b, err := builder.NewTargetBuilder(t) - if err != nil { - NewtUsage(nil, err) - } - - if _, _, err := b.CreateImages(version, keystr, keyId); err != nil { - NewtUsage(nil, err) - return - } -} - -func AddImageCommands(cmd *cobra.Command) { - createImageHelpText := "Create an image by adding an image header to the " + - "binary file created for <target-name>. Version number in the header is set " + - "to be <version>.\n\nTo sign the image give private key as <signing-key> and an optional key-id." - createImageHelpEx := " newt create-image my_target1 1.2.0\n" - createImageHelpEx += " newt create-image my_target1 1.2.0.3\n" - createImageHelpEx += " newt create-image my_target1 1.2.0.3 private.pem\n" - createImageHelpEx += " newt create-image my_target1 1.2.0.3 private.pem 5\n" - - createImageCmd := &cobra.Command{ - Use: "create-image <target-name> <version> [signing-key [key-id]]", - Short: "Add image header to target binary", - Long: createImageHelpText, - Example: createImageHelpEx, - Run: createImageRunCmd, - } - - createImageCmd.PersistentFlags().BoolVarP(&newtutil.NewtForce, - "force", "f", false, - "Ignore flash overflow errors during image creation") - - cmd.AddCommand(createImageCmd) - AddTabCompleteFn(createImageCmd, targetList) -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/cli/mfg_cmds.go ---------------------------------------------------------------------- diff --git a/newt/cli/mfg_cmds.go b/newt/cli/mfg_cmds.go deleted file mode 100644 index 1e35d4e..0000000 --- a/newt/cli/mfg_cmds.go +++ /dev/null @@ -1,201 +0,0 @@ -/** - * 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 cli - -import ( - "github.com/spf13/cobra" - - "mynewt.apache.org/newt/newt/image" - "mynewt.apache.org/newt/newt/mfg" - "mynewt.apache.org/newt/newt/pkg" - "mynewt.apache.org/newt/util" -) - -func ResolveMfgPkg(pkgName string) (*pkg.LocalPackage, error) { - proj := TryGetProject() - - lpkg, err := proj.ResolvePackage(proj.LocalRepo(), pkgName) - if err != nil { - var err2 error - lpkg, err2 = proj.ResolvePackage(proj.LocalRepo(), - MFG_DEFAULT_DIR+"/"+pkgName) - if err2 != nil { - return nil, err - } - } - - if lpkg.Type() != pkg.PACKAGE_TYPE_MFG { - return nil, util.FmtNewtError( - "Package \"%s\" has incorrect type; expected mfg, got %s", - pkgName, pkg.PackageTypeNames[lpkg.Type()]) - } - - return lpkg, nil -} - -func mfgCreate(mi *mfg.MfgImage) { - pathStr := "" - for _, path := range mi.FromPaths() { - pathStr += " * " + path + "\n" - } - - util.StatusMessage(util.VERBOSITY_DEFAULT, - "Creating a manufacturing image from the following files:\n%s\n", - pathStr) - - outputPaths, err := mi.CreateMfgImage() - if err != nil { - NewtUsage(nil, err) - } - - pathStr = "" - for _, path := range outputPaths { - pathStr += " * " + path + "\n" - } - util.StatusMessage(util.VERBOSITY_DEFAULT, - "Generated the following files:\n%s", pathStr) -} - -func mfgLoad(mi *mfg.MfgImage) { - binPath, err := mi.Upload() - if err != nil { - NewtUsage(nil, err) - } - - util.StatusMessage(util.VERBOSITY_DEFAULT, - "Uploaded manufacturing image: %s\n", binPath) -} - -func mfgCreateRunCmd(cmd *cobra.Command, args []string) { - if len(args) < 2 { - NewtUsage(cmd, util.NewNewtError( - "Must specify mfg package name and version number")) - } - - pkgName := args[0] - lpkg, err := ResolveMfgPkg(pkgName) - if err != nil { - NewtUsage(cmd, err) - } - - versStr := args[1] - ver, err := image.ParseVersion(versStr) - if err != nil { - NewtUsage(cmd, err) - } - - mi, err := mfg.Load(lpkg) - if err != nil { - NewtUsage(nil, err) - } - - mi.SetVersion(ver) - mfgCreate(mi) -} - -func mfgLoadRunCmd(cmd *cobra.Command, args []string) { - if len(args) < 1 { - NewtUsage(cmd, util.NewNewtError("Must specify mfg package name")) - } - - pkgName := args[0] - lpkg, err := ResolveMfgPkg(pkgName) - if err != nil { - NewtUsage(cmd, err) - } - - mi, err := mfg.Load(lpkg) - if err != nil { - NewtUsage(nil, err) - } - - mfgLoad(mi) -} - -func mfgDeployRunCmd(cmd *cobra.Command, args []string) { - if len(args) < 1 { - NewtUsage(cmd, util.NewNewtError("Must specify mfg package name")) - } - - pkgName := args[0] - lpkg, err := ResolveMfgPkg(pkgName) - if err != nil { - NewtUsage(cmd, err) - } - - ver := image.ImageVersion{} - if len(args) >= 2 { - versStr := args[1] - ver, err = image.ParseVersion(versStr) - if err != nil { - NewtUsage(cmd, err) - } - } - - mi, err := mfg.Load(lpkg) - if err != nil { - NewtUsage(nil, err) - } - - mi.SetVersion(ver) - mfgCreate(mi) - - mfgLoad(mi) -} - -func AddMfgCommands(cmd *cobra.Command) { - mfgHelpText := "" - mfgHelpEx := "" - mfgCmd := &cobra.Command{ - Use: "mfg", - Short: "Manufacturing flash image commands", - Long: mfgHelpText, - Example: mfgHelpEx, - Run: func(cmd *cobra.Command, args []string) { - cmd.Usage() - }, - } - - cmd.AddCommand(mfgCmd) - - mfgCreateCmd := &cobra.Command{ - Use: "create <mfg-package-name> <version #.#.#.#>", - Short: "Create a manufacturing flash image", - Run: mfgCreateRunCmd, - } - mfgCmd.AddCommand(mfgCreateCmd) - AddTabCompleteFn(mfgCreateCmd, mfgList) - - mfgLoadCmd := &cobra.Command{ - Use: "load <mfg-package-name>", - Short: "Load a manufacturing flash image onto a device", - Run: mfgLoadRunCmd, - } - mfgCmd.AddCommand(mfgLoadCmd) - AddTabCompleteFn(mfgLoadCmd, mfgList) - - mfgDeployCmd := &cobra.Command{ - Use: "deploy <mfg-package-name> [version #.#.#.#]", - Short: "Build and upload a manufacturing image (create + load)", - Run: mfgDeployRunCmd, - } - mfgCmd.AddCommand(mfgDeployCmd) - AddTabCompleteFn(mfgDeployCmd, mfgList) -}
