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  func init() {
   242  	// break init cycle
   243  	CmdBuild.Run = runBuild
   244  	CmdInstall.Run = runInstall
   245  
   246  	CmdBuild.Flag.StringVar(&cfg.BuildO, "o", "", "output file or directory")
   247  
   248  	AddBuildFlags(CmdBuild, DefaultBuildFlags)
   249  	AddBuildFlags(CmdInstall, DefaultBuildFlags)
   250  	AddCoverFlags(CmdBuild, nil)
   251  	AddCoverFlags(CmdInstall, nil)
   252  }
   253  
   254  // Note that flags consulted by other parts of the code
   255  // (for example, buildV) are in cmd/go/internal/cfg.
   256  
   257  var (
   258  	forcedAsmflags   []string // internally-forced flags for cmd/asm
   259  	forcedGcflags    []string // internally-forced flags for cmd/compile
   260  	forcedLdflags    []string // internally-forced flags for cmd/link
   261  	forcedGccgoflags []string // internally-forced flags for gccgo
   262  )
   263  
   264  var BuildToolchain toolchain = noToolchain{}
   265  var ldBuildmode string
   266  
   267  // buildCompiler implements flag.Var.
   268  // It implements Set by updating both
   269  // BuildToolchain and buildContext.Compiler.
   270  type buildCompiler struct{}
   271  
   272  func (c buildCompiler) Set(value string) error {
   273  	switch value {
   274  	case "gc":
   275  		BuildToolchain = gcToolchain{}
   276  	case "gccgo":
   277  		BuildToolchain = gccgoToolchain{}
   278  	default:
   279  		return fmt.Errorf("unknown compiler %q", value)
   280  	}
   281  	cfg.BuildToolchainName = value
   282  	cfg.BuildContext.Compiler = value
   283  	return nil
   284  }
   285  
   286  func (c buildCompiler) String() string {
   287  	return cfg.BuildContext.Compiler
   288  }
   289  
   290  func init() {
   291  	switch build.Default.Compiler {
   292  	case "gc", "gccgo":
   293  		buildCompiler{}.Set(build.Default.Compiler)
   294  	}
   295  }
   296  
   297  type BuildFlagMask int
   298  
   299  const (
   300  	DefaultBuildFlags BuildFlagMask = 0
   301  	OmitModFlag       BuildFlagMask = 1 << iota
   302  	OmitModCommonFlags
   303  	OmitVFlag
   304  	OmitBuildOnlyFlags // Omit flags that only affect building packages
   305  	OmitJSONFlag
   306  )
   307  
   308  // AddBuildFlags adds the flags common to the build, clean, get,
   309  // install, list, run, and test commands.
   310  func AddBuildFlags(cmd *base.Command, mask BuildFlagMask) {
   311  	base.AddBuildFlagsNX(&cmd.Flag)
   312  	base.AddChdirFlag(&cmd.Flag)
   313  	cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "")
   314  	cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "")
   315  	if mask&OmitVFlag == 0 {
   316  		cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "")
   317  	}
   318  
   319  	cmd.Flag.BoolVar(&cfg.BuildASan, "asan", false, "")
   320  	cmd.Flag.Var(&load.BuildAsmflags, "asmflags", "")
   321  	cmd.Flag.Var(buildCompiler{}, "compiler", "")
   322  	cmd.Flag.StringVar(&cfg.BuildBuildmode, "buildmode", "default", "")
   323  	cmd.Flag.Var((*buildvcsFlag)(&cfg.BuildBuildvcs), "buildvcs", "")
   324  	cmd.Flag.Var(&load.BuildGcflags, "gcflags", "")
   325  	cmd.Flag.Var(&load.BuildGccgoflags, "gccgoflags", "")
   326  	if mask&OmitModFlag == 0 {
   327  		base.AddModFlag(&cmd.Flag)
   328  	}
   329  	if mask&OmitModCommonFlags == 0 {
   330  		base.AddModCommonFlags(&cmd.Flag)
   331  	} else {
   332  		// Add the overlay flag even when we don't add the rest of the mod common flags.
   333  		// This only affects 'go get' in GOPATH mode, but add the flag anyway for
   334  		// consistency.
   335  		cmd.Flag.StringVar(&fsys.OverlayFile, "overlay", "", "")
   336  	}
   337  	cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "")
   338  	if mask&(OmitBuildOnlyFlags|OmitJSONFlag) == 0 {
   339  		// TODO(#62250): OmitBuildOnlyFlags should apply to many more flags
   340  		// here, but we let a bunch of flags slip in before we realized that
   341  		// many of them don't make sense for most subcommands. We might even
   342  		// want to separate "AddBuildFlags" and "AddSelectionFlags".
   343  		cmd.Flag.BoolVar(&cfg.BuildJSON, "json", false, "")
   344  	}
   345  	cmd.Flag.Var(&load.BuildLdflags, "ldflags", "")
   346  	cmd.Flag.BoolVar(&cfg.BuildLinkshared, "linkshared", false, "")
   347  	cmd.Flag.BoolVar(&cfg.BuildMSan, "msan", false, "")
   348  	cmd.Flag.StringVar(&cfg.BuildPGO, "pgo", "auto", "")
   349  	cmd.Flag.StringVar(&cfg.BuildPkgdir, "pkgdir", "", "")
   350  	cmd.Flag.BoolVar(&cfg.BuildRace, "race", false, "")
   351  	cmd.Flag.Var((*tagsFlag)(&cfg.BuildContext.BuildTags), "tags", "")
   352  	cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildToolexec), "toolexec", "")
   353  	cmd.Flag.BoolVar(&cfg.BuildTrimpath, "trimpath", false, "")
   354  	cmd.Flag.BoolVar(&cfg.BuildWork, "work", false, "")
   355  
   356  	// Undocumented, unstable debugging flags.
   357  	cmd.Flag.StringVar(&cfg.DebugActiongraph, "debug-actiongraph", "", "")
   358  	cmd.Flag.StringVar(&cfg.DebugRuntimeTrace, "debug-runtime-trace", "", "")
   359  	cmd.Flag.StringVar(&cfg.DebugTrace, "debug-trace", "", "")
   360  }
   361  
   362  // AddCoverFlags adds coverage-related flags to "cmd".
   363  // We add -cover{mode,pkg} to the build command and only
   364  // -coverprofile to the test command.
   365  func AddCoverFlags(cmd *base.Command, coverProfileFlag *string) {
   366  	cmd.Flag.BoolVar(&cfg.BuildCover, "cover", false, "")
   367  	cmd.Flag.Var(coverFlag{(*coverModeFlag)(&cfg.BuildCoverMode)}, "covermode", "")
   368  	cmd.Flag.Var(coverFlag{commaListFlag{&cfg.BuildCoverPkg}}, "coverpkg", "")
   369  	if coverProfileFlag != nil {
   370  		cmd.Flag.Var(coverFlag{V: stringFlag{coverProfileFlag}}, "coverprofile", "")
   371  	}
   372  }
   373  
   374  // tagsFlag is the implementation of the -tags flag.
   375  type tagsFlag []string
   376  
   377  func (v *tagsFlag) Set(s string) error {
   378  	// For compatibility with Go 1.12 and earlier, allow "-tags='a b c'" or even just "-tags='a'".
   379  	if strings.Contains(s, " ") || strings.Contains(s, "'") {
   380  		return (*base.StringsFlag)(v).Set(s)
   381  	}
   382  
   383  	// Split on commas, ignore empty strings.
   384  	*v = []string{}
   385  	for s := range strings.SplitSeq(s, ",") {
   386  		if s != "" {
   387  			*v = append(*v, s)
   388  		}
   389  	}
   390  	return nil
   391  }
   392  
   393  func (v *tagsFlag) String() string {
   394  	return "<TagsFlag>"
   395  }
   396  
   397  // buildvcsFlag is the implementation of the -buildvcs flag.
   398  type buildvcsFlag string
   399  
   400  func (f *buildvcsFlag) IsBoolFlag() bool { return true } // allow -buildvcs (without arguments)
   401  
   402  func (f *buildvcsFlag) Set(s string) error {
   403  	// https://go.dev/issue/51748: allow "-buildvcs=auto",
   404  	// in addition to the usual "true" and "false".
   405  	if s == "" || s == "auto" {
   406  		*f = "auto"
   407  		return nil
   408  	}
   409  
   410  	b, err := strconv.ParseBool(s)
   411  	if err != nil {
   412  		return errors.New("value is neither 'auto' nor a valid bool")
   413  	}
   414  	*f = (buildvcsFlag)(strconv.FormatBool(b)) // convert to canonical "true" or "false"
   415  	return nil
   416  }
   417  
   418  func (f *buildvcsFlag) String() string { return string(*f) }
   419  
   420  // fileExtSplit expects a filename and returns the name
   421  // and ext (without the dot). If the file has no
   422  // extension, ext will be empty.
   423  func fileExtSplit(file string) (name, ext string) {
   424  	dotExt := filepath.Ext(file)
   425  	name = file[:len(file)-len(dotExt)]
   426  	if dotExt != "" {
   427  		ext = dotExt[1:]
   428  	}
   429  	return
   430  }
   431  
   432  func pkgsMain(pkgs []*load.Package) (res []*load.Package) {
   433  	for _, p := range pkgs {
   434  		if p.Name == "main" {
   435  			res = append(res, p)
   436  		}
   437  	}
   438  	return res
   439  }
   440  
   441  func pkgsNotMain(pkgs []*load.Package) (res []*load.Package) {
   442  	for _, p := range pkgs {
   443  		if p.Name != "main" {
   444  			res = append(res, p)
   445  		}
   446  	}
   447  	return res
   448  }
   449  
   450  func oneMainPkg(pkgs []*load.Package) []*load.Package {
   451  	if len(pkgs) != 1 || pkgs[0].Name != "main" {
   452  		base.Fatalf("-buildmode=%s requires exactly one main package", cfg.BuildBuildmode)
   453  	}
   454  	return pkgs
   455  }
   456  
   457  var pkgsFilter = func(pkgs []*load.Package) []*load.Package { return pkgs }
   458  
   459  func runBuild(ctx context.Context, cmd *base.Command, args []string) {
   460  	moduleLoaderState := modload.NewState()
   461  	moduleLoaderState.InitWorkfile()
   462  	BuildInit(moduleLoaderState)
   463  	b := NewBuilder("", moduleLoaderState.VendorDirOrEmpty)
   464  	defer func() {
   465  		if err := b.Close(); err != nil {
   466  			base.Fatal(err)
   467  		}
   468  	}()
   469  
   470  	pkgs := load.PackagesAndErrors(moduleLoaderState, ctx, load.PackageOpts{AutoVCS: true}, args)
   471  	load.CheckPackageErrors(pkgs)
   472  
   473  	explicitO := len(cfg.BuildO) > 0
   474  
   475  	if len(pkgs) == 1 && pkgs[0].Name == "main" && cfg.BuildO == "" {
   476  		cfg.BuildO = pkgs[0].DefaultExecName()
   477  		cfg.BuildO += cfg.ExeSuffix
   478  	}
   479  
   480  	// sanity check some often mis-used options
   481  	switch cfg.BuildContext.Compiler {
   482  	case "gccgo":
   483  		if load.BuildGcflags.Present() {
   484  			fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
   485  		}
   486  		if load.BuildLdflags.Present() {
   487  			fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
   488  		}
   489  	case "gc":
   490  		if load.BuildGccgoflags.Present() {
   491  			fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
   492  		}
   493  	}
   494  
   495  	depMode := ModeBuild
   496  
   497  	pkgs = omitTestOnly(pkgsFilter(pkgs))
   498  
   499  	// Special case -o /dev/null by not writing at all.
   500  	if base.IsNull(cfg.BuildO) {
   501  		cfg.BuildO = ""
   502  	}
   503  
   504  	if cfg.BuildCover {
   505  		load.PrepareForCoverageBuild(moduleLoaderState, pkgs)
   506  	}
   507  
   508  	if cfg.BuildO != "" {
   509  		// If the -o name exists and is a directory or
   510  		// ends with a slash or backslash, then
   511  		// write all main packages to that directory.
   512  		// Otherwise require only a single package be built.
   513  		if fi, err := os.Stat(cfg.BuildO); (err == nil && fi.IsDir()) ||
   514  			strings.HasSuffix(cfg.BuildO, "/") ||
   515  			strings.HasSuffix(cfg.BuildO, string(os.PathSeparator)) {
   516  			if !explicitO {
   517  				base.Fatalf("go: build output %q already exists and is a directory", cfg.BuildO)
   518  			}
   519  			a := &Action{Mode: "go build"}
   520  			for _, p := range pkgs {
   521  				if p.Name != "main" {
   522  					continue
   523  				}
   524  
   525  				p.Target = filepath.Join(cfg.BuildO, p.DefaultExecName())
   526  				p.Target += cfg.ExeSuffix
   527  				p.Stale = true
   528  				p.StaleReason = "build -o flag in use"
   529  				a.Deps = append(a.Deps, b.AutoAction(moduleLoaderState, ModeInstall, depMode, p))
   530  			}
   531  			if len(a.Deps) == 0 {
   532  				base.Fatalf("go: no main packages to build")
   533  			}
   534  			b.Do(ctx, a)
   535  			return
   536  		}
   537  		if len(pkgs) > 1 {
   538  			base.Fatalf("go: cannot write multiple packages to non-directory %s", cfg.BuildO)
   539  		} else if len(pkgs) == 0 {
   540  			base.Fatalf("no packages to build")
   541  		}
   542  		p := pkgs[0]
   543  		p.Target = cfg.BuildO
   544  		p.Stale = true // must build - not up to date
   545  		p.StaleReason = "build -o flag in use"
   546  		a := b.AutoAction(moduleLoaderState, ModeInstall, depMode, p)
   547  		b.Do(ctx, a)
   548  		return
   549  	}
   550  
   551  	a := &Action{Mode: "go build"}
   552  	for _, p := range pkgs {
   553  		a.Deps = append(a.Deps, b.AutoAction(moduleLoaderState, ModeBuild, depMode, p))
   554  	}
   555  	if cfg.BuildBuildmode == "shared" {
   556  		a = b.buildmodeShared(moduleLoaderState, ModeBuild, depMode, args, pkgs, a)
   557  	}
   558  	b.Do(ctx, a)
   559  }
   560  
   561  var CmdInstall = &base.Command{
   562  	UsageLine: "go install [build flags] [packages]",
   563  	Short:     "compile and install packages and dependencies",
   564  	Long: `
   565  Install compiles and installs the packages named by the import paths.
   566  
   567  Executables are installed in the directory named by the GOBIN environment
   568  variable, which defaults to $GOPATH/bin or $HOME/go/bin if the GOPATH
   569  environment variable is not set. Executables in $GOROOT
   570  are installed in $GOROOT/bin or $GOTOOLDIR instead of $GOBIN.
   571  Cross compiled binaries are installed in $GOOS_$GOARCH subdirectories
   572  of the above.
   573  
   574  If the arguments have version suffixes (like @latest or @v1.0.0), "go install"
   575  builds packages in module-aware mode, ignoring the go.mod file in the current
   576  directory or any parent directory, if there is one. This is useful for
   577  installing executables without affecting the dependencies of the main module.
   578  To eliminate ambiguity about which module versions are used in the build, the
   579  arguments must satisfy the following constraints:
   580  
   581  - Arguments must be package paths or package patterns (with "..." wildcards).
   582  They must not be standard packages (like fmt), meta-patterns (std, cmd,
   583  all), or relative or absolute file paths.
   584  
   585  - All arguments must have the same version suffix. Different queries are not
   586  allowed, even if they refer to the same version.
   587  
   588  - All arguments must refer to packages in the same module at the same version.
   589  
   590  - Package path arguments must refer to main packages. Pattern arguments
   591  will only match main packages.
   592  
   593  - No module is considered the "main" module. If the module containing
   594  packages named on the command line has a go.mod file, it must not contain
   595  directives (replace and exclude) that would cause it to be interpreted
   596  differently than if it were the main module. The module must not require
   597  a higher version of itself.
   598  
   599  - Vendor directories are not used in any module. (Vendor directories are not
   600  included in the module zip files downloaded by 'go install'.)
   601  
   602  If the arguments don't have version suffixes, "go install" may run in
   603  module-aware mode or GOPATH mode, depending on the GO111MODULE environment
   604  variable and the presence of a go.mod file. See 'go help modules' for details.
   605  If module-aware mode is enabled, "go install" runs in the context of the main
   606  module.
   607  
   608  When module-aware mode is disabled, non-main packages are installed in the
   609  directory $GOPATH/pkg/$GOOS_$GOARCH. When module-aware mode is enabled,
   610  non-main packages are built and cached but not installed.
   611  
   612  Before Go 1.20, the standard library was installed to
   613  $GOROOT/pkg/$GOOS_$GOARCH.
   614  Starting in Go 1.20, the standard library is built and cached but not installed.
   615  Setting GODEBUG=installgoroot=all restores the use of
   616  $GOROOT/pkg/$GOOS_$GOARCH.
   617  
   618  For more about build flags, see 'go help build'.
   619  
   620  For more about specifying packages, see 'go help packages'.
   621  
   622  See also: go build, go get, go clean.
   623  	`,
   624  }
   625  
   626  // libname returns the filename to use for the shared library when using
   627  // -buildmode=shared. The rules we use are:
   628  // Use arguments for special 'meta' packages:
   629  //
   630  //	std --> libstd.so
   631  //	std cmd --> libstd,cmd.so
   632  //
   633  // A single non-meta argument with trailing "/..." is special cased:
   634  //
   635  //	foo/... --> libfoo.so
   636  //	(A relative path like "./..."  expands the "." first)
   637  //
   638  // Use import paths for other cases, changing '/' to '-':
   639  //
   640  //	somelib --> libsubdir-somelib.so
   641  //	./ or ../ --> libsubdir-somelib.so
   642  //	gopkg.in/tomb.v2 -> libgopkg.in-tomb.v2.so
   643  //	a/... b/... ---> liba/c,b/d.so - all matching import paths
   644  //
   645  // Name parts are joined with ','.
   646  func libname(args []string, pkgs []*load.Package) (string, error) {
   647  	var libname string
   648  	appendName := func(arg string) {
   649  		if libname == "" {
   650  			libname = arg
   651  		} else {
   652  			libname += "," + arg
   653  		}
   654  	}
   655  	var haveNonMeta bool
   656  	for _, arg := range args {
   657  		if search.IsMetaPackage(arg) {
   658  			appendName(arg)
   659  		} else {
   660  			haveNonMeta = true
   661  		}
   662  	}
   663  	if len(libname) == 0 { // non-meta packages only. use import paths
   664  		if len(args) == 1 && strings.HasSuffix(args[0], "/...") {
   665  			// Special case of "foo/..." as mentioned above.
   666  			arg := strings.TrimSuffix(args[0], "/...")
   667  			if build.IsLocalImport(arg) {
   668  				cwd, _ := os.Getwd()
   669  				bp, _ := cfg.BuildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
   670  				if bp.ImportPath != "" && bp.ImportPath != "." {
   671  					arg = bp.ImportPath
   672  				}
   673  			}
   674  			appendName(strings.ReplaceAll(arg, "/", "-"))
   675  		} else {
   676  			for _, pkg := range pkgs {
   677  				appendName(strings.ReplaceAll(pkg.ImportPath, "/", "-"))
   678  			}
   679  		}
   680  	} else if haveNonMeta { // have both meta package and a non-meta one
   681  		return "", errors.New("mixing of meta and non-meta packages is not allowed")
   682  	}
   683  	// TODO(mwhudson): Needs to change for platforms that use different naming
   684  	// conventions...
   685  	return "lib" + libname + ".so", nil
   686  }
   687  
   688  func runInstall(ctx context.Context, cmd *base.Command, args []string) {
   689  	moduleLoaderState := modload.NewState()
   690  	for _, arg := range args {
   691  		if strings.Contains(arg, "@") && !build.IsLocalImport(arg) && !filepath.IsAbs(arg) {
   692  			installOutsideModule(moduleLoaderState, ctx, args)
   693  			return
   694  		}
   695  	}
   696  
   697  	moduleLoaderState.InitWorkfile()
   698  	BuildInit(moduleLoaderState)
   699  	pkgs := load.PackagesAndErrors(moduleLoaderState, ctx, load.PackageOpts{AutoVCS: true}, args)
   700  	if cfg.ModulesEnabled && !moduleLoaderState.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 _, ok := errors.AsType[*modload.ImportMissingError](pkg.Error); !ok {
   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(moduleLoaderState, pkgs)
   726  	}
   727  
   728  	InstallPackages(moduleLoaderState, 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(loaderstate *modload.State, 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("", loaderstate.VendorDirOrEmpty)
   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(loaderstate, 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(loaderstate, 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(loaderstate *modload.State, ctx context.Context, args []string) {
   862  	loaderstate.ForceUseModules = true
   863  	loaderstate.RootMode = modload.NoRoot
   864  	loaderstate.AllowMissingModuleImports()
   865  	modload.Init(loaderstate)
   866  	BuildInit(loaderstate)
   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(loaderstate, 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(loaderstate, 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