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  	modload.InitWorkfile()
   463  	BuildInit()
   464  	b := NewBuilder("")
   465  	defer func() {
   466  		if err := b.Close(); err != nil {
   467  			base.Fatal(err)
   468  		}
   469  	}()
   470  
   471  	pkgs := load.PackagesAndErrors(ctx, load.PackageOpts{AutoVCS: true}, args)
   472  	load.CheckPackageErrors(pkgs)
   473  
   474  	explicitO := len(cfg.BuildO) > 0
   475  
   476  	if len(pkgs) == 1 && pkgs[0].Name == "main" && cfg.BuildO == "" {
   477  		cfg.BuildO = pkgs[0].DefaultExecName()
   478  		cfg.BuildO += cfg.ExeSuffix
   479  	}
   480  
   481  	// sanity check some often mis-used options
   482  	switch cfg.BuildContext.Compiler {
   483  	case "gccgo":
   484  		if load.BuildGcflags.Present() {
   485  			fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
   486  		}
   487  		if load.BuildLdflags.Present() {
   488  			fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
   489  		}
   490  	case "gc":
   491  		if load.BuildGccgoflags.Present() {
   492  			fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
   493  		}
   494  	}
   495  
   496  	depMode := ModeBuild
   497  
   498  	pkgs = omitTestOnly(pkgsFilter(pkgs))
   499  
   500  	// Special case -o /dev/null by not writing at all.
   501  	if base.IsNull(cfg.BuildO) {
   502  		cfg.BuildO = ""
   503  	}
   504  
   505  	if cfg.BuildCover {
   506  		load.PrepareForCoverageBuild(pkgs)
   507  	}
   508  
   509  	if cfg.BuildO != "" {
   510  		// If the -o name exists and is a directory or
   511  		// ends with a slash or backslash, then
   512  		// write all main packages to that directory.
   513  		// Otherwise require only a single package be built.
   514  		if fi, err := os.Stat(cfg.BuildO); (err == nil && fi.IsDir()) ||
   515  			strings.HasSuffix(cfg.BuildO, "/") ||
   516  			strings.HasSuffix(cfg.BuildO, string(os.PathSeparator)) {
   517  			if !explicitO {
   518  				base.Fatalf("go: build output %q already exists and is a directory", cfg.BuildO)
   519  			}
   520  			a := &Action{Mode: "go build"}
   521  			for _, p := range pkgs {
   522  				if p.Name != "main" {
   523  					continue
   524  				}
   525  
   526  				p.Target = filepath.Join(cfg.BuildO, p.DefaultExecName())
   527  				p.Target += cfg.ExeSuffix
   528  				p.Stale = true
   529  				p.StaleReason = "build -o flag in use"
   530  				a.Deps = append(a.Deps, b.AutoAction(ModeInstall, depMode, p))
   531  			}
   532  			if len(a.Deps) == 0 {
   533  				base.Fatalf("go: no main packages to build")
   534  			}
   535  			b.Do(ctx, a)
   536  			return
   537  		}
   538  		if len(pkgs) > 1 {
   539  			base.Fatalf("go: cannot write multiple packages to non-directory %s", cfg.BuildO)
   540  		} else if len(pkgs) == 0 {
   541  			base.Fatalf("no packages to build")
   542  		}
   543  		p := pkgs[0]
   544  		p.Target = cfg.BuildO
   545  		p.Stale = true // must build - not up to date
   546  		p.StaleReason = "build -o flag in use"
   547  		a := b.AutoAction(ModeInstall, depMode, p)
   548  		b.Do(ctx, a)
   549  		return
   550  	}
   551  
   552  	a := &Action{Mode: "go build"}
   553  	for _, p := range pkgs {
   554  		a.Deps = append(a.Deps, b.AutoAction(ModeBuild, depMode, p))
   555  	}
   556  	if cfg.BuildBuildmode == "shared" {
   557  		a = b.buildmodeShared(ModeBuild, depMode, args, pkgs, a)
   558  	}
   559  	b.Do(ctx, a)
   560  }
   561  
   562  var CmdInstall = &base.Command{
   563  	UsageLine: "go install [build flags] [packages]",
   564  	Short:     "compile and install packages and dependencies",
   565  	Long: `
   566  Install compiles and installs the packages named by the import paths.
   567  
   568  Executables are installed in the directory named by the GOBIN environment
   569  variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH
   570  environment variable is not set. Executables in $GOROOT
   571  are installed in $GOROOT/bin or $GOTOOLDIR instead of $GOBIN.
   572  Cross compiled binaries are installed in $GOOS_$GOARCH subdirectories
   573  of the above.
   574  
   575  If the arguments have version suffixes (like @latest or @v1.0.0), "go install"
   576  builds packages in module-aware mode, ignoring the go.mod file in the current
   577  directory or any parent directory, if there is one. This is useful for
   578  installing executables without affecting the dependencies of the main module.
   579  To eliminate ambiguity about which module versions are used in the build, the
   580  arguments must satisfy the following constraints:
   581  
   582  - Arguments must be package paths or package patterns (with "..." wildcards).
   583  They must not be standard packages (like fmt), meta-patterns (std, cmd,
   584  all), or relative or absolute file paths.
   585  
   586  - All arguments must have the same version suffix. Different queries are not
   587  allowed, even if they refer to the same version.
   588  
   589  - All arguments must refer to packages in the same module at the same version.
   590  
   591  - Package path arguments must refer to main packages. Pattern arguments
   592  will only match main packages.
   593  
   594  - No module is considered the "main" module. If the module containing
   595  packages named on the command line has a go.mod file, it must not contain
   596  directives (replace and exclude) that would cause it to be interpreted
   597  differently than if it were the main module. The module must not require
   598  a higher version of itself.
   599  
   600  - Vendor directories are not used in any module. (Vendor directories are not
   601  included in the module zip files downloaded by 'go install'.)
   602  
   603  If the arguments don't have version suffixes, "go install" may run in
   604  module-aware mode or GOPATH mode, depending on the GO111MODULE environment
   605  variable and the presence of a go.mod file. See 'go help modules' for details.
   606  If module-aware mode is enabled, "go install" runs in the context of the main
   607  module.
   608  
   609  When module-aware mode is disabled, non-main packages are installed in the
   610  directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled,
   611  non-main packages are built and cached but not installed.
   612  
   613  Before Go 1.20, the standard library was installed to
   614  $GOROOT/pkg/$GOOS_$GOARCH.
   615  Starting in Go 1.20, the standard library is built and cached but not installed.
   616  Setting GODEBUG=installgoroot=all restores the use of
   617  $GOROOT/pkg/$GOOS_$GOARCH.
   618  
   619  For more about build flags, see 'go help build'.
   620  
   621  For more about specifying packages, see 'go help packages'.
   622  
   623  See also: go build, go get, go clean.
   624  	`,
   625  }
   626  
   627  // libname returns the filename to use for the shared library when using
   628  // -buildmode=shared. The rules we use are:
   629  // Use arguments for special 'meta' packages:
   630  //
   631  //	std --> libstd.so
   632  //	std cmd --> libstd,cmd.so
   633  //
   634  // A single non-meta argument with trailing "/..." is special cased:
   635  //
   636  //	foo/... --> libfoo.so
   637  //	(A relative path like "./..."  expands the "." first)
   638  //
   639  // Use import paths for other cases, changing '/' to '-':
   640  //
   641  //	somelib --> libsubdir-somelib.so
   642  //	./ or ../ --> libsubdir-somelib.so
   643  //	gopkg.in/tomb.v2 -> libgopkg.in-tomb.v2.so
   644  //	a/... b/... ---> liba/c,b/d.so - all matching import paths
   645  //
   646  // Name parts are joined with ','.
   647  func libname(args []string, pkgs []*load.Package) (string, error) {
   648  	var libname string
   649  	appendName := func(arg string) {
   650  		if libname == "" {
   651  			libname = arg
   652  		} else {
   653  			libname += "," + arg
   654  		}
   655  	}
   656  	var haveNonMeta bool
   657  	for _, arg := range args {
   658  		if search.IsMetaPackage(arg) {
   659  			appendName(arg)
   660  		} else {
   661  			haveNonMeta = true
   662  		}
   663  	}
   664  	if len(libname) == 0 { // non-meta packages only. use import paths
   665  		if len(args) == 1 && strings.HasSuffix(args[0], "/...") {
   666  			// Special case of "foo/..." as mentioned above.
   667  			arg := strings.TrimSuffix(args[0], "/...")
   668  			if build.IsLocalImport(arg) {
   669  				cwd, _ := os.Getwd()
   670  				bp, _ := cfg.BuildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
   671  				if bp.ImportPath != "" && bp.ImportPath != "." {
   672  					arg = bp.ImportPath
   673  				}
   674  			}
   675  			appendName(strings.ReplaceAll(arg, "/", "-"))
   676  		} else {
   677  			for _, pkg := range pkgs {
   678  				appendName(strings.ReplaceAll(pkg.ImportPath, "/", "-"))
   679  			}
   680  		}
   681  	} else if haveNonMeta { // have both meta package and a non-meta one
   682  		return "", errors.New("mixing of meta and non-meta packages is not allowed")
   683  	}
   684  	// TODO(mwhudson): Needs to change for platforms that use different naming
   685  	// conventions...
   686  	return "lib" + libname + ".so", nil
   687  }
   688  
   689  func runInstall(ctx context.Context, cmd *base.Command, args []string) {
   690  	for _, arg := range args {
   691  		if strings.Contains(arg, "@") && !build.IsLocalImport(arg) && !filepath.IsAbs(arg) {
   692  			installOutsideModule(ctx, args)
   693  			return
   694  		}
   695  	}
   696  
   697  	modload.InitWorkfile()
   698  	BuildInit()
   699  	pkgs := load.PackagesAndErrors(ctx, load.PackageOpts{AutoVCS: true}, args)
   700  	if cfg.ModulesEnabled && !modload.HasModRoot() {
   701  		haveErrors := false
   702  		allMissingErrors := true
   703  		for _, pkg := range pkgs {
   704  			if pkg.Error == nil {
   705  				continue
   706  			}
   707  			haveErrors = true
   708  			if missingErr := (*modload.ImportMissingError)(nil); !errors.As(pkg.Error, &missingErr) {
   709  				allMissingErrors = false
   710  				break
   711  			}
   712  		}
   713  		if haveErrors && allMissingErrors {
   714  			latestArgs := make([]string, len(args))
   715  			for i := range args {
   716  				latestArgs[i] = args[i] + "@latest"
   717  			}
   718  			hint := strings.Join(latestArgs, " ")
   719  			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)
   720  		}
   721  	}
   722  	load.CheckPackageErrors(pkgs)
   723  
   724  	if cfg.BuildCover {
   725  		load.PrepareForCoverageBuild(pkgs)
   726  	}
   727  
   728  	InstallPackages(ctx, args, pkgs)
   729  }
   730  
   731  // omitTestOnly returns pkgs with test-only packages removed.
   732  func omitTestOnly(pkgs []*load.Package) []*load.Package {
   733  	var list []*load.Package
   734  	for _, p := range pkgs {
   735  		if len(p.GoFiles)+len(p.CgoFiles) == 0 && !p.Internal.CmdlinePkgLiteral {
   736  			// Package has no source files,
   737  			// perhaps due to build tags or perhaps due to only having *_test.go files.
   738  			// Also, it is only being processed as the result of a wildcard match
   739  			// like ./..., not because it was listed as a literal path on the command line.
   740  			// Ignore it.
   741  			continue
   742  		}
   743  		list = append(list, p)
   744  	}
   745  	return list
   746  }
   747  
   748  func InstallPackages(ctx context.Context, patterns []string, pkgs []*load.Package) {
   749  	ctx, span := trace.StartSpan(ctx, "InstallPackages "+strings.Join(patterns, " "))
   750  	defer span.Done()
   751  
   752  	if cfg.GOBIN != "" && !filepath.IsAbs(cfg.GOBIN) {
   753  		base.Fatalf("cannot install, GOBIN must be an absolute path")
   754  	}
   755  
   756  	pkgs = omitTestOnly(pkgsFilter(pkgs))
   757  	for _, p := range pkgs {
   758  		if p.Target == "" {
   759  			switch {
   760  			case p.Name != "main" && p.Internal.Local && p.ConflictDir == "":
   761  				// Non-executables outside GOPATH need not have a target:
   762  				// we can use the cache to hold the built package archive for use in future builds.
   763  				// The ones inside GOPATH should have a target (in GOPATH/pkg)
   764  				// or else something is wrong and worth reporting (like a ConflictDir).
   765  			case p.Name != "main" && p.Module != nil:
   766  				// Non-executables have no target (except the cache) when building with modules.
   767  			case p.Name != "main" && p.Standard && p.Internal.Build.PkgObj == "":
   768  				// Most packages in std do not need an installed .a, because they can be
   769  				// rebuilt and used directly from the build cache.
   770  				// A few targets (notably those using cgo) still do need to be installed
   771  				// in case the user's environment lacks a C compiler.
   772  			case p.Internal.GobinSubdir:
   773  				base.Errorf("go: cannot install cross-compiled binaries when GOBIN is set")
   774  			case p.Internal.CmdlineFiles:
   775  				base.Errorf("go: no install location for .go files listed on command line (GOBIN not set)")
   776  			case p.ConflictDir != "":
   777  				base.Errorf("go: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
   778  			default:
   779  				base.Errorf("go: no install location for directory %s outside GOPATH\n"+
   780  					"\tFor more details see: 'go help gopath'", p.Dir)
   781  			}
   782  		}
   783  	}
   784  	base.ExitIfErrors()
   785  
   786  	b := NewBuilder("")
   787  	defer func() {
   788  		if err := b.Close(); err != nil {
   789  			base.Fatal(err)
   790  		}
   791  	}()
   792  
   793  	depMode := ModeBuild
   794  	a := &Action{Mode: "go install"}
   795  	var tools []*Action
   796  	for _, p := range pkgs {
   797  		// If p is a tool, delay the installation until the end of the build.
   798  		// This avoids installing assemblers/compilers that are being executed
   799  		// by other steps in the build.
   800  		a1 := b.AutoAction(ModeInstall, depMode, p)
   801  		if load.InstallTargetDir(p) == load.ToTool {
   802  			a.Deps = append(a.Deps, a1.Deps...)
   803  			a1.Deps = append(a1.Deps, a)
   804  			tools = append(tools, a1)
   805  			continue
   806  		}
   807  		a.Deps = append(a.Deps, a1)
   808  	}
   809  	if len(tools) > 0 {
   810  		a = &Action{
   811  			Mode: "go install (tools)",
   812  			Deps: tools,
   813  		}
   814  	}
   815  
   816  	if cfg.BuildBuildmode == "shared" {
   817  		// Note: If buildmode=shared then only non-main packages
   818  		// are present in the pkgs list, so all the special case code about
   819  		// tools above did not apply, and a is just a simple Action
   820  		// with a list of Deps, one per package named in pkgs,
   821  		// the same as in runBuild.
   822  		a = b.buildmodeShared(ModeInstall, ModeInstall, patterns, pkgs, a)
   823  	}
   824  
   825  	b.Do(ctx, a)
   826  	base.ExitIfErrors()
   827  
   828  	// Success. If this command is 'go install' with no arguments
   829  	// and the current directory (the implicit argument) is a command,
   830  	// remove any leftover command binary from a previous 'go build'.
   831  	// The binary is installed; it's not needed here anymore.
   832  	// And worse it might be a stale copy, which you don't want to find
   833  	// instead of the installed one if $PATH contains dot.
   834  	// One way to view this behavior is that it is as if 'go install' first
   835  	// runs 'go build' and the moves the generated file to the install dir.
   836  	// See issue 9645.
   837  	if len(patterns) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
   838  		// Compute file 'go build' would have created.
   839  		// If it exists and is an executable file, remove it.
   840  		targ := pkgs[0].DefaultExecName()
   841  		targ += cfg.ExeSuffix
   842  		if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory
   843  			fi, err := os.Stat(targ)
   844  			if err == nil {
   845  				m := fi.Mode()
   846  				if m.IsRegular() {
   847  					if m&0111 != 0 || cfg.Goos == "windows" { // windows never sets executable bit
   848  						os.Remove(targ)
   849  					}
   850  				}
   851  			}
   852  		}
   853  	}
   854  }
   855  
   856  // installOutsideModule implements 'go install pkg@version'. It builds and
   857  // installs one or more main packages in module mode while ignoring any go.mod
   858  // in the current directory or parent directories.
   859  //
   860  // See golang.org/issue/40276 for details and rationale.
   861  func installOutsideModule(ctx context.Context, args []string) {
   862  	modload.ForceUseModules = true
   863  	modload.RootMode = modload.NoRoot
   864  	modload.AllowMissingModuleImports()
   865  	modload.Init()
   866  	BuildInit()
   867  
   868  	// Load packages. Ignore non-main packages.
   869  	// Print a warning if an argument contains "..." and matches no main packages.
   870  	// PackagesAndErrors already prints warnings for patterns that don't match any
   871  	// packages, so be careful not to double print.
   872  	// TODO(golang.org/issue/40276): don't report errors loading non-main packages
   873  	// matched by a pattern.
   874  	pkgOpts := load.PackageOpts{MainOnly: true}
   875  	pkgs, err := load.PackagesAndErrorsOutsideModule(ctx, pkgOpts, args)
   876  	if err != nil {
   877  		base.Fatal(err)
   878  	}
   879  	load.CheckPackageErrors(pkgs)
   880  	patterns := make([]string, len(args))
   881  	for i, arg := range args {
   882  		patterns[i] = arg[:strings.Index(arg, "@")]
   883  	}
   884  
   885  	// Build and install the packages.
   886  	InstallPackages(ctx, patterns, pkgs)
   887  }
   888  
   889  // ExecCmd is the command to use to run user binaries.
   890  // Normally it is empty, meaning run the binaries directly.
   891  // If cross-compiling and running on a remote system or
   892  // simulator, it is typically go_GOOS_GOARCH_exec, with
   893  // the target GOOS and GOARCH substituted.
   894  // The -exec flag overrides these defaults.
   895  var ExecCmd []string
   896  
   897  // FindExecCmd derives the value of ExecCmd to use.
   898  // It returns that value and leaves ExecCmd set for direct use.
   899  func FindExecCmd() []string {
   900  	if ExecCmd != nil {
   901  		return ExecCmd
   902  	}
   903  	ExecCmd = []string{} // avoid work the second time
   904  	if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH {
   905  		return ExecCmd
   906  	}
   907  	path, err := pathcache.LookPath(fmt.Sprintf("go_%s_%s_exec", cfg.Goos, cfg.Goarch))
   908  	if err == nil {
   909  		ExecCmd = []string{path}
   910  	}
   911  	return ExecCmd
   912  }
   913  
   914  // A coverFlag is a flag.Value that also implies -cover.
   915  type coverFlag struct{ V flag.Value }
   916  
   917  func (f coverFlag) String() string { return f.V.String() }
   918  
   919  func (f coverFlag) Set(value string) error {
   920  	if err := f.V.Set(value); err != nil {
   921  		return err
   922  	}
   923  	cfg.BuildCover = true
   924  	return nil
   925  }
   926  
   927  type coverModeFlag string
   928  
   929  func (f *coverModeFlag) String() string { return string(*f) }
   930  func (f *coverModeFlag) Set(value string) error {
   931  	switch value {
   932  	case "", "set", "count", "atomic":
   933  		*f = coverModeFlag(value)
   934  		cfg.BuildCoverMode = value
   935  		return nil
   936  	default:
   937  		return errors.New(`valid modes are "set", "count", or "atomic"`)
   938  	}
   939  }
   940  
   941  // A commaListFlag is a flag.Value representing a comma-separated list.
   942  type commaListFlag struct{ Vals *[]string }
   943  
   944  func (f commaListFlag) String() string { return strings.Join(*f.Vals, ",") }
   945  
   946  func (f commaListFlag) Set(value string) error {
   947  	if value == "" {
   948  		*f.Vals = nil
   949  	} else {
   950  		*f.Vals = strings.Split(value, ",")
   951  	}
   952  	return nil
   953  }
   954  
   955  // A stringFlag is a flag.Value representing a single string.
   956  type stringFlag struct{ val *string }
   957  
   958  func (f stringFlag) String() string { return *f.val }
   959  func (f stringFlag) Set(value string) error {
   960  	*f.val = value
   961  	return nil
   962  }
   963  

View as plain text