// Generates the following build artifacts: // * lst file // * map file // * bin file // // @param elfFilename The filename of the elf file corresponding to // the artifacts to be generated. // @param options Some build options specifying which artifacts // get generated. func (c *Compiler) generateExtras(elfFilename string, options map[string]bool) error { var cmd string if options["binFile"] { binFile := elfFilename + ".bin" cmd = c.ocPath + " -R .bss -R .bss.core -R .bss.core.nz -O binary " + elfFilename + " " + binFile _, err := util.ShellCommand(cmd) if err != nil { return err } } if options["listFile"] { listFile := elfFilename + ".lst" // if list file exists, remove it if util.NodeExist(listFile) { if err := os.RemoveAll(listFile); err != nil { return err } } cmd = c.odPath + " -wxdS " + elfFilename + " >> " + listFile _, err := util.ShellCommand(cmd) if err != nil { // XXX: gobjdump appears to always crash. Until we get that sorted // out, don't fail the link process if lst generation fails. return nil } sects := []string{".text", ".rodata", ".data"} for _, sect := range sects { cmd = c.odPath + " -s -j " + sect + " " + elfFilename + " >> " + listFile util.ShellCommand(cmd) } cmd = c.osPath + " " + elfFilename + " >> " + listFile _, err = util.ShellCommand(cmd) if err != nil { return err } } return nil }
func (b *Builder) Test(p *pkg.LocalPackage) error { // Build the packages alphabetically to ensure a consistent order. bpkgs := b.sortedBuildPackages() for _, bpkg := range bpkgs { if err := b.buildPackage(bpkg); err != nil { return err } } testBpkg := b.PkgMap[p] testFilename := b.TestExePath(testBpkg) if err := b.link(testFilename, nil, nil); err != nil { return err } // Run the tests. if err := os.Chdir(filepath.Dir(testFilename)); err != nil { return err } util.StatusMessage(util.VERBOSITY_DEFAULT, "Executing test: %s\n", testFilename) if _, err := util.ShellCommand(testFilename); err != nil { newtError := err.(*util.NewtError) newtError.Text = fmt.Sprintf("Test failure (%s):\n%s", p.Name(), newtError.Text) return newtError } return nil }
// Generates a dependency Makefile (.d) for the specified source C file. // // @param file The name of the source file. func (c *Compiler) GenDepsForFile(file string) error { if util.NodeNotExist(c.dstDir) { os.MkdirAll(c.dstDir, 0755) } depFile := c.dstDir + "/" + strings.TrimSuffix(file, filepath.Ext(file)) + ".d" depFile = filepath.ToSlash(depFile) var cmd string var err error cmd = c.ccPath + " " + c.cflagsString() + " " + c.includesString() + " -MM -MG " + file + " > " + depFile o, err := util.ShellCommand(cmd) if err != nil { return util.NewNewtError(string(o)) } // Append the extra dependencies (.yml files) to the .d file. f, err := os.OpenFile(depFile, os.O_APPEND|os.O_WRONLY, 0666) if err != nil { return util.NewNewtError(err.Error()) } defer f.Close() objFile := strings.TrimSuffix(file, filepath.Ext(file)) + ".o" if _, err := f.WriteString(objFile + ": " + c.depsString()); err != nil { return util.NewNewtError(err.Error()) } return nil }
// Links the specified elf file. // // @param dstFile The filename of the destination elf file to // link. // @param options Some build options specifying how the elf file // gets generated. // @param objFiles An array of the source .o and .a filenames. func (c *Compiler) CompileBinary(dstFile string, options map[string]bool, objFiles []string, keepSymbols []string, elfLib string) error { // Make sure the compiler package info is added to the global set. c.ensureLclInfoAdded() objList := c.getObjFiles(util.UniqueStrings(objFiles)) util.StatusMessage(util.VERBOSITY_DEFAULT, "Linking %s\n", dstFile) util.StatusMessage(util.VERBOSITY_VERBOSE, "Linking %s with input files %s\n", dstFile, objList) if elfLib != "" { util.StatusMessage(util.VERBOSITY_VERBOSE, "Linking %s with rom image %s\n", dstFile, elfLib) } cmd := c.CompileBinaryCmd(dstFile, options, objFiles, keepSymbols, elfLib) _, err := util.ShellCommand(cmd) if err != nil { return err } err = writeCommandFile(dstFile, cmd) if err != nil { return err } return nil }
func (c *Compiler) PrintSize(elfFilename string) (string, error) { cmd := c.osPath + " " + elfFilename rsp, err := util.ShellCommand(cmd) if err != nil { return "", err } return string(rsp), nil }
func (c *Compiler) RenameSymbols(sm *symbol.SymbolMap, libraryFile string, ext string) error { cmd := c.RenameSymbolsCmd(sm, libraryFile, ext) _, err := util.ShellCommand(cmd) return err }
func (c *Compiler) CopySymbols(infile string, outfile string, sm *symbol.SymbolMap) error { cmd := c.CopySymbolsCmd(infile, outfile, sm) _, err := util.ShellCommand(cmd) if err != nil { return err } return err }
func (c *Compiler) ParseLibrary(libraryFile string) (error, []byte) { cmd := c.ParseLibraryCmd(libraryFile) out, err := util.ShellCommand(cmd) if err != nil { return err, nil } return err, out }
func (gd *GithubDownloader) DownloadRepo(commit string) (string, error) { // Get a temporary directory, and copy the repository into that directory. tmpdir, err := ioutil.TempDir("", "newt-repo") if err != nil { return "", err } // Currently only the master branch is supported. branch := "master" url := fmt.Sprintf("https://github.com/%s/%s.git", gd.User, gd.Repo) util.StatusMessage(util.VERBOSITY_VERBOSE, "Downloading "+ "repository %s (branch: %s; commit: %s) at %s\n", gd.Repo, branch, commit, url) gitPath, err := exec.LookPath("git") if err != nil { os.RemoveAll(tmpdir) return "", util.NewNewtError(fmt.Sprintf("Can't find git binary: %s\n", err.Error())) } // Clone the repository. cmds := []string{ gitPath, "clone", "-b", branch, url, tmpdir, } if util.Verbosity >= util.VERBOSITY_VERBOSE { if err := util.ShellInteractiveCommand(cmds, nil); err != nil { os.RemoveAll(tmpdir) return "", err } } else { if _, err := util.ShellCommand(strings.Join(cmds, " ")); err != nil { return "", err } } // Checkout the specified commit. if err := checkout(tmpdir, commit); err != nil { return "", err } return tmpdir, nil }
// Archives the specified static library. // // @param archiveFile The filename of the library to archive. // @param objFiles An array of the source .o filenames. func (c *Compiler) CompileArchive(archiveFile string) error { objFiles := []string{} // Make sure the compiler package info is added to the global set. c.ensureLclInfoAdded() arRequired, err := c.depTracker.ArchiveRequired(archiveFile, objFiles) if err != nil { return err } if !arRequired { return nil } if err := os.MkdirAll(filepath.Dir(archiveFile), 0755); err != nil { return util.NewNewtError(err.Error()) } // Delete the old archive, if it exists. err = os.Remove(archiveFile) util.StatusMessage(util.VERBOSITY_DEFAULT, "Archiving %s\n", path.Base(archiveFile)) objList := c.getObjFiles([]string{}) if objList == "" { return nil } util.StatusMessage(util.VERBOSITY_VERBOSE, "Archiving %s with object "+ "files %s\n", archiveFile, objList) if err != nil && !os.IsNotExist(err) { return util.NewNewtError(err.Error()) } cmd := c.CompileArchiveCmd(archiveFile, objFiles) _, err = util.ShellCommand(cmd) if err != nil { return err } err = writeCommandFile(archiveFile, cmd) if err != nil { return err } return nil }
// Compile the specified C or assembly file. // // @param file The filename of the source file to compile. // @param compilerType One of the COMPILER_TYPE_[...] constants. func (c *Compiler) CompileFile(file string, compilerType int) error { if util.NodeNotExist(c.dstDir) { os.MkdirAll(c.dstDir, 0755) } objFile := strings.TrimSuffix(file, filepath.Ext(file)) + ".o" objPath := c.dstDir + "/" + objFile c.ObjPathList[filepath.ToSlash(objPath)] = true cmd, err := c.CompileFileCmd(file, compilerType) if err != nil { return err } switch compilerType { case COMPILER_TYPE_C: util.StatusMessage(util.VERBOSITY_DEFAULT, "Compiling %s\n", file) case COMPILER_TYPE_CPP: util.StatusMessage(util.VERBOSITY_DEFAULT, "Compiling %s\n", file) case COMPILER_TYPE_ASM: util.StatusMessage(util.VERBOSITY_DEFAULT, "Assembling %s\n", file) default: return util.NewNewtError("Unknown compiler type") } _, err = util.ShellCommand(cmd) if err != nil { return err } err = writeCommandFile(objPath, cmd) if err != nil { return err } // Tell the dependency tracker that an object file was just rebuilt. c.depTracker.MostRecent = time.Now() return nil }
func Load(binBaseName string, bspPkg *pkg.BspPackage, extraEnvSettings map[string]string) error { if bspPkg.DownloadScript == "" { return nil } bspPath := bspPkg.BasePath() sortedKeys := make([]string, 0, len(extraEnvSettings)) for k, _ := range extraEnvSettings { sortedKeys = append(sortedKeys, k) } sort.Strings(sortedKeys) envSettings := "" for _, key := range sortedKeys { envSettings += fmt.Sprintf("%s=\"%s\" ", key, extraEnvSettings[key]) } coreRepo := project.GetProject().FindRepo("apache-mynewt-core") envSettings += fmt.Sprintf("CORE_PATH=\"%s\" ", coreRepo.Path()) envSettings += fmt.Sprintf("BSP_PATH=\"%s\" ", bspPath) envSettings += fmt.Sprintf("BIN_BASENAME=\"%s\" ", binBaseName) // bspPath, binBaseName are passed in command line for backwards // compatibility downloadCmd := fmt.Sprintf("%s %s %s %s", envSettings, bspPkg.DownloadScript, bspPath, binBaseName) util.StatusMessage(util.VERBOSITY_VERBOSE, "Load command: %s\n", downloadCmd) _, err := util.ShellCommand(downloadCmd) if err != nil { return err } util.StatusMessage(util.VERBOSITY_VERBOSE, "Successfully loaded image.\n") return nil }
func checkout(repoDir string, commit string) error { // Retrieve the current directory so that we can get back to where we // started after the download completes. pwd, err := os.Getwd() if err != nil { return util.NewNewtError(err.Error()) } gitPath, err := exec.LookPath("git") if err != nil { return util.NewNewtError(fmt.Sprintf("Can't find git binary: %s\n", err.Error())) } if err := os.Chdir(repoDir); err != nil { return util.NewNewtError(err.Error()) } // Checkout the specified commit. cmds := []string{ gitPath, "checkout", commit, } if o, err := util.ShellCommand(strings.Join(cmds, " ")); err != nil { return util.NewNewtError(string(o)) } // Go back to original directory. if err := os.Chdir(pwd); err != nil { return util.NewNewtError(err.Error()) } return nil }