github.com/bir3/gocompiler@v0.3.205/src/cmd/gocmd/internal/work/build.go (about)

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