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