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