github.com/neilgarb/delve@v1.9.2-nobreaks/pkg/gobuild/gobuild.go (about) 1 // Package gobuild provides utilities for building programs and tests 2 // for the debugging session. 3 package gobuild 4 5 import ( 6 "fmt" 7 "os" 8 "os/exec" 9 "runtime" 10 "strings" 11 "time" 12 13 "github.com/go-delve/delve/pkg/config" 14 ) 15 16 // Remove the file at path and issue a warning to stderr if this fails. 17 // This can be used to remove the temporary binary generated for the session. 18 func Remove(path string) { 19 var err error 20 for i := 0; i < 20; i++ { 21 err = os.Remove(path) 22 // Open files can be removed on Unix, but not on Windows, where there also appears 23 // to be a delay in releasing the binary when the process exits. 24 // Leaving temporary files behind can be annoying to users, so we try again. 25 if err == nil || runtime.GOOS != "windows" { 26 break 27 } 28 time.Sleep(1 * time.Millisecond) 29 } 30 if err != nil { 31 fmt.Fprintf(os.Stderr, "could not remove %v: %v\n", path, err) 32 } 33 } 34 35 // GoBuild builds non-test files in 'pkgs' with the specified 'buildflags' 36 // and writes the output at 'debugname'. 37 func GoBuild(debugname string, pkgs []string, buildflags string) error { 38 args := goBuildArgs(debugname, pkgs, buildflags, false) 39 return gocommandRun("build", args...) 40 } 41 42 // GoBuildCombinedOutput builds non-test files in 'pkgs' with the specified 'buildflags' 43 // and writes the output at 'debugname'. 44 func GoBuildCombinedOutput(debugname string, pkgs []string, buildflags string) (string, []byte, error) { 45 args := goBuildArgs(debugname, pkgs, buildflags, false) 46 return gocommandCombinedOutput("build", args...) 47 } 48 49 // GoTestBuild builds test files 'pkgs' with the specified 'buildflags' 50 // and writes the output at 'debugname'. 51 func GoTestBuild(debugname string, pkgs []string, buildflags string) error { 52 args := goBuildArgs(debugname, pkgs, buildflags, true) 53 return gocommandRun("test", args...) 54 } 55 56 // GoTestBuildCombinedOutput builds test files 'pkgs' with the specified 'buildflags' 57 // and writes the output at 'debugname'. 58 func GoTestBuildCombinedOutput(debugname string, pkgs []string, buildflags string) (string, []byte, error) { 59 args := goBuildArgs(debugname, pkgs, buildflags, true) 60 return gocommandCombinedOutput("test", args...) 61 } 62 63 func goBuildArgs(debugname string, pkgs []string, buildflags string, isTest bool) []string { 64 args := []string{"-o", debugname} 65 if isTest { 66 args = append([]string{"-c"}, args...) 67 } 68 args = append(args, "-gcflags", "all=-N -l") 69 if buildflags != "" { 70 args = append(args, config.SplitQuotedFields(buildflags, '\'')...) 71 } 72 args = append(args, pkgs...) 73 return args 74 } 75 76 func gocommandRun(command string, args ...string) error { 77 _, goBuild := gocommandExecCmd(command, args...) 78 goBuild.Stderr = os.Stdout 79 goBuild.Stdout = os.Stderr 80 return goBuild.Run() 81 } 82 83 func gocommandCombinedOutput(command string, args ...string) (string, []byte, error) { 84 buildCmd, goBuild := gocommandExecCmd(command, args...) 85 out, err := goBuild.CombinedOutput() 86 return buildCmd, out, err 87 } 88 89 func gocommandExecCmd(command string, args ...string) (string, *exec.Cmd) { 90 allargs := []string{command} 91 allargs = append(allargs, args...) 92 goBuild := exec.Command("go", allargs...) 93 return strings.Join(append([]string{"go"}, allargs...), " "), goBuild 94 }