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