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