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

View as plain text