Source file src/pkg/cmd/go/internal/run/run.go
1
2
3
4
5
6 package run
7
8 import (
9 "fmt"
10 "os"
11 "path"
12 "strings"
13
14 "cmd/go/internal/base"
15 "cmd/go/internal/cfg"
16 "cmd/go/internal/load"
17 "cmd/go/internal/str"
18 "cmd/go/internal/work"
19 )
20
21 var CmdRun = &base.Command{
22 UsageLine: "go run [build flags] [-exec xprog] package [arguments...]",
23 Short: "compile and run Go program",
24 Long: `
25 Run compiles and runs the named main Go package.
26 Typically the package is specified as a list of .go source files from a single directory,
27 but it may also be an import path, file system path, or pattern
28 matching a single known package, as in 'go run .' or 'go run my/cmd'.
29
30 By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
31 If the -exec flag is given, 'go run' invokes the binary using xprog:
32 'xprog a.out arguments...'.
33 If the -exec flag is not given, GOOS or GOARCH is different from the system
34 default, and a program named go_$GOOS_$GOARCH_exec can be found
35 on the current search path, 'go run' invokes the binary using that program,
36 for example 'go_nacl_386_exec a.out arguments...'. This allows execution of
37 cross-compiled programs when a simulator or other execution method is
38 available.
39
40 The exit status of Run is not the exit status of the compiled binary.
41
42 For more about build flags, see 'go help build'.
43 For more about specifying packages, see 'go help packages'.
44
45 See also: go build.
46 `,
47 }
48
49 func init() {
50 CmdRun.Run = runRun
51
52 work.AddBuildFlags(CmdRun)
53 CmdRun.Flag.Var((*base.StringsFlag)(&work.ExecCmd), "exec", "")
54 }
55
56 func printStderr(args ...interface{}) (int, error) {
57 return fmt.Fprint(os.Stderr, args...)
58 }
59
60 func runRun(cmd *base.Command, args []string) {
61 work.BuildInit()
62 var b work.Builder
63 b.Init()
64 b.Print = printStderr
65 i := 0
66 for i < len(args) && strings.HasSuffix(args[i], ".go") {
67 i++
68 }
69 var p *load.Package
70 if i > 0 {
71 files := args[:i]
72 for _, file := range files {
73 if strings.HasSuffix(file, "_test.go") {
74
75
76 base.Fatalf("go run: cannot run *_test.go files (%s)", file)
77 }
78 }
79 p = load.GoFilesPackage(files)
80 } else if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
81 pkgs := load.PackagesAndErrors(args[:1])
82 if len(pkgs) == 0 {
83 base.Fatalf("go run: no packages loaded from %s", args[0])
84 }
85 if len(pkgs) > 1 {
86 var names []string
87 for _, p := range pkgs {
88 names = append(names, p.ImportPath)
89 }
90 base.Fatalf("go run: pattern %s matches multiple packages:\n\t%s", args[0], strings.Join(names, "\n\t"))
91 }
92 p = pkgs[0]
93 i++
94 } else {
95 base.Fatalf("go run: no go files listed")
96 }
97 cmdArgs := args[i:]
98 if p.Error != nil {
99 base.Fatalf("%s", p.Error)
100 }
101
102 p.Internal.OmitDebug = true
103 if len(p.DepsErrors) > 0 {
104
105
106
107
108 printed := map[*load.PackageError]bool{}
109 for _, err := range p.DepsErrors {
110 if !printed[err] {
111 printed[err] = true
112 base.Errorf("%s", err)
113 }
114 }
115 }
116 base.ExitIfErrors()
117 if p.Name != "main" {
118 base.Fatalf("go run: cannot run non-main package")
119 }
120 p.Target = ""
121 if p.Internal.CmdlineFiles {
122
123 var src string
124 if len(p.GoFiles) > 0 {
125 src = p.GoFiles[0]
126 } else if len(p.CgoFiles) > 0 {
127 src = p.CgoFiles[0]
128 } else {
129
130
131 hint := ""
132 if !cfg.BuildContext.CgoEnabled {
133 hint = " (cgo is disabled)"
134 }
135 base.Fatalf("go run: no suitable source files%s", hint)
136 }
137 p.Internal.ExeName = src[:len(src)-len(".go")]
138 } else {
139 p.Internal.ExeName = path.Base(p.ImportPath)
140 }
141 a1 := b.LinkAction(work.ModeBuild, work.ModeBuild, p)
142 a := &work.Action{Mode: "go run", Func: buildRunProgram, Args: cmdArgs, Deps: []*work.Action{a1}}
143 b.Do(a)
144 }
145
146
147
148 func buildRunProgram(b *work.Builder, a *work.Action) error {
149 cmdline := str.StringList(work.FindExecCmd(), a.Deps[0].Target, a.Args)
150 if cfg.BuildN || cfg.BuildX {
151 b.Showcmd("", "%s", strings.Join(cmdline, " "))
152 if cfg.BuildN {
153 return nil
154 }
155 }
156
157 base.RunStdin(cmdline)
158 return nil
159 }
160
View as plain text