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://golang.org/ref/mod#build-commands for details.
159 -modcacherw
160 leave newly-created directories in the module cache read-write
161 instead of making them read-only.
162 -modfile file
163 in module aware mode, read (and possibly write) an alternate go.mod
164 file instead of the one in the module root directory. A file named
165 "go.mod" must still be present in order to determine the module root
166 directory, but it is not accessed. When -modfile is specified, an
167 alternate go.sum file is also used: its path is derived from the
168 -modfile flag by trimming the ".mod" extension and appending ".sum".
169 -overlay file
170 read a JSON config file that provides an overlay for build operations.
171 The file is a JSON object with a single field, named 'Replace', that
172 maps each disk file path (a string) to its backing file path, so that
173 a build will run as if the disk file path exists with the contents
174 given by the backing file paths, or as if the disk file path does not
175 exist if its backing file path is empty. Support for the -overlay flag
176 has some limitations: importantly, cgo files included from outside the
177 include path must be in the same directory as the Go package they are
178 included from, overlays will not appear when binaries and tests are
179 run through go run and go test respectively, and files beneath
180 GOMODCACHE may not be replaced.
181 -pgo file
182 specify the file path of a profile for profile-guided optimization (PGO).
183 When the special name "auto" is specified, for each main package in the
184 build, the go command selects a file named "default.pgo" in the package's
185 directory if that file exists, and applies it to the (transitive)
186 dependencies of the main package (other packages are not affected).
187 Special name "off" turns off PGO. The default is "auto".
188 -pkgdir dir
189 install and load all packages from dir instead of the usual locations.
190 For example, when building with a non-standard configuration,
191 use -pkgdir to keep generated packages in a separate location.
192 -tags tag,list
193 a comma-separated list of additional build tags to consider satisfied
194 during the build. For more information about build tags, see
195 'go help buildconstraint'. (Earlier versions of Go used a
196 space-separated list, and that form is deprecated but still recognized.)
197 -trimpath
198 remove all file system paths from the resulting executable.
199 Instead of absolute file system paths, the recorded file names
200 will begin either a module path@version (when using modules),
201 or a plain import path (when using the standard library, or GOPATH).
202 -toolexec 'cmd args'
203 a program to use to invoke toolchain programs like vet and asm.
204 For example, instead of running asm, the go command will run
205 'cmd args /path/to/asm <arguments for asm>'.
206 The TOOLEXEC_IMPORTPATH environment variable will be set,
207 matching 'go list -f {{.ImportPath}}' for the package being built.
208
209 The -asmflags, -gccgoflags, -gcflags, and -ldflags flags accept a
210 space-separated list of arguments to pass to an underlying tool
211 during the build. To embed spaces in an element in the list, surround
212 it with either single or double quotes. The argument list may be
213 preceded by a package pattern and an equal sign, which restricts
214 the use of that argument list to the building of packages matching
215 that pattern (see 'go help packages' for a description of package
216 patterns). Without a pattern, the argument list applies only to the
217 packages named on the command line. The flags may be repeated
218 with different patterns in order to specify different arguments for
219 different sets of packages. If a package matches patterns given in
220 multiple flags, the latest match on the command line wins.
221 For example, 'go build -gcflags=-S fmt' prints the disassembly
222 only for package fmt, while 'go build -gcflags=all=-S fmt'
223 prints the disassembly for fmt and all its dependencies.
224
225 For more about specifying packages, see 'go help packages'.
226 For more about where packages and binaries are installed,
227 run 'go help gopath'.
228 For more about calling between Go and C/C++, run 'go help c'.
229
230 Note: Build adheres to certain conventions such as those described
231 by 'go help gopath'. Not all projects can follow these conventions,
232 however. Installations that have their own conventions or that use
233 a separate software build system may choose to use lower-level
234 invocations such as 'go tool compile' and 'go tool link' to avoid
235 some of the overheads and design decisions of the build tool.
236
237 See also: go install, go get, go clean.
238 `,
239 }
240
241 const concurrentGCBackendCompilationEnabledByDefault = true
242
243 func init() {
244
245 CmdBuild.Run = runBuild
246 CmdInstall.Run = runInstall
247
248 CmdBuild.Flag.StringVar(&cfg.BuildO, "o", "", "output file or directory")
249
250 AddBuildFlags(CmdBuild, DefaultBuildFlags)
251 AddBuildFlags(CmdInstall, DefaultBuildFlags)
252 AddCoverFlags(CmdBuild, nil)
253 AddCoverFlags(CmdInstall, nil)
254 }
255
256
257
258
259 var (
260 forcedAsmflags []string
261 forcedGcflags []string
262 forcedLdflags []string
263 forcedGccgoflags []string
264 )
265
266 var 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 func AddCoverFlags(cmd *base.Command, coverProfileFlag *string) {
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 if coverProfileFlag != nil {
372 cmd.Flag.Var(coverFlag{V: stringFlag{coverProfileFlag}}, "coverprofile", "")
373 }
374 }
375
376
377 type tagsFlag []string
378
379 func (v *tagsFlag) Set(s string) error {
380
381 if strings.Contains(s, " ") || strings.Contains(s, "'") {
382 return (*base.StringsFlag)(v).Set(s)
383 }
384
385
386 *v = []string{}
387 for s := range strings.SplitSeq(s, ",") {
388 if s != "" {
389 *v = append(*v, s)
390 }
391 }
392 return nil
393 }
394
395 func (v *tagsFlag) String() string {
396 return "<TagsFlag>"
397 }
398
399
400 type buildvcsFlag string
401
402 func (f *buildvcsFlag) IsBoolFlag() bool { return true }
403
404 func (f *buildvcsFlag) Set(s string) error {
405
406
407 if s == "" || s == "auto" {
408 *f = "auto"
409 return nil
410 }
411
412 b, err := strconv.ParseBool(s)
413 if err != nil {
414 return errors.New("value is neither 'auto' nor a valid bool")
415 }
416 *f = (buildvcsFlag)(strconv.FormatBool(b))
417 return nil
418 }
419
420 func (f *buildvcsFlag) String() string { return string(*f) }
421
422
423
424
425 func fileExtSplit(file string) (name, ext string) {
426 dotExt := filepath.Ext(file)
427 name = file[:len(file)-len(dotExt)]
428 if dotExt != "" {
429 ext = dotExt[1:]
430 }
431 return
432 }
433
434 func pkgsMain(pkgs []*load.Package) (res []*load.Package) {
435 for _, p := range pkgs {
436 if p.Name == "main" {
437 res = append(res, p)
438 }
439 }
440 return res
441 }
442
443 func pkgsNotMain(pkgs []*load.Package) (res []*load.Package) {
444 for _, p := range pkgs {
445 if p.Name != "main" {
446 res = append(res, p)
447 }
448 }
449 return res
450 }
451
452 func oneMainPkg(pkgs []*load.Package) []*load.Package {
453 if len(pkgs) != 1 || pkgs[0].Name != "main" {
454 base.Fatalf("-buildmode=%s requires exactly one main package", cfg.BuildBuildmode)
455 }
456 return pkgs
457 }
458
459 var pkgsFilter = func(pkgs []*load.Package) []*load.Package { return pkgs }
460
461 func runBuild(ctx context.Context, cmd *base.Command, args []string) {
462 moduleLoaderState := modload.NewState()
463 modload.InitWorkfile(moduleLoaderState)
464 BuildInit(moduleLoaderState)
465 b := NewBuilder("", moduleLoaderState.VendorDirOrEmpty)
466 defer func() {
467 if err := b.Close(); err != nil {
468 base.Fatal(err)
469 }
470 }()
471
472 pkgs := load.PackagesAndErrors(moduleLoaderState, 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.BuildCover {
507 load.PrepareForCoverageBuild(moduleLoaderState, 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(moduleLoaderState, 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(moduleLoaderState, 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(moduleLoaderState, ModeBuild, depMode, p))
556 }
557 if cfg.BuildBuildmode == "shared" {
558 a = b.buildmodeShared(moduleLoaderState, 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 Cross compiled binaries are installed in $GOOS_$GOARCH subdirectories
574 of the above.
575
576 If the arguments have version suffixes (like @latest or @v1.0.0), "go install"
577 builds packages in module-aware mode, ignoring the go.mod file in the current
578 directory or any parent directory, if there is one. This is useful for
579 installing executables without affecting the dependencies of the main module.
580 To eliminate ambiguity about which module versions are used in the build, the
581 arguments must satisfy the following constraints:
582
583 - Arguments must be package paths or package patterns (with "..." wildcards).
584 They must not be standard packages (like fmt), meta-patterns (std, cmd,
585 all), or relative or absolute file paths.
586
587 - All arguments must have the same version suffix. Different queries are not
588 allowed, even if they refer to the same version.
589
590 - All arguments must refer to packages in the same module at the same version.
591
592 - Package path arguments must refer to main packages. Pattern arguments
593 will only match main packages.
594
595 - No module is considered the "main" module. If the module containing
596 packages named on the command line has a go.mod file, it must not contain
597 directives (replace and exclude) that would cause it to be interpreted
598 differently than if it were the main module. The module must not require
599 a higher version of itself.
600
601 - Vendor directories are not used in any module. (Vendor directories are not
602 included in the module zip files downloaded by 'go install'.)
603
604 If the arguments don't have version suffixes, "go install" may run in
605 module-aware mode or GOPATH mode, depending on the GO111MODULE environment
606 variable and the presence of a go.mod file. See 'go help modules' for details.
607 If module-aware mode is enabled, "go install" runs in the context of the main
608 module.
609
610 When module-aware mode is disabled, non-main packages are installed in the
611 directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled,
612 non-main packages are built and cached but not installed.
613
614 Before Go 1.20, the standard library was installed to
615 $GOROOT/pkg/$GOOS_$GOARCH.
616 Starting in Go 1.20, the standard library is built and cached but not installed.
617 Setting GODEBUG=installgoroot=all restores the use of
618 $GOROOT/pkg/$GOOS_$GOARCH.
619
620 For more about build flags, see 'go help build'.
621
622 For more about specifying packages, see 'go help packages'.
623
624 See also: go build, go get, go clean.
625 `,
626 }
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648 func libname(args []string, pkgs []*load.Package) (string, error) {
649 var libname string
650 appendName := func(arg string) {
651 if libname == "" {
652 libname = arg
653 } else {
654 libname += "," + arg
655 }
656 }
657 var haveNonMeta bool
658 for _, arg := range args {
659 if search.IsMetaPackage(arg) {
660 appendName(arg)
661 } else {
662 haveNonMeta = true
663 }
664 }
665 if len(libname) == 0 {
666 if len(args) == 1 && strings.HasSuffix(args[0], "/...") {
667
668 arg := strings.TrimSuffix(args[0], "/...")
669 if build.IsLocalImport(arg) {
670 cwd, _ := os.Getwd()
671 bp, _ := cfg.BuildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
672 if bp.ImportPath != "" && bp.ImportPath != "." {
673 arg = bp.ImportPath
674 }
675 }
676 appendName(strings.ReplaceAll(arg, "/", "-"))
677 } else {
678 for _, pkg := range pkgs {
679 appendName(strings.ReplaceAll(pkg.ImportPath, "/", "-"))
680 }
681 }
682 } else if haveNonMeta {
683 return "", errors.New("mixing of meta and non-meta packages is not allowed")
684 }
685
686
687 return "lib" + libname + ".so", nil
688 }
689
690 func runInstall(ctx context.Context, cmd *base.Command, args []string) {
691 moduleLoaderState := modload.NewState()
692 for _, arg := range args {
693 if strings.Contains(arg, "@") && !build.IsLocalImport(arg) && !filepath.IsAbs(arg) {
694 installOutsideModule(moduleLoaderState, ctx, args)
695 return
696 }
697 }
698
699 modload.InitWorkfile(moduleLoaderState)
700 BuildInit(moduleLoaderState)
701 pkgs := load.PackagesAndErrors(moduleLoaderState, ctx, load.PackageOpts{AutoVCS: true}, args)
702 if cfg.ModulesEnabled && !modload.HasModRoot(moduleLoaderState) {
703 haveErrors := false
704 allMissingErrors := true
705 for _, pkg := range pkgs {
706 if pkg.Error == nil {
707 continue
708 }
709 haveErrors = true
710 if _, ok := errors.AsType[*modload.ImportMissingError](pkg.Error); !ok {
711 allMissingErrors = false
712 break
713 }
714 }
715 if haveErrors && allMissingErrors {
716 latestArgs := make([]string, len(args))
717 for i := range args {
718 latestArgs[i] = args[i] + "@latest"
719 }
720 hint := strings.Join(latestArgs, " ")
721 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)
722 }
723 }
724 load.CheckPackageErrors(pkgs)
725
726 if cfg.BuildCover {
727 load.PrepareForCoverageBuild(moduleLoaderState, pkgs)
728 }
729
730 InstallPackages(moduleLoaderState, ctx, args, pkgs)
731 }
732
733
734 func omitTestOnly(pkgs []*load.Package) []*load.Package {
735 var list []*load.Package
736 for _, p := range pkgs {
737 if len(p.GoFiles)+len(p.CgoFiles) == 0 && !p.Internal.CmdlinePkgLiteral {
738
739
740
741
742
743 continue
744 }
745 list = append(list, p)
746 }
747 return list
748 }
749
750 func InstallPackages(loaderstate *modload.State, ctx context.Context, patterns []string, pkgs []*load.Package) {
751 ctx, span := trace.StartSpan(ctx, "InstallPackages "+strings.Join(patterns, " "))
752 defer span.Done()
753
754 if cfg.GOBIN != "" && !filepath.IsAbs(cfg.GOBIN) {
755 base.Fatalf("cannot install, GOBIN must be an absolute path")
756 }
757
758 pkgs = omitTestOnly(pkgsFilter(pkgs))
759 for _, p := range pkgs {
760 if p.Target == "" {
761 switch {
762 case p.Name != "main" && p.Internal.Local && p.ConflictDir == "":
763
764
765
766
767 case p.Name != "main" && p.Module != nil:
768
769 case p.Name != "main" && p.Standard && p.Internal.Build.PkgObj == "":
770
771
772
773
774 case p.Internal.GobinSubdir:
775 base.Errorf("go: cannot install cross-compiled binaries when GOBIN is set")
776 case p.Internal.CmdlineFiles:
777 base.Errorf("go: no install location for .go files listed on command line (GOBIN not set)")
778 case p.ConflictDir != "":
779 base.Errorf("go: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
780 default:
781 base.Errorf("go: no install location for directory %s outside GOPATH\n"+
782 "\tFor more details see: 'go help gopath'", p.Dir)
783 }
784 }
785 }
786 base.ExitIfErrors()
787
788 b := NewBuilder("", loaderstate.VendorDirOrEmpty)
789 defer func() {
790 if err := b.Close(); err != nil {
791 base.Fatal(err)
792 }
793 }()
794
795 depMode := ModeBuild
796 a := &Action{Mode: "go install"}
797 var tools []*Action
798 for _, p := range pkgs {
799
800
801
802 a1 := b.AutoAction(loaderstate, ModeInstall, depMode, p)
803 if load.InstallTargetDir(p) == load.ToTool {
804 a.Deps = append(a.Deps, a1.Deps...)
805 a1.Deps = append(a1.Deps, a)
806 tools = append(tools, a1)
807 continue
808 }
809 a.Deps = append(a.Deps, a1)
810 }
811 if len(tools) > 0 {
812 a = &Action{
813 Mode: "go install (tools)",
814 Deps: tools,
815 }
816 }
817
818 if cfg.BuildBuildmode == "shared" {
819
820
821
822
823
824 a = b.buildmodeShared(loaderstate, ModeInstall, ModeInstall, patterns, pkgs, a)
825 }
826
827 b.Do(ctx, a)
828 base.ExitIfErrors()
829
830
831
832
833
834
835
836
837
838
839 if len(patterns) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
840
841
842 targ := pkgs[0].DefaultExecName()
843 targ += cfg.ExeSuffix
844 if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target {
845 fi, err := os.Stat(targ)
846 if err == nil {
847 m := fi.Mode()
848 if m.IsRegular() {
849 if m&0111 != 0 || cfg.Goos == "windows" {
850 os.Remove(targ)
851 }
852 }
853 }
854 }
855 }
856 }
857
858
859
860
861
862
863 func installOutsideModule(loaderstate *modload.State, ctx context.Context, args []string) {
864 loaderstate.ForceUseModules = true
865 loaderstate.RootMode = modload.NoRoot
866 modload.AllowMissingModuleImports(loaderstate)
867 modload.Init(loaderstate)
868 BuildInit(loaderstate)
869
870
871
872
873
874
875
876 pkgOpts := load.PackageOpts{MainOnly: true}
877 pkgs, err := load.PackagesAndErrorsOutsideModule(loaderstate, ctx, pkgOpts, args)
878 if err != nil {
879 base.Fatal(err)
880 }
881 load.CheckPackageErrors(pkgs)
882 patterns := make([]string, len(args))
883 for i, arg := range args {
884 patterns[i] = arg[:strings.Index(arg, "@")]
885 }
886
887
888 InstallPackages(loaderstate, ctx, patterns, pkgs)
889 }
890
891
892
893
894
895
896
897 var ExecCmd []string
898
899
900
901 func FindExecCmd() []string {
902 if ExecCmd != nil {
903 return ExecCmd
904 }
905 ExecCmd = []string{}
906 if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH {
907 return ExecCmd
908 }
909 path, err := pathcache.LookPath(fmt.Sprintf("go_%s_%s_exec", cfg.Goos, cfg.Goarch))
910 if err == nil {
911 ExecCmd = []string{path}
912 }
913 return ExecCmd
914 }
915
916
917 type coverFlag struct{ V flag.Value }
918
919 func (f coverFlag) String() string { return f.V.String() }
920
921 func (f coverFlag) Set(value string) error {
922 if err := f.V.Set(value); err != nil {
923 return err
924 }
925 cfg.BuildCover = true
926 return nil
927 }
928
929 type coverModeFlag string
930
931 func (f *coverModeFlag) String() string { return string(*f) }
932 func (f *coverModeFlag) Set(value string) error {
933 switch value {
934 case "", "set", "count", "atomic":
935 *f = coverModeFlag(value)
936 cfg.BuildCoverMode = value
937 return nil
938 default:
939 return errors.New(`valid modes are "set", "count", or "atomic"`)
940 }
941 }
942
943
944 type commaListFlag struct{ Vals *[]string }
945
946 func (f commaListFlag) String() string { return strings.Join(*f.Vals, ",") }
947
948 func (f commaListFlag) Set(value string) error {
949 if value == "" {
950 *f.Vals = nil
951 } else {
952 *f.Vals = strings.Split(value, ",")
953 }
954 return nil
955 }
956
957
958 type stringFlag struct{ val *string }
959
960 func (f stringFlag) String() string { return *f.val }
961 func (f stringFlag) Set(value string) error {
962 *f.val = value
963 return nil
964 }
965
View as plain text