1
2
3
4
5 package work
6
7 import (
8 "context"
9 "errors"
10 "flag"
11 "fmt"
12 "go/build"
13 "os"
14 "path/filepath"
15 "runtime"
16 "strconv"
17 "strings"
18
19 "cmd/go/internal/base"
20 "cmd/go/internal/cfg"
21 "cmd/go/internal/fsys"
22 "cmd/go/internal/load"
23 "cmd/go/internal/modload"
24 "cmd/go/internal/search"
25 "cmd/go/internal/trace"
26 "cmd/internal/pathcache"
27 )
28
29 var CmdBuild = &base.Command{
30 UsageLine: "go build [-o output] [build flags] [packages]",
31 Short: "compile packages and dependencies",
32 Long: `
33 Build compiles the packages named by the import paths,
34 along with their dependencies, but it does not install the results.
35
36 If the arguments to build are a list of .go files from a single directory,
37 build treats them as a list of source files specifying a single package.
38
39 When compiling packages, build ignores files that end in '_test.go'.
40
41 When compiling a single main package, build writes the resulting
42 executable to an output file named after the last non-major-version
43 component of the package import path. The '.exe' suffix is added
44 when writing a Windows executable.
45 So 'go build example/sam' writes 'sam' or 'sam.exe'.
46 'go build example.com/foo/v2' writes 'foo' or 'foo.exe', not 'v2.exe'.
47
48 When compiling a package from a list of .go files, the executable
49 is named after the first source file.
50 'go build ed.go rx.go' writes 'ed' or 'ed.exe'.
51
52 When compiling multiple packages or a single non-main package,
53 build compiles the packages but discards the resulting object,
54 serving only as a check that the packages can be built.
55
56 The -o flag forces build to write the resulting executable or object
57 to the named output file or directory, instead of the default behavior described
58 in the last two paragraphs. If the named output is an existing directory or
59 ends with a slash or backslash, then any resulting executables
60 will be written to that directory.
61
62 The build flags are shared by the build, clean, get, install, list, run,
63 and test commands:
64
65 -C dir
66 Change to dir before running the command.
67 Any files named on the command line are interpreted after
68 changing directories.
69 If used, this flag must be the first one in the command line.
70 -a
71 force rebuilding of packages that are already up-to-date.
72 -n
73 print the commands but do not run them.
74 -p n
75 the number of programs, such as build commands or
76 test binaries, that can be run in parallel.
77 The default is GOMAXPROCS, normally the number of CPUs available.
78 -race
79 enable data race detection.
80 Supported only on darwin/amd64, darwin/arm64, freebsd/amd64, linux/amd64,
81 linux/arm64 (only for 48-bit VMA), linux/ppc64le, linux/riscv64 and
82 windows/amd64.
83 -msan
84 enable interoperation with memory sanitizer.
85 Supported only on linux/amd64, linux/arm64, linux/loong64, freebsd/amd64
86 and only with Clang/LLVM as the host C compiler.
87 PIE build mode will be used on all platforms except linux/amd64.
88 -asan
89 enable interoperation with address sanitizer.
90 Supported only on linux/arm64, linux/amd64, linux/loong64.
91 Supported on linux/amd64 or linux/arm64 and only with GCC 7 and higher
92 or Clang/LLVM 9 and higher.
93 And supported on linux/loong64 only with Clang/LLVM 16 and higher.
94 -cover
95 enable code coverage instrumentation.
96 -covermode set,count,atomic
97 set the mode for coverage analysis.
98 The default is "set" unless -race is enabled,
99 in which case it is "atomic".
100 The values:
101 set: bool: does this statement run?
102 count: int: how many times does this statement run?
103 atomic: int: count, but correct in multithreaded tests;
104 significantly more expensive.
105 Sets -cover.
106 -coverpkg pattern1,pattern2,pattern3
107 For a build that targets package 'main' (e.g. building a Go
108 executable), apply coverage analysis to each package whose
109 import path matches the patterns. The default is to apply
110 coverage analysis to packages in the main Go module. See
111 'go help packages' for a description of package patterns.
112 Sets -cover.
113 -v
114 print the names of packages as they are compiled.
115 -work
116 print the name of the temporary work directory and
117 do not delete it when exiting.
118 -x
119 print the commands.
120 -asmflags '[pattern=]arg list'
121 arguments to pass on each go tool asm invocation.
122 -buildmode mode
123 build mode to use. See 'go help buildmode' for more.
124 -buildvcs
125 Whether to stamp binaries with version control information
126 ("true", "false", or "auto"). By default ("auto"), version control
127 information is stamped into a binary if the main package, the main module
128 containing it, and the current directory are all in the same repository.
129 Use -buildvcs=false to always omit version control information, or
130 -buildvcs=true to error out if version control information is available but
131 cannot be included due to a missing tool or ambiguous directory structure.
132 -compiler name
133 name of compiler to use, as in runtime.Compiler (gccgo or gc).
134 -gccgoflags '[pattern=]arg list'
135 arguments to pass on each gccgo compiler/linker invocation.
136 -gcflags '[pattern=]arg list'
137 arguments to pass on each go tool compile invocation.
138 -installsuffix suffix
139 a suffix to use in the name of the package installation directory,
140 in order to keep output separate from default builds.
141 If using the -race flag, the install suffix is automatically set to race
142 or, if set explicitly, has _race appended to it. Likewise for the -msan
143 and -asan flags. Using a -buildmode option that requires non-default compile
144 flags has a similar effect.
145 -json
146 Emit build output in JSON suitable for automated processing.
147 See 'go help buildjson' for the encoding details.
148 -ldflags '[pattern=]arg list'
149 arguments to pass on each go tool link invocation.
150 -linkshared
151 build code that will be linked against shared libraries previously
152 created with -buildmode=shared.
153 -mod mode
154 module download mode to use: readonly, vendor, or mod.
155 By default, if a vendor directory is present and the go version in go.mod
156 is 1.14 or higher, the go command acts as if -mod=vendor were set.
157 Otherwise, the go command acts as if -mod=readonly were set.
158 See https://go.dev/ref/mod#build-commands for details.
159 -modcacherw
160 leave newly-created directories in the module cache read-write
161 instead of making them read-only.
162 -modfile file
163 in module aware mode, read (and possibly write) an alternate go.mod
164 file instead of the one in the module root directory. A file named
165 "go.mod" must still be present in order to determine the module root
166 directory, but it is not accessed. When -modfile is specified, an
167 alternate go.sum file is also used: its path is derived from the
168 -modfile flag by trimming the ".mod" extension and appending ".sum".
169 -overlay file
170 read a JSON config file that provides an overlay for build operations.
171 The file is a JSON object with a single field, named 'Replace', that
172 maps each disk file path (a string) to its backing file path, so that
173 a build will run as if the disk file path exists with the contents
174 given by the backing file paths, or as if the disk file path does not
175 exist if its backing file path is empty. Support for the -overlay flag
176 has some limitations: importantly, cgo files included from outside the
177 include path must be in the same directory as the Go package they are
178 included from, overlays will not appear when binaries and tests are
179 run through go run and go test respectively, and files beneath
180 GOMODCACHE may not be replaced.
181 -pgo file
182 specify the file path of a profile for profile-guided optimization (PGO).
183 When the special name "auto" is specified, for each main package in the
184 build, the go command selects a file named "default.pgo" in the package's
185 directory if that file exists, and applies it to the (transitive)
186 dependencies of the main package (other packages are not affected).
187 Special name "off" turns off PGO. The default is "auto".
188 -pkgdir dir
189 install and load all packages from dir instead of the usual locations.
190 For example, when building with a non-standard configuration,
191 use -pkgdir to keep generated packages in a separate location.
192 -tags tag,list
193 a comma-separated list of additional build tags to consider satisfied
194 during the build. For more information about build tags, see
195 'go help buildconstraint'. (Earlier versions of Go used a
196 space-separated list, and that form is deprecated but still recognized.)
197 -trimpath
198 remove all file system paths from the resulting executable.
199 Instead of absolute file system paths, the recorded file names
200 will begin either a module path@version (when using modules),
201 or a plain import path (when using the standard library, or GOPATH).
202 -toolexec 'cmd args'
203 a program to use to invoke toolchain programs like vet and asm.
204 For example, instead of running asm, the go command will run
205 'cmd args /path/to/asm <arguments for asm>'.
206 The TOOLEXEC_IMPORTPATH environment variable will be set,
207 matching 'go list -f {{.ImportPath}}' for the package being built.
208
209 The -asmflags, -gccgoflags, -gcflags, and -ldflags flags accept a
210 space-separated list of arguments to pass to an underlying tool
211 during the build. To embed spaces in an element in the list, surround
212 it with either single or double quotes. The argument list may be
213 preceded by a package pattern and an equal sign, which restricts
214 the use of that argument list to the building of packages matching
215 that pattern (see 'go help packages' for a description of package
216 patterns). Without a pattern, the argument list applies only to the
217 packages named on the command line. The flags may be repeated
218 with different patterns in order to specify different arguments for
219 different sets of packages. If a package matches patterns given in
220 multiple flags, the latest match on the command line wins.
221 For example, 'go build -gcflags=-S fmt' prints the disassembly
222 only for package fmt, while 'go build -gcflags=all=-S fmt'
223 prints the disassembly for fmt and all its dependencies.
224
225 For more about specifying packages, see 'go help packages'.
226 For more about where binaries are installed, run 'go help gopath'.
227 For more about calling between Go and C/C++, run 'go help c'.
228 For more about project organization, run 'go help modules'.
229
230 Note: go build adheres to certain conventions for organizing projects:
231 it primarily supports go modules (see 'go help modules') while
232 also supporting an alternative GOPATH mode (see 'go help gopath').
233 Not all projects can follow these conventions,
234 however. Installations that have their own conventions or that use
235 a separate software build system may choose to use lower-level
236 invocations such as 'go tool compile' and 'go tool link' to avoid
237 some of the overheads and design decisions of the build tool.
238
239 See also: go install, go get, go clean.
240 `,
241 }
242
243 func init() {
244
245 CmdBuild.Run = runBuild
246 CmdInstall.Run = runInstall
247
248 CmdBuild.Flag.StringVar(&cfg.BuildO, "o", "", "output file or directory")
249
250 AddBuildFlags(CmdBuild, DefaultBuildFlags)
251 AddBuildFlags(CmdInstall, DefaultBuildFlags)
252 AddCoverFlags(CmdBuild, nil)
253 AddCoverFlags(CmdInstall, nil)
254 }
255
256
257
258
259 var (
260 forcedAsmflags []string
261 forcedGcflags []string
262 forcedLdflags []string
263 forcedGccgoflags []string
264 )
265
266 var (
267 BuildToolchain toolchain = noToolchain{}
268 ldBuildmode string
269 )
270
271
272
273
274 type buildCompiler struct{}
275
276 func (c buildCompiler) Set(value string) error {
277 switch value {
278 case "gc":
279 BuildToolchain = gcToolchain{}
280 case "gccgo":
281 BuildToolchain = gccgoToolchain{}
282 default:
283 return fmt.Errorf("unknown compiler %q", value)
284 }
285 cfg.BuildToolchainName = value
286 cfg.BuildContext.Compiler = value
287 return nil
288 }
289
290 func (c buildCompiler) String() string {
291 return cfg.BuildContext.Compiler
292 }
293
294 func init() {
295 switch build.Default.Compiler {
296 case "gc", "gccgo":
297 buildCompiler{}.Set(build.Default.Compiler)
298 }
299 }
300
301 type BuildFlagMask int
302
303 const (
304 DefaultBuildFlags BuildFlagMask = 0
305 OmitModFlag BuildFlagMask = 1 << iota
306 OmitModCommonFlags
307 OmitVFlag
308 OmitBuildOnlyFlags
309 OmitJSONFlag
310 )
311
312
313
314 func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) {
315 base.AddBuildFlagsNX(&cmd.Flag)
316 base.AddChdirFlag(&cmd.Flag)
317 cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "force rebuilding of packages that are already up-to-date")
318 cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "the number of programs, such as build commands or test binaries, that can be run in parallel")
319 if mask&OmitVFlag == 0 {
320 cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "print the names of packages as they are compiled")
321 }
322
323 cmd.Flag.BoolVar(&cfg.BuildASan, "asan", false, "enable interoperation with address sanitizer")
324 cmd.Flag.Var(&load.BuildAsmflags, "asmflags", "`arguments` to pass on each go tool asm invocation")
325 cmd.Flag.Var(buildCompiler{}, "compiler", "`name` of compiler to use, as in runtime.Compiler: gccgo, gc")
326 cmd.Flag.StringVar(&cfg.BuildBuildmode, "buildmode", "default", "build `mode` to use; see 'go help buildmode' for details: archive, c-archive, c-shared, default, shared, exe, pie, plugin")
327 cmd.Flag.Var((*buildvcsFlag)(&cfg.BuildBuildvcs), "buildvcs", "whether to stamp binaries with version control information: true, false, auto")
328 cmd.Flag.Var(&load.BuildGcflags, "gcflags", "`arguments` to pass on each go tool compile invocation")
329 cmd.Flag.Var(&load.BuildGccgoflags, "gccgoflags", "`arguments` to pass on each gccgo compiler/linker invocation")
330 if mask&OmitModFlag == 0 {
331 base.AddModFlag(&cmd.Flag)
332 }
333 if mask&OmitModCommonFlags == 0 {
334 base.AddModCommonFlags(&cmd.Flag)
335 } else {
336
337
338
339 cmd.Flag.StringVar(&fsys.OverlayFile, "overlay", "", "read a JSON config `file` that provides an overlay for build operations")
340 }
341 cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "a `suffix` to use in the name of the package installation directory, to keep output separate from default builds")
342 if mask&(OmitBuildOnlyFlags|OmitJSONFlag) == 0 {
343
344
345
346
347 cmd.Flag.BoolVar(&cfg.BuildJSON, "json", false, "emit build output in JSON suitable for automated processing; see 'go help buildjson'")
348 }
349 cmd.Flag.Var(&load.BuildLdflags, "ldflags", "`arguments` to pass on each go tool link invocation")
350 cmd.Flag.BoolVar(&cfg.BuildLinkshared, "linkshared", false, "build code that will be linked against shared libraries previously created with -buildmode=shared")
351 cmd.Flag.BoolVar(&cfg.BuildMSan, "msan", false, "enable interoperation with memory sanitizer")
352 cmd.Flag.StringVar(&cfg.BuildPGO, "pgo", "auto", "specify the `file` path of a profile for profile-guided optimization (PGO); special name \"auto\" selects default.pgo, \"off\" turns off PGO")
353 cmd.Flag.StringVar(&cfg.BuildPkgdir, "pkgdir", "", "install and load all packages from `dir` instead of the usual locations")
354 cmd.Flag.BoolVar(&cfg.BuildRace, "race", false, "enable data race detection")
355 cmd.Flag.Var((*tagsFlag)(&cfg.BuildContext.BuildTags), "tags", "a comma-separated list of additional build `tags` to consider satisfied during the build")
356 cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildToolexec), "toolexec", "a `program` to use to invoke toolchain programs like vet and asm; see 'go help build'")
357 cmd.Flag.BoolVar(&cfg.BuildTrimpath, "trimpath", false, "remove all file system paths from the resulting executable")
358 cmd.Flag.BoolVar(&cfg.BuildWork, "work", false, "print the name of the temporary work directory and do not delete it when exiting")
359
360
361 cmd.Flag.StringVar(&cfg.DebugActiongraph, "debug-actiongraph", "", "")
362 cmd.Flag.StringVar(&cfg.DebugRuntimeTrace, "debug-runtime-trace", "", "")
363 cmd.Flag.StringVar(&cfg.DebugTrace, "debug-trace", "", "")
364 }
365
366
367
368
369 func AddCoverFlags(cmd *base.Command, coverProfileFlag *string) {
370 cmd.Flag.BoolVar(&cfg.BuildCover, "cover", false, "enable code coverage instrumentation")
371 cmd.Flag.Var(coverFlag{(*coverModeFlag)(&cfg.BuildCoverMode)}, "covermode", "set the `mode` for coverage analysis: set, count, atomic")
372 cmd.Flag.Var(coverFlag{commaListFlag{&cfg.BuildCoverPkg}}, "coverpkg", "apply coverage analysis to each package whose import path matches the `patterns`")
373 if coverProfileFlag != nil {
374 cmd.Flag.Var(coverFlag{V: stringFlag{coverProfileFlag}}, "coverprofile", "write a coverage profile to `file`")
375 }
376 }
377
378
379 type tagsFlag []string
380
381 func (v *tagsFlag) Set(s string) error {
382
383 if strings.Contains(s, " ") || strings.Contains(s, "'") {
384 return (*base.StringsFlag)(v).Set(s)
385 }
386
387
388 *v = []string{}
389 for s := range strings.SplitSeq(s, ",") {
390 if s != "" {
391 *v = append(*v, s)
392 }
393 }
394 return nil
395 }
396
397 func (v *tagsFlag) String() string {
398 return "<TagsFlag>"
399 }
400
401
402 type buildvcsFlag string
403
404 func (f *buildvcsFlag) IsBoolFlag() bool { return true }
405
406 func (f *buildvcsFlag) Set(s string) error {
407
408
409 if s == "" || s == "auto" {
410 *f = "auto"
411 return nil
412 }
413
414 b, err := strconv.ParseBool(s)
415 if err != nil {
416 return errors.New("value is neither 'auto' nor a valid bool")
417 }
418 *f = buildvcsFlag(strconv.FormatBool(b))
419 return nil
420 }
421
422 func (f *buildvcsFlag) String() string { return string(*f) }
423
424
425
426
427 func fileExtSplit(file string) (name, ext string) {
428 dotExt := filepath.Ext(file)
429 name = file[:len(file)-len(dotExt)]
430 if dotExt != "" {
431 ext = dotExt[1:]
432 }
433 return
434 }
435
436 func pkgsMain(pkgs []*load.Package) (res []*load.Package) {
437 for _, p := range pkgs {
438 if p.Name == "main" {
439 res = append(res, p)
440 }
441 }
442 return res
443 }
444
445 func pkgsNotMain(pkgs []*load.Package) (res []*load.Package) {
446 for _, p := range pkgs {
447 if p.Name != "main" {
448 res = append(res, p)
449 }
450 }
451 return res
452 }
453
454 func oneMainPkg(pkgs []*load.Package) []*load.Package {
455 if len(pkgs) != 1 || pkgs[0].Name != "main" {
456 base.Fatalf("-buildmode=%s requires exactly one main package", cfg.BuildBuildmode)
457 }
458 return pkgs
459 }
460
461 var pkgsFilter = func(pkgs []*load.Package) []*load.Package { return pkgs }
462
463 func runBuild(ctx context.Context, cmd *base.Command, args []string) {
464 moduleLoader := modload.NewLoader()
465 moduleLoader.InitWorkfile()
466 BuildInit(moduleLoader)
467 b := NewBuilder("", moduleLoader.VendorDirOrEmpty)
468 defer func() {
469 if err := b.Close(); err != nil {
470 base.Fatal(err)
471 }
472 }()
473
474 pkgs := load.PackagesAndErrors(moduleLoader, ctx, load.PackageOpts{AutoVCS: true}, args)
475 load.CheckPackageErrors(pkgs)
476
477 explicitO := len(cfg.BuildO) > 0
478
479 if len(pkgs) == 1 && pkgs[0].Name == "main" && cfg.BuildO == "" {
480 cfg.BuildO = pkgs[0].DefaultExecName()
481 cfg.BuildO += cfg.ExeSuffix
482 }
483
484
485 switch cfg.BuildContext.Compiler {
486 case "gccgo":
487 if load.BuildGcflags.Present() {
488 fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
489 }
490 if load.BuildLdflags.Present() {
491 fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
492 }
493 case "gc":
494 if load.BuildGccgoflags.Present() {
495 fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
496 }
497 }
498
499 depMode := ModeBuild
500
501 pkgs = omitTestOnly(pkgsFilter(pkgs))
502
503
504 if base.IsNull(cfg.BuildO) {
505 cfg.BuildO = ""
506 }
507
508 if cfg.BuildCover {
509 load.PrepareForCoverageBuild(moduleLoader, pkgs)
510 }
511
512 if cfg.BuildO != "" {
513
514
515
516
517 if fi, err := os.Stat(cfg.BuildO); (err == nil && fi.IsDir()) ||
518 strings.HasSuffix(cfg.BuildO, "/") ||
519 strings.HasSuffix(cfg.BuildO, string(os.PathSeparator)) {
520 if !explicitO {
521 base.Fatalf("go: build output %q already exists and is a directory", cfg.BuildO)
522 }
523 a := &Action{Mode: "go build"}
524 for _, p := range pkgs {
525 if p.Name != "main" {
526 continue
527 }
528
529 p.Target = filepath.Join(cfg.BuildO, p.DefaultExecName())
530 p.Target += cfg.ExeSuffix
531 p.Stale = true
532 p.StaleReason = "build -o flag in use"
533 a.Deps = append(a.Deps, b.AutoAction(moduleLoader, ModeInstall, depMode, p))
534 }
535 if len(a.Deps) == 0 {
536 base.Fatalf("go: no main packages to build")
537 }
538 b.Do(ctx, a)
539 return
540 }
541 if len(pkgs) > 1 {
542 base.Fatalf("go: cannot write multiple packages to non-directory %s", cfg.BuildO)
543 } else if len(pkgs) == 0 {
544 base.Fatalf("no packages to build")
545 }
546 p := pkgs[0]
547 p.Target = cfg.BuildO
548 p.Stale = true
549 p.StaleReason = "build -o flag in use"
550 a := b.AutoAction(moduleLoader, ModeInstall, depMode, p)
551 b.Do(ctx, a)
552 return
553 }
554
555 a := &Action{Mode: "go build"}
556 for _, p := range pkgs {
557 a.Deps = append(a.Deps, b.AutoAction(moduleLoader, ModeBuild, depMode, p))
558 }
559 if cfg.BuildBuildmode == "shared" {
560 a = b.buildmodeShared(moduleLoader, ModeBuild, depMode, args, pkgs, a)
561 }
562 b.Do(ctx, a)
563 }
564
565 var CmdInstall = &base.Command{
566 UsageLine: "go install [build flags] [packages]",
567 Short: "compile and install packages and dependencies",
568 Long: `
569 Install compiles and installs the packages named by the import paths.
570
571 Executables are installed in the directory named by the GOBIN environment
572 variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH
573 environment variable is not set. Executables in $GOROOT
574 are installed in $GOROOT/bin or $GOTOOLDIR instead of $GOBIN.
575 Cross compiled binaries are installed in $GOOS_$GOARCH subdirectories
576 of the above.
577
578 If the arguments have version suffixes (like @latest or @v1.0.0), "go install"
579 builds packages in module-aware mode, ignoring the go.mod file in the current
580 directory or any parent directory, if there is one. This is useful for
581 installing executables without affecting the dependencies of the main module.
582 To eliminate ambiguity about which module versions are used in the build, the
583 arguments must satisfy the following constraints:
584
585 - Arguments must be package paths or package patterns (with "..." wildcards).
586 They must not be standard packages (like fmt), meta-patterns (std, cmd,
587 all), or relative or absolute file paths.
588
589 - All arguments must have the same version suffix. Different queries are not
590 allowed, even if they refer to the same version.
591
592 - All arguments must refer to packages in the same module at the same version.
593
594 - Package path arguments must refer to main packages. Pattern arguments
595 will only match main packages.
596
597 - No module is considered the "main" module. If the module containing
598 packages named on the command line has a go.mod file, it must not contain
599 directives (replace and exclude) that would cause it to be interpreted
600 differently than if it were the main module. The module must not require
601 a higher version of itself.
602
603 - Vendor directories are not used in any module. (Vendor directories are not
604 included in the module zip files downloaded by 'go install'.)
605
606 If the arguments don't have version suffixes, "go install" may run in
607 module-aware mode or GOPATH mode, depending on the GO111MODULE environment
608 variable and the presence of a go.mod file. See 'go help modules' for details.
609 If module-aware mode is enabled, "go install" runs in the context of the main
610 module.
611
612 When module-aware mode is disabled, non-main packages are installed in the
613 directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled,
614 non-main packages are built and cached but not installed.
615
616 Before Go 1.20, the standard library was installed to
617 $GOROOT/pkg/$GOOS_$GOARCH.
618 Starting in Go 1.20, the standard library is built and cached but not installed.
619 Setting GODEBUG=installgoroot=all restores the use of
620 $GOROOT/pkg/$GOOS_$GOARCH.
621
622 For more about build flags, see 'go help build'.
623
624 For more about specifying packages, see 'go help packages'.
625
626 See also: go build, go get, go clean.
627 `,
628 }
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650 func libname(args []string, pkgs []*load.Package) (string, error) {
651 var libname string
652 appendName := func(arg string) {
653 if libname == "" {
654 libname = arg
655 } else {
656 libname += "," + arg
657 }
658 }
659 var haveNonMeta bool
660 for _, arg := range args {
661 if search.IsMetaPackage(arg) {
662 appendName(arg)
663 } else {
664 haveNonMeta = true
665 }
666 }
667 if len(libname) == 0 {
668 if len(args) == 1 && strings.HasSuffix(args[0], "/...") {
669
670 arg := strings.TrimSuffix(args[0], "/...")
671 if build.IsLocalImport(arg) {
672 cwd, _ := os.Getwd()
673 bp, _ := cfg.BuildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
674 if bp.ImportPath != "" && bp.ImportPath != "." {
675 arg = bp.ImportPath
676 }
677 }
678 appendName(strings.ReplaceAll(arg, "/", "-"))
679 } else {
680 for _, pkg := range pkgs {
681 appendName(strings.ReplaceAll(pkg.ImportPath, "/", "-"))
682 }
683 }
684 } else if haveNonMeta {
685 return "", errors.New("mixing of meta and non-meta packages is not allowed")
686 }
687
688
689 return "lib" + libname + ".so", nil
690 }
691
692 func runInstall(ctx context.Context, cmd *base.Command, args []string) {
693 moduleLoader := modload.NewLoader()
694 for _, arg := range args {
695 if strings.Contains(arg, "@") && !build.IsLocalImport(arg) && !filepath.IsAbs(arg) {
696 installOutsideModule(moduleLoader, ctx, args)
697 return
698 }
699 }
700
701 moduleLoader.InitWorkfile()
702 BuildInit(moduleLoader)
703 pkgs := load.PackagesAndErrors(moduleLoader, ctx, load.PackageOpts{AutoVCS: true}, args)
704 if cfg.ModulesEnabled && !moduleLoader.HasModRoot() {
705 haveErrors := false
706 allMissingErrors := true
707 for _, pkg := range pkgs {
708 if pkg.Error == nil {
709 continue
710 }
711 haveErrors = true
712 if _, ok := errors.AsType[*modload.ImportMissingError](pkg.Error); !ok {
713 allMissingErrors = false
714 break
715 }
716 }
717 if haveErrors && allMissingErrors {
718 latestArgs := make([]string, len(args))
719 for i := range args {
720 latestArgs[i] = args[i] + "@latest"
721 }
722 hint := strings.Join(latestArgs, " ")
723 base.Fatalf("go: 'go install' requires a version when current directory is not in a module\n\tTry 'go install %s' to install the latest version", hint)
724 }
725 }
726 load.CheckPackageErrors(pkgs)
727
728 if cfg.BuildCover {
729 load.PrepareForCoverageBuild(moduleLoader, pkgs)
730 }
731
732 InstallPackages(moduleLoader, ctx, args, pkgs)
733 }
734
735
736 func omitTestOnly(pkgs []*load.Package) []*load.Package {
737 var list []*load.Package
738 for _, p := range pkgs {
739 if len(p.GoFiles)+len(p.CgoFiles) == 0 && !p.Internal.CmdlinePkgLiteral {
740
741
742
743
744
745 continue
746 }
747 list = append(list, p)
748 }
749 return list
750 }
751
752 func InstallPackages(ld *modload.Loader, ctx context.Context, patterns []string, pkgs []*load.Package) {
753 ctx, span := trace.StartSpan(ctx, "InstallPackages "+strings.Join(patterns, " "))
754 defer span.Done()
755
756 if cfg.GOBIN != "" && !filepath.IsAbs(cfg.GOBIN) {
757 base.Fatalf("cannot install, GOBIN must be an absolute path")
758 }
759
760 pkgs = omitTestOnly(pkgsFilter(pkgs))
761 for _, p := range pkgs {
762 if p.Target == "" {
763 switch {
764 case p.Name != "main" && p.Internal.Local && p.ConflictDir == "":
765
766
767
768
769 case p.Name != "main" && p.Module != nil:
770
771 case p.Name != "main" && p.Standard && p.Internal.Build.PkgObj == "":
772
773
774
775
776 case p.Internal.GobinSubdir:
777 base.Errorf("go: cannot install cross-compiled binaries when GOBIN is set")
778 case p.Internal.CmdlineFiles:
779 base.Errorf("go: no install location for .go files listed on command line (GOBIN not set)")
780 case p.ConflictDir != "":
781 base.Errorf("go: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
782 default:
783 base.Errorf("go: no install location for directory %s outside GOPATH\n"+
784 "\tFor more details see: 'go help gopath'", p.Dir)
785 }
786 }
787 }
788 base.ExitIfErrors()
789
790 b := NewBuilder("", ld.VendorDirOrEmpty)
791 defer func() {
792 if err := b.Close(); err != nil {
793 base.Fatal(err)
794 }
795 }()
796
797 depMode := ModeBuild
798 a := &Action{Mode: "go install"}
799 var tools []*Action
800 for _, p := range pkgs {
801
802
803
804 a1 := b.AutoAction(ld, ModeInstall, depMode, p)
805 if load.InstallTargetDir(p) == load.ToTool {
806 a.Deps = append(a.Deps, a1.Deps...)
807 a1.Deps = append(a1.Deps, a)
808 tools = append(tools, a1)
809 continue
810 }
811 a.Deps = append(a.Deps, a1)
812 }
813 if len(tools) > 0 {
814 a = &Action{
815 Mode: "go install (tools)",
816 Deps: tools,
817 }
818 }
819
820 if cfg.BuildBuildmode == "shared" {
821
822
823
824
825
826 a = b.buildmodeShared(ld, ModeInstall, ModeInstall, patterns, pkgs, a)
827 }
828
829 b.Do(ctx, a)
830 base.ExitIfErrors()
831
832
833
834
835
836
837
838
839
840
841 if len(patterns) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
842
843
844 targ := pkgs[0].DefaultExecName()
845 targ += cfg.ExeSuffix
846 if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target {
847 fi, err := os.Stat(targ)
848 if err == nil {
849 m := fi.Mode()
850 if m.IsRegular() {
851 if m&0111 != 0 || cfg.Goos == "windows" {
852 os.Remove(targ)
853 }
854 }
855 }
856 }
857 }
858 }
859
860
861
862
863
864
865 func installOutsideModule(ld *modload.Loader, ctx context.Context, args []string) {
866 ld.ForceUseModules = true
867 ld.RootMode = modload.NoRoot
868 ld.AllowMissingModuleImports()
869 modload.Init(ld)
870 BuildInit(ld)
871
872
873
874
875
876
877
878 pkgOpts := load.PackageOpts{MainOnly: true}
879 pkgs, err := load.PackagesAndErrorsOutsideModule(ld, ctx, pkgOpts, args)
880 if err != nil {
881 base.Fatal(err)
882 }
883 load.CheckPackageErrors(pkgs)
884 patterns := make([]string, len(args))
885 for i, arg := range args {
886 patterns[i] = arg[:strings.Index(arg, "@")]
887 }
888
889
890 InstallPackages(ld, ctx, patterns, pkgs)
891 }
892
893
894
895
896
897
898
899 var ExecCmd []string
900
901
902
903 func FindExecCmd() []string {
904 if ExecCmd != nil {
905 return ExecCmd
906 }
907 ExecCmd = []string{}
908 if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH {
909 return ExecCmd
910 }
911 path, err := pathcache.LookPath(fmt.Sprintf("go_%s_%s_exec", cfg.Goos, cfg.Goarch))
912 if err == nil {
913 ExecCmd = []string{path}
914 }
915 return ExecCmd
916 }
917
918
919 type coverFlag struct{ V flag.Value }
920
921 func (f coverFlag) String() string {
922 if f.V == nil {
923 return ""
924 }
925 return f.V.String()
926 }
927
928 func (f coverFlag) Set(value string) error {
929 if err := f.V.Set(value); err != nil {
930 return err
931 }
932 cfg.BuildCover = true
933 return nil
934 }
935
936 type coverModeFlag string
937
938 func (f coverModeFlag) String() string { return string(f) }
939 func (f *coverModeFlag) Set(value string) error {
940 switch value {
941 case "", "set", "count", "atomic":
942 *f = coverModeFlag(value)
943 cfg.BuildCoverMode = value
944 return nil
945 default:
946 return errors.New(`valid modes are "set", "count", or "atomic"`)
947 }
948 }
949
950
951 type commaListFlag struct{ Vals *[]string }
952
953 func (f commaListFlag) String() string { return strings.Join(*f.Vals, ",") }
954
955 func (f commaListFlag) Set(value string) error {
956 if value == "" {
957 *f.Vals = nil
958 } else {
959 *f.Vals = strings.Split(value, ",")
960 }
961 return nil
962 }
963
964
965 type stringFlag struct{ val *string }
966
967 func (f stringFlag) String() string { return *f.val }
968 func (f stringFlag) Set(value string) error {
969 *f.val = value
970 return nil
971 }
972
View as plain text