From c4d642007e6747ef9425471c16536617ac2d1ca5 Mon Sep 17 00:00:00 2001 From: Fauchon Date: Thu, 14 Jan 2021 21:35:01 +0100 Subject: [PATCH] New tinygo -x option to print commands (#1572) main: add '-x' runtime flag that displays the executed external commands when performing operations like flashing. --- compileopts/options.go | 1 + main.go | 54 +++++++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 22 deletions(-) diff --git a/compileopts/options.go b/compileopts/options.go index b5526b78..f5f5a222 100644 --- a/compileopts/options.go +++ b/compileopts/options.go @@ -23,6 +23,7 @@ type Options struct { PrintIR bool DumpSSA bool VerifyIR bool + PrintCommands bool Debug bool PrintSizes string PrintStacks bool diff --git a/main.go b/main.go index 84bf3f05..74c4d6aa 100644 --- a/main.go +++ b/main.go @@ -88,6 +88,14 @@ func copyFile(src, dst string) error { return err } +// executeCommand is a simple wrapper to exec.Cmd +func executeCommand(options *compileopts.Options, name string, arg ...string) *exec.Cmd { + if options.PrintCommands { + fmt.Printf("%s %s\n ", name, strings.Join(arg, " ")) + } + return exec.Command(name, arg...) +} + // Build compiles and links the given package and writes it to outpath. func Build(pkgName, outpath string, options *compileopts.Options) error { config, err := builder.NewConfig(options) @@ -147,7 +155,7 @@ func Test(pkgName string, options *compileopts.Options, testCompileOnly bool, ou } if len(config.Target.Emulator) == 0 { // Run directly. - cmd := exec.Command(result.Binary) + cmd := executeCommand(config.Options, result.Binary) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr cmd.Dir = result.MainDir @@ -166,7 +174,7 @@ func Test(pkgName string, options *compileopts.Options, testCompileOnly bool, ou } else { // Run in an emulator. args := append(config.Target.Emulator[1:], result.Binary) - cmd := exec.Command(config.Target.Emulator[0], args...) + cmd := executeCommand(config.Options, config.Target.Emulator[0], args...) buf := &bytes.Buffer{} w := io.MultiWriter(os.Stdout, buf) cmd.Stdout = w @@ -275,9 +283,9 @@ func Flash(pkgName, port string, options *compileopts.Options) error { if len(command) < 2 { return errors.New("invalid flash command") } - cmd = exec.Command(command[0], command[1:]...) + cmd = executeCommand(config.Options, command[0], command[1:]...) default: - cmd = exec.Command("/bin/sh", "-c", flashCmd) + cmd = executeCommand(config.Options, "/bin/sh", "-c", flashCmd) } cmd.Stdout = os.Stdout @@ -291,13 +299,13 @@ func Flash(pkgName, port string, options *compileopts.Options) error { case "msd": switch fileExt { case ".uf2": - err := flashUF2UsingMSD(config.Target.FlashVolume, result.Binary) + err := flashUF2UsingMSD(config.Target.FlashVolume, result.Binary, config.Options) if err != nil { return &commandError{"failed to flash", result.Binary, err} } return nil case ".hex": - err := flashHexUsingMSD(config.Target.FlashVolume, result.Binary) + err := flashHexUsingMSD(config.Target.FlashVolume, result.Binary, config.Options) if err != nil { return &commandError{"failed to flash", result.Binary, err} } @@ -311,7 +319,7 @@ func Flash(pkgName, port string, options *compileopts.Options) error { return err } args = append(args, "-c", "program "+filepath.ToSlash(result.Binary)+" reset exit") - cmd := exec.Command("openocd", args...) + cmd := executeCommand(config.Options, "openocd", args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err = cmd.Run() @@ -380,7 +388,7 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro if err != nil { return err } - daemon = exec.Command("openocd", args...) + daemon = executeCommand(config.Options, "openocd", args...) if ocdOutput { // Make it clear which output is from the daemon. w := &ColorWriter{ @@ -395,7 +403,7 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro gdbCommands = append(gdbCommands, "target remote :2331", "load", "monitor reset halt") // We need a separate debugging daemon for on-chip debugging. - daemon = exec.Command("JLinkGDBServer", "-device", config.Target.JLinkDevice) + daemon = executeCommand(config.Options, "JLinkGDBServer", "-device", config.Target.JLinkDevice) if ocdOutput { // Make it clear which output is from the daemon. w := &ColorWriter{ @@ -411,7 +419,7 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro // Run in an emulator. args := append(config.Target.Emulator[1:], result.Binary, "-s", "-S") - daemon = exec.Command(config.Target.Emulator[0], args...) + daemon = executeCommand(config.Options, config.Target.Emulator[0], args...) daemon.Stdout = os.Stdout daemon.Stderr = os.Stderr case "qemu-user": @@ -419,7 +427,7 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro // Run in an emulator. args := append(config.Target.Emulator[1:], "-g", "1234", result.Binary) - daemon = exec.Command(config.Target.Emulator[0], args...) + daemon = executeCommand(config.Options, config.Target.Emulator[0], args...) daemon.Stdout = os.Stdout daemon.Stderr = os.Stderr case "mgba": @@ -427,7 +435,7 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro // Run in an emulator. args := append(config.Target.Emulator[1:], result.Binary, "-g") - daemon = exec.Command(config.Target.Emulator[0], args...) + daemon = executeCommand(config.Options, config.Target.Emulator[0], args...) daemon.Stdout = os.Stdout daemon.Stderr = os.Stderr case "simavr": @@ -435,7 +443,7 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro // Run in an emulator. args := append(config.Target.Emulator[1:], "-g", result.Binary) - daemon = exec.Command(config.Target.Emulator[0], args...) + daemon = executeCommand(config.Options, config.Target.Emulator[0], args...) daemon.Stdout = os.Stdout daemon.Stderr = os.Stderr case "msd": @@ -476,7 +484,7 @@ func FlashGDB(pkgName string, ocdOutput bool, options *compileopts.Options) erro for _, cmd := range gdbCommands { params = append(params, "-ex", cmd) } - cmd := exec.Command(config.Target.GDB, params...) + cmd := executeCommand(config.Options, config.Target.GDB, params...) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr @@ -501,7 +509,7 @@ func Run(pkgName string, options *compileopts.Options) error { return builder.Build(pkgName, ".elf", config, func(result builder.BuildResult) error { if len(config.Target.Emulator) == 0 { // Run directly. - cmd := exec.Command(result.Binary) + cmd := executeCommand(config.Options, result.Binary) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err := cmd.Run() @@ -516,7 +524,7 @@ func Run(pkgName string, options *compileopts.Options) error { } else { // Run in an emulator. args := append(config.Target.Emulator[1:], result.Binary) - cmd := exec.Command(config.Target.Emulator[0], args...) + cmd := executeCommand(config.Options, config.Target.Emulator[0], args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr err := cmd.Run() @@ -559,7 +567,7 @@ func touchSerialPortAt1200bps(port string) (err error) { const maxMSDRetries = 10 -func flashUF2UsingMSD(volume, tmppath string) error { +func flashUF2UsingMSD(volume, tmppath string, options *compileopts.Options) error { // find standard UF2 info path var infoPath string switch runtime.GOOS { @@ -568,7 +576,7 @@ func flashUF2UsingMSD(volume, tmppath string) error { case "darwin": infoPath = "/Volumes/" + volume + "/INFO_UF2.TXT" case "windows": - path, err := windowsFindUSBDrive(volume) + path, err := windowsFindUSBDrive(volume, options) if err != nil { return err } @@ -583,7 +591,7 @@ func flashUF2UsingMSD(volume, tmppath string) error { return moveFile(tmppath, filepath.Dir(d)+"/flash.uf2") } -func flashHexUsingMSD(volume, tmppath string) error { +func flashHexUsingMSD(volume, tmppath string, options *compileopts.Options) error { // find expected volume path var destPath string switch runtime.GOOS { @@ -592,7 +600,7 @@ func flashHexUsingMSD(volume, tmppath string) error { case "darwin": destPath = "/Volumes/" + volume case "windows": - path, err := windowsFindUSBDrive(volume) + path, err := windowsFindUSBDrive(volume, options) if err != nil { return err } @@ -626,8 +634,8 @@ func locateDevice(volume, path string) (string, error) { return d[0], nil } -func windowsFindUSBDrive(volume string) (string, error) { - cmd := exec.Command("wmic", +func windowsFindUSBDrive(volume string, options *compileopts.Options) (string, error) { + cmd := executeCommand(options, "wmic", "PATH", "Win32_LogicalDisk", "WHERE", "VolumeName = '"+volume+"'", "get", "DeviceID,VolumeName,FileSystem,DriveType") @@ -807,6 +815,7 @@ func main() { target := flag.String("target", "", "LLVM target | .json file with TargetSpec") printSize := flag.String("size", "", "print sizes (none, short, full)") printStacks := flag.Bool("print-stacks", false, "print stack sizes of goroutines") + printCommands := flag.Bool("x", false, "Print commands") nodebug := flag.Bool("no-debug", false, "disable DWARF debug symbol generation") ocdOutput := flag.Bool("ocd-output", false, "print OCD daemon output during debug") port := flag.String("port", "", "flash port") @@ -854,6 +863,7 @@ func main() { Debug: !*nodebug, PrintSizes: *printSize, PrintStacks: *printStacks, + PrintCommands: *printCommands, Tags: *tags, WasmAbi: *wasmAbi, Programmer: *programmer,