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