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