From 0407005cdb5fea70741848435a12f3b665e0e50a Mon Sep 17 00:00:00 2001 From: deadprogram Date: Thu, 21 Mar 2024 20:25:53 +0100 Subject: [PATCH] mecha: extend build command with project/modules subcommands and build flags Signed-off-by: deadprogram --- cmd/mecha/about.go | 1 + cmd/mecha/build.go | 61 +++++++++++++++++++++++++++++++++++++++++++--- cmd/mecha/flash.go | 2 +- cmd/mecha/main.go | 52 ++++++++++++++++++++++++++------------- cmd/mecha/run.go | 2 +- 5 files changed, 95 insertions(+), 23 deletions(-) diff --git a/cmd/mecha/about.go b/cmd/mecha/about.go index fe4a270..51064c5 100644 --- a/cmd/mecha/about.go +++ b/cmd/mecha/about.go @@ -22,6 +22,7 @@ var logo = ` func about(cCtx *cli.Context) error { fmt.Println(logo) + fmt.Println("Version:", Version()) return nil } diff --git a/cmd/mecha/build.go b/cmd/mecha/build.go index c8d4a78..6840788 100644 --- a/cmd/mecha/build.go +++ b/cmd/mecha/build.go @@ -13,15 +13,70 @@ import ( "github.com/urfave/cli/v2" ) -func build(cCtx *cli.Context) error { +func buildProject(cCtx *cli.Context) error { + if cCtx.Args().Len() < 1 { + return fmt.Errorf("target board required") + } + + targetName := cCtx.Args().First() + wd, err := os.Getwd() if err != nil { fmt.Println(err) os.Exit(1) } - if stat, err := os.Stat(filepath.Join(wd, "modules")); err == nil && stat.IsDir() { + projectname := filepath.Base(wd) + + s := spinner.New(spinner.CharSets[5], 100*time.Millisecond, spinner.WithWriter(os.Stdout)) + s.Suffix = " Building application for " + targetName + " using interpreter " + cCtx.String("interpreter") + s.FinalMSG = "Application built.\n" + s.Start() + defer s.Stop() + + intp := cCtx.String("interpreter") + if intp == "wasman" { + intp = "wasman nowazero" + } + if cCtx.Bool("debug") { + intp += " debug" + } + + args := []string{"build", "-o", projectname+".uf2", "-size", "short", "-stack-size", "8kb", "-tags", intp, "-target", targetName} + + if len(cCtx.StringSlice("params")) > 0 { + ldlags := "" + for _, p := range cCtx.StringSlice("params") { + ldlags += " -X " + p + } + args = append(args, "-ldflags", ldlags) + } + + args = append(args, ".") + + var cmd = exec.Command("tinygo", args...) + + var stdoutBuf, stderrBuf bytes.Buffer + cmd.Stdout = io.MultiWriter(&spinWriter{s, os.Stdout, false}, &stdoutBuf) + cmd.Stderr = io.MultiWriter(&spinWriter{s, os.Stderr, false}, &stderrBuf) + + if err := cmd.Run(); err != nil { + fmt.Printf("%s: %v\n", cmd.String(), err) + os.Exit(1) + } + + return nil +} + +func buildModules(cCtx *cli.Context) error { + wd, err := os.Getwd() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + if stat, err := os.Stat(filepath.Join(wd, "modules")); err == nil && stat.IsDir() { // build modules? dirs, err := os.ReadDir(filepath.Join(wd, "modules")) if err != nil { @@ -51,8 +106,6 @@ func build(cCtx *cli.Context) error { } } - // TODO: build main project - return nil } diff --git a/cmd/mecha/flash.go b/cmd/mecha/flash.go index f96a49f..d4ef88c 100644 --- a/cmd/mecha/flash.go +++ b/cmd/mecha/flash.go @@ -18,7 +18,7 @@ func flash(cCtx *cli.Context) error { } // build all the modules before flashing the hardware - if err := build(cCtx); err != nil { + if err := buildModules(cCtx); err != nil { return err } diff --git a/cmd/mecha/main.go b/cmd/mecha/main.go index 2df2598..a23deaa 100644 --- a/cmd/mecha/main.go +++ b/cmd/mecha/main.go @@ -7,9 +7,20 @@ import ( "github.com/urfave/cli/v2" ) -var templateFlags = []cli.Flag{ - &cli.StringFlag{Name: "template", Aliases: []string{"t"}, Usage: "template to use for module creation"}, -} +var ( + templateFlags = []cli.Flag{ + &cli.StringFlag{Name: "template", Aliases: []string{"t"}, Usage: "template to use for module creation"}, + } + + buildFlags = []cli.Flag{ + &cli.StringFlag{Name: "interpreter", Aliases: []string{"i"}, Value: "wazero", Usage: "WebAssembly interpreter to use (wasman, wazero)"}, + &cli.BoolFlag{Name: "debug", Aliases: []string{"d"}, Usage: "perform additional logging for debugging"}, + &cli.StringSliceFlag{ + Name: "params", + Usage: "Pass build-time parameters for the application or modules. Format: -params main.name=value -params main.descript=value2", + }, + } +) func main() { app := &cli.App{ @@ -42,32 +53,39 @@ func main() { }, { Name: "build", - Usage: "Build binary files for Mechanoid project", - Action: build, + Usage: "Build binary files for Mechanoid project and/or modules", + ArgsUsage: "", + Flags: buildFlags, + Action: buildModules, + Subcommands: []*cli.Command{ + { + Name: "project", + Usage: "Build current Mechanoid project", + Action: buildProject, + Flags: buildFlags, + }, + { + Name: "modules", + Usage: "Build current Mechanoid modules", + Action: buildModules, + Flags: buildFlags, + }, + }, }, { Name: "flash", Usage: "Flash Mechanoid project to hardware", Action: flash, ArgsUsage: "", - Flags: []cli.Flag{ + Flags: append(buildFlags, &cli.BoolFlag{Name: "monitor", Aliases: []string{"m"}, Usage: "monitor the serial port after flashing"}, - &cli.StringFlag{Name: "interpreter", Aliases: []string{"i"}, Value: "wazero", Usage: "WebAssembly interpreter to use (wasman, wazero)"}, - &cli.BoolFlag{Name: "debug", Aliases: []string{"d"}, Usage: "perform additional logging for debugging"}, - &cli.StringSliceFlag{ - Name: "params", - Usage: "Pass build-time parameters for the application. Format: -params main.name=value -params main.descript=value2", - }, - }, + ), }, { Name: "run", Usage: "Run code for Mechanoid project", Action: run, - Flags: []cli.Flag{ - &cli.StringFlag{Name: "interpreter", Aliases: []string{"i"}, Value: "wazero", Usage: "WebAssembly interpreter to use (wasman, wazero)"}, - &cli.BoolFlag{Name: "debug", Aliases: []string{"d"}, Usage: "perform additional logging for debugging"}, - }, + Flags: buildFlags, }, { Name: "test", diff --git a/cmd/mecha/run.go b/cmd/mecha/run.go index 7df460b..d7217ee 100644 --- a/cmd/mecha/run.go +++ b/cmd/mecha/run.go @@ -14,7 +14,7 @@ func run(cCtx *cli.Context) error { fmt.Println("Running using interpreter", cCtx.String("interpreter")) // build all the modules before running - if err := build(cCtx); err != nil { + if err := buildModules(cCtx); err != nil { return err }