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://golang.org/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 packages and binaries are installed,
   227  run 'go help gopath'.
   228  For more about calling between Go and C/C++, run 'go help c'.
   229  
   230  Note: Build adheres to certain conventions such as those described
   231  by 'go help gopath'. Not all projects can follow these conventions,
   232  however. Installations that have their own conventions or that use
   233  a separate software build system may choose to use lower-level
   234  invocations such as 'go tool compile' and 'go tool link' to avoid
   235  some of the overheads and design decisions of the build tool.
   236  
   237  See also: go install, go get, go clean.
   238  	`,
   239  }
   240  
   241  const concurrentGCBackendCompilationEnabledByDefault = true
   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 BuildToolchain toolchain = noToolchain{}
   267  var ldBuildmode string
   268  
   269  // buildCompiler implements flag.Var.
   270  // It implements Set by updating both
   271  // BuildToolchain and buildContext.Compiler.
   272  type buildCompiler struct{}
   273  
   274  func (c buildCompiler) Set(value string) error {
   275  	switch value {
   276  	case "gc":
   277  		BuildToolchain = gcToolchain{}
   278  	case "gccgo":
   279  		BuildToolchain = gccgoToolchain{}
   280  	default:
   281  		return fmt.Errorf("unknown compiler %q", value)
   282  	}
   283  	cfg.BuildToolchainName = value
   284  	cfg.BuildContext.Compiler = value
   285  	return nil
   286  }
   287  
   288  func (c buildCompiler) String() string {
   289  	return cfg.BuildContext.Compiler
   290  }
   291  
   292  func init() {
   293  	switch build.Default.Compiler {
   294  	case "gc", "gccgo":
   295  		buildCompiler{}.Set(build.Default.Compiler)
   296  	}
   297  }
   298  
   299  type BuildFlagMask int
   300  
   301  const (
   302  	DefaultBuildFlags BuildFlagMask = 0
   303  	OmitModFlag       BuildFlagMask = 1 << iota
   304  	OmitModCommonFlags
   305  	OmitVFlag
   306  	OmitBuildOnlyFlags // Omit flags that only affect building packages
   307  	OmitJSONFlag
   308  )
   309  
   310  // AddBuildFlags adds the flags common to the build, clean, get,
   311  // install, list, run, and test commands.
   312  func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) {
   313  	base.AddBuildFlagsNX(&cmd.Flag)
   314  	base.AddChdirFlag(&cmd.Flag)
   315  	cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "")
   316  	cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "")
   317  	if mask&OmitVFlag == 0 {
   318  		cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "")
   319  	}
   320  
   321  	cmd.Flag.BoolVar(&cfg.BuildASan, "asan", false, "")
   322  	cmd.Flag.Var(&load.BuildAsmflags, "asmflags", "")
   323  	cmd.Flag.Var(buildCompiler{}, "compiler", "")
   324  	cmd.Flag.StringVar(&cfg.BuildBuildmode, "buildmode", "default", "")
   325  	cmd.Flag.Var((*buildvcsFlag)(&cfg.BuildBuildvcs), "buildvcs", "")
   326  	cmd.Flag.Var(&load.BuildGcflags, "gcflags", "")
   327  	cmd.Flag.Var(&load.BuildGccgoflags, "gccgoflags", "")
   328  	if mask&OmitModFlag == 0 {
   329  		base.AddModFlag(&cmd.Flag)
   330  	}
   331  	if mask&OmitModCommonFlags == 0 {
   332  		base.AddModCommonFlags(&cmd.Flag)
   333  	} else {
   334  		// Add the overlay flag even when we don't add the rest of the mod common flags.
   335  		// This only affects 'go get' in GOPATH mode, but add the flag anyway for
   336  		// consistency.
   337  		cmd.Flag.StringVar(&fsys.OverlayFile, "overlay", "", "")
   338  	}
   339  	cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "")
   340  	if mask&(OmitBuildOnlyFlags|OmitJSONFlag) == 0 {
   341  		// TODO(#62250): OmitBuildOnlyFlags should apply to many more flags
   342  		// here, but we let a bunch of flags slip in before we realized that
   343  		// many of them don't make sense for most subcommands. We might even
   344  		// want to separate "AddBuildFlags" and "AddSelectionFlags".
   345  		cmd.Flag.BoolVar(&cfg.BuildJSON, "json", false, "")
   346  	}
   347  	cmd.Flag.Var(&load.BuildLdflags, "ldflags", "")
   348  	cmd.Flag.BoolVar(&cfg.BuildLinkshared, "linkshared", false, "")
   349  	cmd.Flag.BoolVar(&cfg.BuildMSan, "msan", false, "")
   350  	cmd.Flag.StringVar(&cfg.BuildPGO, "pgo", "auto", "")
   351  	cmd.Flag.StringVar(&cfg.BuildPkgdir, "pkgdir", "", "")
   352  	cmd.Flag.BoolVar(&cfg.BuildRace, "race", false, "")
   353  	cmd.Flag.Var((*tagsFlag)(&cfg.BuildContext.BuildTags), "tags", "")
   354  	cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildToolexec), "toolexec", "")
   355  	cmd.Flag.BoolVar(&cfg.BuildTrimpath, "trimpath", false, "")
   356  	cmd.Flag.BoolVar(&cfg.BuildWork, "work", false, "")
   357  
   358  	// Undocumented, unstable debugging flags.
   359  	cmd.Flag.StringVar(&cfg.DebugActiongraph, "debug-actiongraph", "", "")
   360  	cmd.Flag.StringVar(&cfg.DebugRuntimeTrace, "debug-runtime-trace", "", "")
   361  	cmd.Flag.StringVar(&cfg.DebugTrace, "debug-trace", "", "")
   362  }
   363  
   364  // AddCoverFlags adds coverage-related flags to "cmd".
   365  // We add -cover{mode,pkg} to the build command and only
   366  // -coverprofile to the test command.
   367  func AddCoverFlags(cmd *base.Command, coverProfileFlag *string) {
   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  	if coverProfileFlag != nil {
   372  		cmd.Flag.Var(coverFlag{V: stringFlag{coverProfileFlag}}, "coverprofile", "")
   373  	}
   374  }
   375  
   376  // tagsFlag is the implementation of the -tags flag.
   377  type tagsFlag []string
   378  
   379  func (v *tagsFlag) Set(s string) error {
   380  	// For compatibility with Go 1.12 and earlier, allow "-tags='a b c'" or even just "-tags='a'".
   381  	if strings.Contains(s, " ") || strings.Contains(s, "'") {
   382  		return (*base.StringsFlag)(v).Set(s)
   383  	}
   384  
   385  	// Split on commas, ignore empty strings.
   386  	*v = []string{}
   387  	for s := range strings.SplitSeq(s, ",") {
   388  		if s != "" {
   389  			*v = append(*v, s)
   390  		}
   391  	}
   392  	return nil
   393  }
   394  
   395  func (v *tagsFlag) String() string {
   396  	return "<TagsFlag>"
   397  }
   398  
   399  // buildvcsFlag is the implementation of the -buildvcs flag.
   400  type buildvcsFlag string
   401  
   402  func (f *buildvcsFlag) IsBoolFlag() bool { return true } // allow -buildvcs (without arguments)
   403  
   404  func (f *buildvcsFlag) Set(s string) error {
   405  	// https://go.dev/issue/51748: allow "-buildvcs=auto",
   406  	// in addition to the usual "true" and "false".
   407  	if s == "" || s == "auto" {
   408  		*f = "auto"
   409  		return nil
   410  	}
   411  
   412  	b, err := strconv.ParseBool(s)
   413  	if err != nil {
   414  		return errors.New("value is neither 'auto' nor a valid bool")
   415  	}
   416  	*f = (buildvcsFlag)(strconv.FormatBool(b)) // convert to canonical "true" or "false"
   417  	return nil
   418  }
   419  
   420  func (f *buildvcsFlag) String() string { return string(*f) }
   421  
   422  // fileExtSplit expects a filename and returns the name
   423  // and ext (without the dot). If the file has no
   424  // extension, ext will be empty.
   425  func fileExtSplit(file string) (name, ext string) {
   426  	dotExt := filepath.Ext(file)
   427  	name = file[:len(file)-len(dotExt)]
   428  	if dotExt != "" {
   429  		ext = dotExt[1:]
   430  	}
   431  	return
   432  }
   433  
   434  func pkgsMain(pkgs []*load.Package) (res []*load.Package) {
   435  	for _, p := range pkgs {
   436  		if p.Name == "main" {
   437  			res = append(res, p)
   438  		}
   439  	}
   440  	return res
   441  }
   442  
   443  func pkgsNotMain(pkgs []*load.Package) (res []*load.Package) {
   444  	for _, p := range pkgs {
   445  		if p.Name != "main" {
   446  			res = append(res, p)
   447  		}
   448  	}
   449  	return res
   450  }
   451  
   452  func oneMainPkg(pkgs []*load.Package) []*load.Package {
   453  	if len(pkgs) != 1 || pkgs[0].Name != "main" {
   454  		base.Fatalf("-buildmode=%s requires exactly one main package", cfg.BuildBuildmode)
   455  	}
   456  	return pkgs
   457  }
   458  
   459  var pkgsFilter = func(pkgs []*load.Package) []*load.Package { return pkgs }
   460  
   461  func runBuild(ctx context.Context, cmd *base.Command, args []string) {
   462  	moduleLoaderState := modload.NewState()
   463  	modload.InitWorkfile(moduleLoaderState)
   464  	BuildInit(moduleLoaderState)
   465  	b := NewBuilder("", moduleLoaderState.VendorDirOrEmpty)
   466  	defer func() {
   467  		if err := b.Close(); err != nil {
   468  			base.Fatal(err)
   469  		}
   470  	}()
   471  
   472  	pkgs := load.PackagesAndErrors(moduleLoaderState, 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.BuildCover {
   507  		load.PrepareForCoverageBuild(moduleLoaderState, 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(moduleLoaderState, 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(moduleLoaderState, 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(moduleLoaderState, ModeBuild, depMode, p))
   556  	}
   557  	if cfg.BuildBuildmode == "shared" {
   558  		a = b.buildmodeShared(moduleLoaderState, 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  Cross compiled binaries are installed in $GOOS_$GOARCH subdirectories
   574  of the above.
   575  
   576  If the arguments have version suffixes (like @latest or @v1.0.0), "go install"
   577  builds packages in module-aware mode, ignoring the go.mod file in the current
   578  directory or any parent directory, if there is one. This is useful for
   579  installing executables without affecting the dependencies of the main module.
   580  To eliminate ambiguity about which module versions are used in the build, the
   581  arguments must satisfy the following constraints:
   582  
   583  - Arguments must be package paths or package patterns (with "..." wildcards).
   584  They must not be standard packages (like fmt), meta-patterns (std, cmd,
   585  all), or relative or absolute file paths.
   586  
   587  - All arguments must have the same version suffix. Different queries are not
   588  allowed, even if they refer to the same version.
   589  
   590  - All arguments must refer to packages in the same module at the same version.
   591  
   592  - Package path arguments must refer to main packages. Pattern arguments
   593  will only match main packages.
   594  
   595  - No module is considered the "main" module. If the module containing
   596  packages named on the command line has a go.mod file, it must not contain
   597  directives (replace and exclude) that would cause it to be interpreted
   598  differently than if it were the main module. The module must not require
   599  a higher version of itself.
   600  
   601  - Vendor directories are not used in any module. (Vendor directories are not
   602  included in the module zip files downloaded by 'go install'.)
   603  
   604  If the arguments don't have version suffixes, "go install" may run in
   605  module-aware mode or GOPATH mode, depending on the GO111MODULE environment
   606  variable and the presence of a go.mod file. See 'go help modules' for details.
   607  If module-aware mode is enabled, "go install" runs in the context of the main
   608  module.
   609  
   610  When module-aware mode is disabled, non-main packages are installed in the
   611  directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled,
   612  non-main packages are built and cached but not installed.
   613  
   614  Before Go 1.20, the standard library was installed to
   615  $GOROOT/pkg/$GOOS_$GOARCH.
   616  Starting in Go 1.20, the standard library is built and cached but not installed.
   617  Setting GODEBUG=installgoroot=all restores the use of
   618  $GOROOT/pkg/$GOOS_$GOARCH.
   619  
   620  For more about build flags, see 'go help build'.
   621  
   622  For more about specifying packages, see 'go help packages'.
   623  
   624  See also: go build, go get, go clean.
   625  	`,
   626  }
   627  
   628  // libname returns the filename to use for the shared library when using
   629  // -buildmode=shared. The rules we use are:
   630  // Use arguments for special 'meta' packages:
   631  //
   632  //	std --> libstd.so
   633  //	std cmd --> libstd,cmd.so
   634  //
   635  // A single non-meta argument with trailing "/..." is special cased:
   636  //
   637  //	foo/... --> libfoo.so
   638  //	(A relative path like "./..."  expands the "." first)
   639  //
   640  // Use import paths for other cases, changing '/' to '-':
   641  //
   642  //	somelib --> libsubdir-somelib.so
   643  //	./ or ../ --> libsubdir-somelib.so
   644  //	gopkg.in/tomb.v2 -> libgopkg.in-tomb.v2.so
   645  //	a/... b/... ---> liba/c,b/d.so - all matching import paths
   646  //
   647  // Name parts are joined with ','.
   648  func libname(args []string, pkgs []*load.Package) (string, error) {
   649  	var libname string
   650  	appendName := func(arg string) {
   651  		if libname == "" {
   652  			libname = arg
   653  		} else {
   654  			libname += "," + arg
   655  		}
   656  	}
   657  	var haveNonMeta bool
   658  	for _, arg := range args {
   659  		if search.IsMetaPackage(arg) {
   660  			appendName(arg)
   661  		} else {
   662  			haveNonMeta = true
   663  		}
   664  	}
   665  	if len(libname) == 0 { // non-meta packages only. use import paths
   666  		if len(args) == 1 && strings.HasSuffix(args[0], "/...") {
   667  			// Special case of "foo/..." as mentioned above.
   668  			arg := strings.TrimSuffix(args[0], "/...")
   669  			if build.IsLocalImport(arg) {
   670  				cwd, _ := os.Getwd()
   671  				bp, _ := cfg.BuildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
   672  				if bp.ImportPath != "" && bp.ImportPath != "." {
   673  					arg = bp.ImportPath
   674  				}
   675  			}
   676  			appendName(strings.ReplaceAll(arg, "/", "-"))
   677  		} else {
   678  			for _, pkg := range pkgs {
   679  				appendName(strings.ReplaceAll(pkg.ImportPath, "/", "-"))
   680  			}
   681  		}
   682  	} else if haveNonMeta { // have both meta package and a non-meta one
   683  		return "", errors.New("mixing of meta and non-meta packages is not allowed")
   684  	}
   685  	// TODO(mwhudson): Needs to change for platforms that use different naming
   686  	// conventions...
   687  	return "lib" + libname + ".so", nil
   688  }
   689  
   690  func runInstall(ctx context.Context, cmd *base.Command, args []string) {
   691  	moduleLoaderState := modload.NewState()
   692  	for _, arg := range args {
   693  		if strings.Contains(arg, "@") && !build.IsLocalImport(arg) && !filepath.IsAbs(arg) {
   694  			installOutsideModule(moduleLoaderState, ctx, args)
   695  			return
   696  		}
   697  	}
   698  
   699  	modload.InitWorkfile(moduleLoaderState)
   700  	BuildInit(moduleLoaderState)
   701  	pkgs := load.PackagesAndErrors(moduleLoaderState, ctx, load.PackageOpts{AutoVCS: true}, args)
   702  	if cfg.ModulesEnabled && !modload.HasModRoot(moduleLoaderState) {
   703  		haveErrors := false
   704  		allMissingErrors := true
   705  		for _, pkg := range pkgs {
   706  			if pkg.Error == nil {
   707  				continue
   708  			}
   709  			haveErrors = true
   710  			if _, ok := errors.AsType[*modload.ImportMissingError](pkg.Error); !ok {
   711  				allMissingErrors = false
   712  				break
   713  			}
   714  		}
   715  		if haveErrors && allMissingErrors {
   716  			latestArgs := make([]string, len(args))
   717  			for i := range args {
   718  				latestArgs[i] = args[i] + "@latest"
   719  			}
   720  			hint := strings.Join(latestArgs, " ")
   721  			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)
   722  		}
   723  	}
   724  	load.CheckPackageErrors(pkgs)
   725  
   726  	if cfg.BuildCover {
   727  		load.PrepareForCoverageBuild(moduleLoaderState, pkgs)
   728  	}
   729  
   730  	InstallPackages(moduleLoaderState, ctx, args, pkgs)
   731  }
   732  
   733  // omitTestOnly returns pkgs with test-only packages removed.
   734  func omitTestOnly(pkgs []*load.Package) []*load.Package {
   735  	var list []*load.Package
   736  	for _, p := range pkgs {
   737  		if len(p.GoFiles)+len(p.CgoFiles) == 0 && !p.Internal.CmdlinePkgLiteral {
   738  			// Package has no source files,
   739  			// perhaps due to build tags or perhaps due to only having *_test.go files.
   740  			// Also, it is only being processed as the result of a wildcard match
   741  			// like ./..., not because it was listed as a literal path on the command line.
   742  			// Ignore it.
   743  			continue
   744  		}
   745  		list = append(list, p)
   746  	}
   747  	return list
   748  }
   749  
   750  func InstallPackages(loaderstate *modload.State, ctx context.Context, patterns []string, pkgs []*load.Package) {
   751  	ctx, span := trace.StartSpan(ctx, "InstallPackages "+strings.Join(patterns, " "))
   752  	defer span.Done()
   753  
   754  	if cfg.GOBIN != "" && !filepath.IsAbs(cfg.GOBIN) {
   755  		base.Fatalf("cannot install, GOBIN must be an absolute path")
   756  	}
   757  
   758  	pkgs = omitTestOnly(pkgsFilter(pkgs))
   759  	for _, p := range pkgs {
   760  		if p.Target == "" {
   761  			switch {
   762  			case p.Name != "main" && p.Internal.Local && p.ConflictDir == "":
   763  				// Non-executables outside GOPATH need not have a target:
   764  				// we can use the cache to hold the built package archive for use in future builds.
   765  				// The ones inside GOPATH should have a target (in GOPATH/pkg)
   766  				// or else something is wrong and worth reporting (like a ConflictDir).
   767  			case p.Name != "main" && p.Module != nil:
   768  				// Non-executables have no target (except the cache) when building with modules.
   769  			case p.Name != "main" && p.Standard && p.Internal.Build.PkgObj == "":
   770  				// Most packages in std do not need an installed .a, because they can be
   771  				// rebuilt and used directly from the build cache.
   772  				// A few targets (notably those using cgo) still do need to be installed
   773  				// in case the user's environment lacks a C compiler.
   774  			case p.Internal.GobinSubdir:
   775  				base.Errorf("go: cannot install cross-compiled binaries when GOBIN is set")
   776  			case p.Internal.CmdlineFiles:
   777  				base.Errorf("go: no install location for .go files listed on command line (GOBIN not set)")
   778  			case p.ConflictDir != "":
   779  				base.Errorf("go: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
   780  			default:
   781  				base.Errorf("go: no install location for directory %s outside GOPATH\n"+
   782  					"\tFor more details see: 'go help gopath'", p.Dir)
   783  			}
   784  		}
   785  	}
   786  	base.ExitIfErrors()
   787  
   788  	b := NewBuilder("", loaderstate.VendorDirOrEmpty)
   789  	defer func() {
   790  		if err := b.Close(); err != nil {
   791  			base.Fatal(err)
   792  		}
   793  	}()
   794  
   795  	depMode := ModeBuild
   796  	a := &Action{Mode: "go install"}
   797  	var tools []*Action
   798  	for _, p := range pkgs {
   799  		// If p is a tool, delay the installation until the end of the build.
   800  		// This avoids installing assemblers/compilers that are being executed
   801  		// by other steps in the build.
   802  		a1 := b.AutoAction(loaderstate, ModeInstall, depMode, p)
   803  		if load.InstallTargetDir(p) == load.ToTool {
   804  			a.Deps = append(a.Deps, a1.Deps...)
   805  			a1.Deps = append(a1.Deps, a)
   806  			tools = append(tools, a1)
   807  			continue
   808  		}
   809  		a.Deps = append(a.Deps, a1)
   810  	}
   811  	if len(tools) > 0 {
   812  		a = &Action{
   813  			Mode: "go install (tools)",
   814  			Deps: tools,
   815  		}
   816  	}
   817  
   818  	if cfg.BuildBuildmode == "shared" {
   819  		// Note: If buildmode=shared then only non-main packages
   820  		// are present in the pkgs list, so all the special case code about
   821  		// tools above did not apply, and a is just a simple Action
   822  		// with a list of Deps, one per package named in pkgs,
   823  		// the same as in runBuild.
   824  		a = b.buildmodeShared(loaderstate, ModeInstall, ModeInstall, patterns, pkgs, a)
   825  	}
   826  
   827  	b.Do(ctx, a)
   828  	base.ExitIfErrors()
   829  
   830  	// Success. If this command is 'go install' with no arguments
   831  	// and the current directory (the implicit argument) is a command,
   832  	// remove any leftover command binary from a previous 'go build'.
   833  	// The binary is installed; it's not needed here anymore.
   834  	// And worse it might be a stale copy, which you don't want to find
   835  	// instead of the installed one if $PATH contains dot.
   836  	// One way to view this behavior is that it is as if 'go install' first
   837  	// runs 'go build' and the moves the generated file to the install dir.
   838  	// See issue 9645.
   839  	if len(patterns) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
   840  		// Compute file 'go build' would have created.
   841  		// If it exists and is an executable file, remove it.
   842  		targ := pkgs[0].DefaultExecName()
   843  		targ += cfg.ExeSuffix
   844  		if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory
   845  			fi, err := os.Stat(targ)
   846  			if err == nil {
   847  				m := fi.Mode()
   848  				if m.IsRegular() {
   849  					if m&0111 != 0 || cfg.Goos == "windows" { // windows never sets executable bit
   850  						os.Remove(targ)
   851  					}
   852  				}
   853  			}
   854  		}
   855  	}
   856  }
   857  
   858  // installOutsideModule implements 'go install pkg@version'. It builds and
   859  // installs one or more main packages in module mode while ignoring any go.mod
   860  // in the current directory or parent directories.
   861  //
   862  // See golang.org/issue/40276 for details and rationale.
   863  func installOutsideModule(loaderstate *modload.State, ctx context.Context, args []string) {
   864  	loaderstate.ForceUseModules = true
   865  	loaderstate.RootMode = modload.NoRoot
   866  	modload.AllowMissingModuleImports(loaderstate)
   867  	modload.Init(loaderstate)
   868  	BuildInit(loaderstate)
   869  
   870  	// Load packages. Ignore non-main packages.
   871  	// Print a warning if an argument contains "..." and matches no main packages.
   872  	// PackagesAndErrors already prints warnings for patterns that don't match any
   873  	// packages, so be careful not to double print.
   874  	// TODO(golang.org/issue/40276): don't report errors loading non-main packages
   875  	// matched by a pattern.
   876  	pkgOpts := load.PackageOpts{MainOnly: true}
   877  	pkgs, err := load.PackagesAndErrorsOutsideModule(loaderstate, ctx, pkgOpts, args)
   878  	if err != nil {
   879  		base.Fatal(err)
   880  	}
   881  	load.CheckPackageErrors(pkgs)
   882  	patterns := make([]string, len(args))
   883  	for i, arg := range args {
   884  		patterns[i] = arg[:strings.Index(arg, "@")]
   885  	}
   886  
   887  	// Build and install the packages.
   888  	InstallPackages(loaderstate, ctx, patterns, pkgs)
   889  }
   890  
   891  // ExecCmd is the command to use to run user binaries.
   892  // Normally it is empty, meaning run the binaries directly.
   893  // If cross-compiling and running on a remote system or
   894  // simulator, it is typically go_GOOS_GOARCH_exec, with
   895  // the target GOOS and GOARCH substituted.
   896  // The -exec flag overrides these defaults.
   897  var ExecCmd []string
   898  
   899  // FindExecCmd derives the value of ExecCmd to use.
   900  // It returns that value and leaves ExecCmd set for direct use.
   901  func FindExecCmd() []string {
   902  	if ExecCmd != nil {
   903  		return ExecCmd
   904  	}
   905  	ExecCmd = []string{} // avoid work the second time
   906  	if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH {
   907  		return ExecCmd
   908  	}
   909  	path, err := pathcache.LookPath(fmt.Sprintf("go_%s_%s_exec", cfg.Goos, cfg.Goarch))
   910  	if err == nil {
   911  		ExecCmd = []string{path}
   912  	}
   913  	return ExecCmd
   914  }
   915  
   916  // A coverFlag is a flag.Value that also implies -cover.
   917  type coverFlag struct{ V flag.Value }
   918  
   919  func (f coverFlag) String() string { return f.V.String() }
   920  
   921  func (f coverFlag) Set(value string) error {
   922  	if err := f.V.Set(value); err != nil {
   923  		return err
   924  	}
   925  	cfg.BuildCover = true
   926  	return nil
   927  }
   928  
   929  type coverModeFlag string
   930  
   931  func (f *coverModeFlag) String() string { return string(*f) }
   932  func (f *coverModeFlag) Set(value string) error {
   933  	switch value {
   934  	case "", "set", "count", "atomic":
   935  		*f = coverModeFlag(value)
   936  		cfg.BuildCoverMode = value
   937  		return nil
   938  	default:
   939  		return errors.New(`valid modes are "set", "count", or "atomic"`)
   940  	}
   941  }
   942  
   943  // A commaListFlag is a flag.Value representing a comma-separated list.
   944  type commaListFlag struct{ Vals *[]string }
   945  
   946  func (f commaListFlag) String() string { return strings.Join(*f.Vals, ",") }
   947  
   948  func (f commaListFlag) Set(value string) error {
   949  	if value == "" {
   950  		*f.Vals = nil
   951  	} else {
   952  		*f.Vals = strings.Split(value, ",")
   953  	}
   954  	return nil
   955  }
   956  
   957  // A stringFlag is a flag.Value representing a single string.
   958  type stringFlag struct{ val *string }
   959  
   960  func (f stringFlag) String() string { return *f.val }
   961  func (f stringFlag) Set(value string) error {
   962  	*f.val = value
   963  	return nil
   964  }
   965  

View as plain text