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 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 AddCoverFlags(CmdBuild, nil)
251 AddCoverFlags(CmdInstall, nil)
252 }
253
254
255
256
257 var (
258 forcedAsmflags []string
259 forcedGcflags []string
260 forcedLdflags []string
261 forcedGccgoflags []string
262 )
263
264 var BuildToolchain toolchain = noToolchain{}
265 var ldBuildmode string
266
267
268
269
270 type buildCompiler struct{}
271
272 func (c buildCompiler) Set(value string) error {
273 switch value {
274 case "gc":
275 BuildToolchain = gcToolchain{}
276 case "gccgo":
277 BuildToolchain = gccgoToolchain{}
278 default:
279 return fmt.Errorf("unknown compiler %q", value)
280 }
281 cfg.BuildToolchainName = value
282 cfg.BuildContext.Compiler = value
283 return nil
284 }
285
286 func (c buildCompiler) String() string {
287 return cfg.BuildContext.Compiler
288 }
289
290 func init() {
291 switch build.Default.Compiler {
292 case "gc", "gccgo":
293 buildCompiler{}.Set(build.Default.Compiler)
294 }
295 }
296
297 type BuildFlagMask int
298
299 const (
300 DefaultBuildFlags BuildFlagMask = 0
301 OmitModFlag BuildFlagMask = 1 << iota
302 OmitModCommonFlags
303 OmitVFlag
304 OmitBuildOnlyFlags
305 OmitJSONFlag
306 )
307
308
309
310 func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) {
311 base.AddBuildFlagsNX(&cmd.Flag)
312 base.AddChdirFlag(&cmd.Flag)
313 cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "")
314 cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "")
315 if mask&OmitVFlag == 0 {
316 cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "")
317 }
318
319 cmd.Flag.BoolVar(&cfg.BuildASan, "asan", false, "")
320 cmd.Flag.Var(&load.BuildAsmflags, "asmflags", "")
321 cmd.Flag.Var(buildCompiler{}, "compiler", "")
322 cmd.Flag.StringVar(&cfg.BuildBuildmode, "buildmode", "default", "")
323 cmd.Flag.Var((*buildvcsFlag)(&cfg.BuildBuildvcs), "buildvcs", "")
324 cmd.Flag.Var(&load.BuildGcflags, "gcflags", "")
325 cmd.Flag.Var(&load.BuildGccgoflags, "gccgoflags", "")
326 if mask&OmitModFlag == 0 {
327 base.AddModFlag(&cmd.Flag)
328 }
329 if mask&OmitModCommonFlags == 0 {
330 base.AddModCommonFlags(&cmd.Flag)
331 } else {
332
333
334
335 cmd.Flag.StringVar(&fsys.OverlayFile, "overlay", "", "")
336 }
337 cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "")
338 if mask&(OmitBuildOnlyFlags|OmitJSONFlag) == 0 {
339
340
341
342
343 cmd.Flag.BoolVar(&cfg.BuildJSON, "json", false, "")
344 }
345 cmd.Flag.Var(&load.BuildLdflags, "ldflags", "")
346 cmd.Flag.BoolVar(&cfg.BuildLinkshared, "linkshared", false, "")
347 cmd.Flag.BoolVar(&cfg.BuildMSan, "msan", false, "")
348 cmd.Flag.StringVar(&cfg.BuildPGO, "pgo", "auto", "")
349 cmd.Flag.StringVar(&cfg.BuildPkgdir, "pkgdir", "", "")
350 cmd.Flag.BoolVar(&cfg.BuildRace, "race", false, "")
351 cmd.Flag.Var((*tagsFlag)(&cfg.BuildContext.BuildTags), "tags", "")
352 cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildToolexec), "toolexec", "")
353 cmd.Flag.BoolVar(&cfg.BuildTrimpath, "trimpath", false, "")
354 cmd.Flag.BoolVar(&cfg.BuildWork, "work", false, "")
355
356
357 cmd.Flag.StringVar(&cfg.DebugActiongraph, "debug-actiongraph", "", "")
358 cmd.Flag.StringVar(&cfg.DebugRuntimeTrace, "debug-runtime-trace", "", "")
359 cmd.Flag.StringVar(&cfg.DebugTrace, "debug-trace", "", "")
360 }
361
362
363
364
365 func AddCoverFlags(cmd *base.Command, coverProfileFlag *string) {
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 if coverProfileFlag != nil {
370 cmd.Flag.Var(coverFlag{V: stringFlag{coverProfileFlag}}, "coverprofile", "")
371 }
372 }
373
374
375 type tagsFlag []string
376
377 func (v *tagsFlag) Set(s string) error {
378
379 if strings.Contains(s, " ") || strings.Contains(s, "'") {
380 return (*base.StringsFlag)(v).Set(s)
381 }
382
383
384 *v = []string{}
385 for s := range strings.SplitSeq(s, ",") {
386 if s != "" {
387 *v = append(*v, s)
388 }
389 }
390 return nil
391 }
392
393 func (v *tagsFlag) String() string {
394 return "<TagsFlag>"
395 }
396
397
398 type buildvcsFlag string
399
400 func (f *buildvcsFlag) IsBoolFlag() bool { return true }
401
402 func (f *buildvcsFlag) Set(s string) error {
403
404
405 if s == "" || s == "auto" {
406 *f = "auto"
407 return nil
408 }
409
410 b, err := strconv.ParseBool(s)
411 if err != nil {
412 return errors.New("value is neither 'auto' nor a valid bool")
413 }
414 *f = (buildvcsFlag)(strconv.FormatBool(b))
415 return nil
416 }
417
418 func (f *buildvcsFlag) String() string { return string(*f) }
419
420
421
422
423 func fileExtSplit(file string) (name, ext string) {
424 dotExt := filepath.Ext(file)
425 name = file[:len(file)-len(dotExt)]
426 if dotExt != "" {
427 ext = dotExt[1:]
428 }
429 return
430 }
431
432 func pkgsMain(pkgs []*load.Package) (res []*load.Package) {
433 for _, p := range pkgs {
434 if p.Name == "main" {
435 res = append(res, p)
436 }
437 }
438 return res
439 }
440
441 func pkgsNotMain(pkgs []*load.Package) (res []*load.Package) {
442 for _, p := range pkgs {
443 if p.Name != "main" {
444 res = append(res, p)
445 }
446 }
447 return res
448 }
449
450 func oneMainPkg(pkgs []*load.Package) []*load.Package {
451 if len(pkgs) != 1 || pkgs[0].Name != "main" {
452 base.Fatalf("-buildmode=%s requires exactly one main package", cfg.BuildBuildmode)
453 }
454 return pkgs
455 }
456
457 var pkgsFilter = func(pkgs []*load.Package) []*load.Package { return pkgs }
458
459 func runBuild(ctx context.Context, cmd *base.Command, args []string) {
460 moduleLoaderState := modload.NewState()
461 moduleLoaderState.InitWorkfile()
462 BuildInit(moduleLoaderState)
463 b := NewBuilder("", moduleLoaderState.VendorDirOrEmpty)
464 defer func() {
465 if err := b.Close(); err != nil {
466 base.Fatal(err)
467 }
468 }()
469
470 pkgs := load.PackagesAndErrors(moduleLoaderState, 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.BuildCover {
505 load.PrepareForCoverageBuild(moduleLoaderState, 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(moduleLoaderState, 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(moduleLoaderState, 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(moduleLoaderState, ModeBuild, depMode, p))
554 }
555 if cfg.BuildBuildmode == "shared" {
556 a = b.buildmodeShared(moduleLoaderState, 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 Cross compiled binaries are installed in $GOOS_$GOARCH subdirectories
572 of the above.
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 moduleLoaderState := modload.NewState()
690 for _, arg := range args {
691 if strings.Contains(arg, "@") && !build.IsLocalImport(arg) && !filepath.IsAbs(arg) {
692 installOutsideModule(moduleLoaderState, ctx, args)
693 return
694 }
695 }
696
697 moduleLoaderState.InitWorkfile()
698 BuildInit(moduleLoaderState)
699 pkgs := load.PackagesAndErrors(moduleLoaderState, ctx, load.PackageOpts{AutoVCS: true}, args)
700 if cfg.ModulesEnabled && !moduleLoaderState.HasModRoot() {
701 haveErrors := false
702 allMissingErrors := true
703 for _, pkg := range pkgs {
704 if pkg.Error == nil {
705 continue
706 }
707 haveErrors = true
708 if _, ok := errors.AsType[*modload.ImportMissingError](pkg.Error); !ok {
709 allMissingErrors = false
710 break
711 }
712 }
713 if haveErrors && allMissingErrors {
714 latestArgs := make([]string, len(args))
715 for i := range args {
716 latestArgs[i] = args[i] + "@latest"
717 }
718 hint := strings.Join(latestArgs, " ")
719 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)
720 }
721 }
722 load.CheckPackageErrors(pkgs)
723
724 if cfg.BuildCover {
725 load.PrepareForCoverageBuild(moduleLoaderState, pkgs)
726 }
727
728 InstallPackages(moduleLoaderState, ctx, args, pkgs)
729 }
730
731
732 func omitTestOnly(pkgs []*load.Package) []*load.Package {
733 var list []*load.Package
734 for _, p := range pkgs {
735 if len(p.GoFiles)+len(p.CgoFiles) == 0 && !p.Internal.CmdlinePkgLiteral {
736
737
738
739
740
741 continue
742 }
743 list = append(list, p)
744 }
745 return list
746 }
747
748 func InstallPackages(loaderstate *modload.State, ctx context.Context, patterns []string, pkgs []*load.Package) {
749 ctx, span := trace.StartSpan(ctx, "InstallPackages "+strings.Join(patterns, " "))
750 defer span.Done()
751
752 if cfg.GOBIN != "" && !filepath.IsAbs(cfg.GOBIN) {
753 base.Fatalf("cannot install, GOBIN must be an absolute path")
754 }
755
756 pkgs = omitTestOnly(pkgsFilter(pkgs))
757 for _, p := range pkgs {
758 if p.Target == "" {
759 switch {
760 case p.Name != "main" && p.Internal.Local && p.ConflictDir == "":
761
762
763
764
765 case p.Name != "main" && p.Module != nil:
766
767 case p.Name != "main" && p.Standard && p.Internal.Build.PkgObj == "":
768
769
770
771
772 case p.Internal.GobinSubdir:
773 base.Errorf("go: cannot install cross-compiled binaries when GOBIN is set")
774 case p.Internal.CmdlineFiles:
775 base.Errorf("go: no install location for .go files listed on command line (GOBIN not set)")
776 case p.ConflictDir != "":
777 base.Errorf("go: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
778 default:
779 base.Errorf("go: no install location for directory %s outside GOPATH\n"+
780 "\tFor more details see: 'go help gopath'", p.Dir)
781 }
782 }
783 }
784 base.ExitIfErrors()
785
786 b := NewBuilder("", loaderstate.VendorDirOrEmpty)
787 defer func() {
788 if err := b.Close(); err != nil {
789 base.Fatal(err)
790 }
791 }()
792
793 depMode := ModeBuild
794 a := &Action{Mode: "go install"}
795 var tools []*Action
796 for _, p := range pkgs {
797
798
799
800 a1 := b.AutoAction(loaderstate, ModeInstall, depMode, p)
801 if load.InstallTargetDir(p) == load.ToTool {
802 a.Deps = append(a.Deps, a1.Deps...)
803 a1.Deps = append(a1.Deps, a)
804 tools = append(tools, a1)
805 continue
806 }
807 a.Deps = append(a.Deps, a1)
808 }
809 if len(tools) > 0 {
810 a = &Action{
811 Mode: "go install (tools)",
812 Deps: tools,
813 }
814 }
815
816 if cfg.BuildBuildmode == "shared" {
817
818
819
820
821
822 a = b.buildmodeShared(loaderstate, ModeInstall, ModeInstall, patterns, pkgs, a)
823 }
824
825 b.Do(ctx, a)
826 base.ExitIfErrors()
827
828
829
830
831
832
833
834
835
836
837 if len(patterns) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
838
839
840 targ := pkgs[0].DefaultExecName()
841 targ += cfg.ExeSuffix
842 if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target {
843 fi, err := os.Stat(targ)
844 if err == nil {
845 m := fi.Mode()
846 if m.IsRegular() {
847 if m&0111 != 0 || cfg.Goos == "windows" {
848 os.Remove(targ)
849 }
850 }
851 }
852 }
853 }
854 }
855
856
857
858
859
860
861 func installOutsideModule(loaderstate *modload.State, ctx context.Context, args []string) {
862 loaderstate.ForceUseModules = true
863 loaderstate.RootMode = modload.NoRoot
864 loaderstate.AllowMissingModuleImports()
865 modload.Init(loaderstate)
866 BuildInit(loaderstate)
867
868
869
870
871
872
873
874 pkgOpts := load.PackageOpts{MainOnly: true}
875 pkgs, err := load.PackagesAndErrorsOutsideModule(loaderstate, ctx, pkgOpts, args)
876 if err != nil {
877 base.Fatal(err)
878 }
879 load.CheckPackageErrors(pkgs)
880 patterns := make([]string, len(args))
881 for i, arg := range args {
882 patterns[i] = arg[:strings.Index(arg, "@")]
883 }
884
885
886 InstallPackages(loaderstate, ctx, patterns, pkgs)
887 }
888
889
890
891
892
893
894
895 var ExecCmd []string
896
897
898
899 func FindExecCmd() []string {
900 if ExecCmd != nil {
901 return ExecCmd
902 }
903 ExecCmd = []string{}
904 if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH {
905 return ExecCmd
906 }
907 path, err := pathcache.LookPath(fmt.Sprintf("go_%s_%s_exec", cfg.Goos, cfg.Goarch))
908 if err == nil {
909 ExecCmd = []string{path}
910 }
911 return ExecCmd
912 }
913
914
915 type coverFlag struct{ V flag.Value }
916
917 func (f coverFlag) String() string { return f.V.String() }
918
919 func (f coverFlag) Set(value string) error {
920 if err := f.V.Set(value); err != nil {
921 return err
922 }
923 cfg.BuildCover = true
924 return nil
925 }
926
927 type coverModeFlag string
928
929 func (f *coverModeFlag) String() string { return string(*f) }
930 func (f *coverModeFlag) Set(value string) error {
931 switch value {
932 case "", "set", "count", "atomic":
933 *f = coverModeFlag(value)
934 cfg.BuildCoverMode = value
935 return nil
936 default:
937 return errors.New(`valid modes are "set", "count", or "atomic"`)
938 }
939 }
940
941
942 type commaListFlag struct{ Vals *[]string }
943
944 func (f commaListFlag) String() string { return strings.Join(*f.Vals, ",") }
945
946 func (f commaListFlag) Set(value string) error {
947 if value == "" {
948 *f.Vals = nil
949 } else {
950 *f.Vals = strings.Split(value, ",")
951 }
952 return nil
953 }
954
955
956 type stringFlag struct{ val *string }
957
958 func (f stringFlag) String() string { return *f.val }
959 func (f stringFlag) Set(value string) error {
960 *f.val = value
961 return nil
962 }
963
View as plain text