Help us shape the future of Go! Take the 2026 Go Developer Survey

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

View as plain text