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