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  }