github.com/Filosottile/go@v0.0.0-20170906193555-dbed9972d994/src/cmd/go/internal/work/build.go (about)

     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  	"bufio"
     9  	"bytes"
    10  	"container/heap"
    11  	"debug/elf"
    12  	"errors"
    13  	"flag"
    14  	"fmt"
    15  	"go/build"
    16  	"io"
    17  	"io/ioutil"
    18  	"log"
    19  	"os"
    20  	"os/exec"
    21  	"path"
    22  	"path/filepath"
    23  	"regexp"
    24  	"runtime"
    25  	"strconv"
    26  	"strings"
    27  	"sync"
    28  	"time"
    29  
    30  	"cmd/go/internal/base"
    31  	"cmd/go/internal/buildid"
    32  	"cmd/go/internal/cfg"
    33  	"cmd/go/internal/load"
    34  	"cmd/go/internal/str"
    35  )
    36  
    37  var CmdBuild = &base.Command{
    38  	UsageLine: "build [-o output] [-i] [build flags] [packages]",
    39  	Short:     "compile packages and dependencies",
    40  	Long: `
    41  Build compiles the packages named by the import paths,
    42  along with their dependencies, but it does not install the results.
    43  
    44  If the arguments to build are a list of .go files, build treats
    45  them as a list of source files specifying a single package.
    46  
    47  When compiling a single main package, build writes
    48  the resulting executable to an output file named after
    49  the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe')
    50  or the source code directory ('go build unix/sam' writes 'sam' or 'sam.exe').
    51  The '.exe' suffix is added when writing a Windows executable.
    52  
    53  When compiling multiple packages or a single non-main package,
    54  build compiles the packages but discards the resulting object,
    55  serving only as a check that the packages can be built.
    56  
    57  When compiling packages, build ignores files that end in '_test.go'.
    58  
    59  The -o flag, only allowed when compiling a single package,
    60  forces build to write the resulting executable or object
    61  to the named output file, instead of the default behavior described
    62  in the last two paragraphs.
    63  
    64  The -i flag installs the packages that are dependencies of the target.
    65  
    66  The build flags are shared by the build, clean, get, install, list, run,
    67  and test commands:
    68  
    69  	-a
    70  		force rebuilding of packages that are already up-to-date.
    71  	-n
    72  		print the commands but do not run them.
    73  	-p n
    74  		the number of programs, such as build commands or
    75  		test binaries, that can be run in parallel.
    76  		The default is the number of CPUs available.
    77  	-race
    78  		enable data race detection.
    79  		Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
    80  	-msan
    81  		enable interoperation with memory sanitizer.
    82  		Supported only on linux/amd64,
    83  		and only with Clang/LLVM as the host C compiler.
    84  	-v
    85  		print the names of packages as they are compiled.
    86  	-work
    87  		print the name of the temporary work directory and
    88  		do not delete it when exiting.
    89  	-x
    90  		print the commands.
    91  
    92  	-asmflags 'flag list'
    93  		arguments to pass on each go tool asm invocation.
    94  	-buildmode mode
    95  		build mode to use. See 'go help buildmode' for more.
    96  	-compiler name
    97  		name of compiler to use, as in runtime.Compiler (gccgo or gc).
    98  	-gccgoflags 'arg list'
    99  		arguments to pass on each gccgo compiler/linker invocation.
   100  	-gcflags 'arg list'
   101  		arguments to pass on each go tool compile invocation.
   102  	-installsuffix suffix
   103  		a suffix to use in the name of the package installation directory,
   104  		in order to keep output separate from default builds.
   105  		If using the -race flag, the install suffix is automatically set to race
   106  		or, if set explicitly, has _race appended to it. Likewise for the -msan
   107  		flag. Using a -buildmode option that requires non-default compile flags
   108  		has a similar effect.
   109  	-ldflags 'flag list'
   110  		arguments to pass on each go tool link invocation.
   111  	-linkshared
   112  		link against shared libraries previously created with
   113  		-buildmode=shared.
   114  	-pkgdir dir
   115  		install and load all packages from dir instead of the usual locations.
   116  		For example, when building with a non-standard configuration,
   117  		use -pkgdir to keep generated packages in a separate location.
   118  	-tags 'tag list'
   119  		a space-separated list of build tags to consider satisfied during the
   120  		build. For more information about build tags, see the description of
   121  		build constraints in the documentation for the go/build package.
   122  	-toolexec 'cmd args'
   123  		a program to use to invoke toolchain programs like vet and asm.
   124  		For example, instead of running asm, the go command will run
   125  		'cmd args /path/to/asm <arguments for asm>'.
   126  
   127  All the flags that take a list of arguments accept a space-separated
   128  list of strings. To embed spaces in an element in the list, surround
   129  it with either single or double quotes.
   130  
   131  For more about specifying packages, see 'go help packages'.
   132  For more about where packages and binaries are installed,
   133  run 'go help gopath'.
   134  For more about calling between Go and C/C++, run 'go help c'.
   135  
   136  Note: Build adheres to certain conventions such as those described
   137  by 'go help gopath'. Not all projects can follow these conventions,
   138  however. Installations that have their own conventions or that use
   139  a separate software build system may choose to use lower-level
   140  invocations such as 'go tool compile' and 'go tool link' to avoid
   141  some of the overheads and design decisions of the build tool.
   142  
   143  See also: go install, go get, go clean.
   144  	`,
   145  }
   146  
   147  const concurrentGCBackendCompilationEnabledByDefault = true
   148  
   149  func init() {
   150  	// break init cycle
   151  	CmdBuild.Run = runBuild
   152  	CmdInstall.Run = runInstall
   153  
   154  	CmdBuild.Flag.BoolVar(&cfg.BuildI, "i", false, "")
   155  	CmdBuild.Flag.StringVar(&cfg.BuildO, "o", "", "output file")
   156  
   157  	AddBuildFlags(CmdBuild)
   158  	AddBuildFlags(CmdInstall)
   159  }
   160  
   161  // Note that flags consulted by other parts of the code
   162  // (for example, buildV) are in cmd/go/internal/cfg.
   163  
   164  var buildAsmflags []string   // -asmflags flag
   165  var buildGcflags []string    // -gcflags flag
   166  var buildGccgoflags []string // -gccgoflags flag
   167  
   168  var BuildToolchain toolchain = noToolchain{}
   169  var ldBuildmode string
   170  
   171  // buildCompiler implements flag.Var.
   172  // It implements Set by updating both
   173  // BuildToolchain and buildContext.Compiler.
   174  type buildCompiler struct{}
   175  
   176  func (c buildCompiler) Set(value string) error {
   177  	switch value {
   178  	case "gc":
   179  		BuildToolchain = gcToolchain{}
   180  	case "gccgo":
   181  		BuildToolchain = gccgoToolchain{}
   182  	default:
   183  		return fmt.Errorf("unknown compiler %q", value)
   184  	}
   185  	cfg.BuildToolchainName = value
   186  	cfg.BuildToolchainCompiler = BuildToolchain.compiler
   187  	cfg.BuildToolchainLinker = BuildToolchain.linker
   188  	cfg.BuildContext.Compiler = value
   189  	return nil
   190  }
   191  
   192  func (c buildCompiler) String() string {
   193  	return cfg.BuildContext.Compiler
   194  }
   195  
   196  func init() {
   197  	switch build.Default.Compiler {
   198  	case "gc", "gccgo":
   199  		buildCompiler{}.Set(build.Default.Compiler)
   200  	}
   201  }
   202  
   203  // addBuildFlags adds the flags common to the build, clean, get,
   204  // install, list, run, and test commands.
   205  func AddBuildFlags(cmd *base.Command) {
   206  	cmd.Flag.BoolVar(&cfg.BuildA, "a", false, "")
   207  	cmd.Flag.BoolVar(&cfg.BuildN, "n", false, "")
   208  	cmd.Flag.IntVar(&cfg.BuildP, "p", cfg.BuildP, "")
   209  	cmd.Flag.BoolVar(&cfg.BuildV, "v", false, "")
   210  	cmd.Flag.BoolVar(&cfg.BuildX, "x", false, "")
   211  
   212  	cmd.Flag.Var((*base.StringsFlag)(&buildAsmflags), "asmflags", "")
   213  	cmd.Flag.Var(buildCompiler{}, "compiler", "")
   214  	cmd.Flag.StringVar(&cfg.BuildBuildmode, "buildmode", "default", "")
   215  	cmd.Flag.Var((*base.StringsFlag)(&buildGcflags), "gcflags", "")
   216  	cmd.Flag.Var((*base.StringsFlag)(&buildGccgoflags), "gccgoflags", "")
   217  	cmd.Flag.StringVar(&cfg.BuildContext.InstallSuffix, "installsuffix", "", "")
   218  	cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildLdflags), "ldflags", "")
   219  	cmd.Flag.BoolVar(&cfg.BuildLinkshared, "linkshared", false, "")
   220  	cmd.Flag.StringVar(&cfg.BuildPkgdir, "pkgdir", "", "")
   221  	cmd.Flag.BoolVar(&cfg.BuildRace, "race", false, "")
   222  	cmd.Flag.BoolVar(&cfg.BuildMSan, "msan", false, "")
   223  	cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildContext.BuildTags), "tags", "")
   224  	cmd.Flag.Var((*base.StringsFlag)(&cfg.BuildToolexec), "toolexec", "")
   225  	cmd.Flag.BoolVar(&cfg.BuildWork, "work", false, "")
   226  }
   227  
   228  // fileExtSplit expects a filename and returns the name
   229  // and ext (without the dot). If the file has no
   230  // extension, ext will be empty.
   231  func fileExtSplit(file string) (name, ext string) {
   232  	dotExt := filepath.Ext(file)
   233  	name = file[:len(file)-len(dotExt)]
   234  	if dotExt != "" {
   235  		ext = dotExt[1:]
   236  	}
   237  	return
   238  }
   239  
   240  func pkgsMain(pkgs []*load.Package) (res []*load.Package) {
   241  	for _, p := range pkgs {
   242  		if p.Name == "main" {
   243  			res = append(res, p)
   244  		}
   245  	}
   246  	return res
   247  }
   248  
   249  func pkgsNotMain(pkgs []*load.Package) (res []*load.Package) {
   250  	for _, p := range pkgs {
   251  		if p.Name != "main" {
   252  			res = append(res, p)
   253  		}
   254  	}
   255  	return res
   256  }
   257  
   258  func oneMainPkg(pkgs []*load.Package) []*load.Package {
   259  	if len(pkgs) != 1 || pkgs[0].Name != "main" {
   260  		base.Fatalf("-buildmode=%s requires exactly one main package", cfg.BuildBuildmode)
   261  	}
   262  	return pkgs
   263  }
   264  
   265  var pkgsFilter = func(pkgs []*load.Package) []*load.Package { return pkgs }
   266  
   267  func BuildModeInit() {
   268  	gccgo := cfg.BuildToolchainName == "gccgo"
   269  	var codegenArg string
   270  	platform := cfg.Goos + "/" + cfg.Goarch
   271  	switch cfg.BuildBuildmode {
   272  	case "archive":
   273  		pkgsFilter = pkgsNotMain
   274  	case "c-archive":
   275  		pkgsFilter = oneMainPkg
   276  		switch platform {
   277  		case "darwin/arm", "darwin/arm64":
   278  			codegenArg = "-shared"
   279  		default:
   280  			switch cfg.Goos {
   281  			case "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
   282  				// Use -shared so that the result is
   283  				// suitable for inclusion in a PIE or
   284  				// shared library.
   285  				codegenArg = "-shared"
   286  			}
   287  		}
   288  		cfg.ExeSuffix = ".a"
   289  		ldBuildmode = "c-archive"
   290  	case "c-shared":
   291  		pkgsFilter = oneMainPkg
   292  		if gccgo {
   293  			codegenArg = "-fPIC"
   294  		} else {
   295  			switch platform {
   296  			case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/ppc64le",
   297  				"android/amd64", "android/arm", "android/arm64", "android/386":
   298  				codegenArg = "-shared"
   299  			case "darwin/amd64", "darwin/386":
   300  			default:
   301  				base.Fatalf("-buildmode=c-shared not supported on %s\n", platform)
   302  			}
   303  		}
   304  		ldBuildmode = "c-shared"
   305  	case "default":
   306  		switch platform {
   307  		case "android/arm", "android/arm64", "android/amd64", "android/386":
   308  			codegenArg = "-shared"
   309  			ldBuildmode = "pie"
   310  		case "darwin/arm", "darwin/arm64":
   311  			codegenArg = "-shared"
   312  			fallthrough
   313  		default:
   314  			ldBuildmode = "exe"
   315  		}
   316  	case "exe":
   317  		pkgsFilter = pkgsMain
   318  		ldBuildmode = "exe"
   319  	case "pie":
   320  		if cfg.BuildRace {
   321  			base.Fatalf("-buildmode=pie not supported when -race is enabled")
   322  		}
   323  		if gccgo {
   324  			base.Fatalf("-buildmode=pie not supported by gccgo")
   325  		} else {
   326  			switch platform {
   327  			case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x",
   328  				"android/amd64", "android/arm", "android/arm64", "android/386":
   329  				codegenArg = "-shared"
   330  			case "darwin/amd64":
   331  				codegenArg = "-shared"
   332  			default:
   333  				base.Fatalf("-buildmode=pie not supported on %s\n", platform)
   334  			}
   335  		}
   336  		ldBuildmode = "pie"
   337  	case "shared":
   338  		pkgsFilter = pkgsNotMain
   339  		if gccgo {
   340  			codegenArg = "-fPIC"
   341  		} else {
   342  			switch platform {
   343  			case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
   344  			default:
   345  				base.Fatalf("-buildmode=shared not supported on %s\n", platform)
   346  			}
   347  			codegenArg = "-dynlink"
   348  		}
   349  		if cfg.BuildO != "" {
   350  			base.Fatalf("-buildmode=shared and -o not supported together")
   351  		}
   352  		ldBuildmode = "shared"
   353  	case "plugin":
   354  		pkgsFilter = oneMainPkg
   355  		if gccgo {
   356  			codegenArg = "-fPIC"
   357  		} else {
   358  			switch platform {
   359  			case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/s390x",
   360  				"android/amd64", "android/arm", "android/arm64", "android/386":
   361  			default:
   362  				base.Fatalf("-buildmode=plugin not supported on %s\n", platform)
   363  			}
   364  			codegenArg = "-dynlink"
   365  		}
   366  		cfg.ExeSuffix = ".so"
   367  		ldBuildmode = "plugin"
   368  	default:
   369  		base.Fatalf("buildmode=%s not supported", cfg.BuildBuildmode)
   370  	}
   371  	if cfg.BuildLinkshared {
   372  		if gccgo {
   373  			codegenArg = "-fPIC"
   374  		} else {
   375  			switch platform {
   376  			case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
   377  				buildAsmflags = append(buildAsmflags, "-D=GOBUILDMODE_shared=1")
   378  			default:
   379  				base.Fatalf("-linkshared not supported on %s\n", platform)
   380  			}
   381  			codegenArg = "-dynlink"
   382  			// TODO(mwhudson): remove -w when that gets fixed in linker.
   383  			cfg.BuildLdflags = append(cfg.BuildLdflags, "-linkshared", "-w")
   384  		}
   385  	}
   386  	if codegenArg != "" {
   387  		if gccgo {
   388  			buildGccgoflags = append([]string{codegenArg}, buildGccgoflags...)
   389  		} else {
   390  			buildAsmflags = append([]string{codegenArg}, buildAsmflags...)
   391  			buildGcflags = append([]string{codegenArg}, buildGcflags...)
   392  		}
   393  		// Don't alter InstallSuffix when modifying default codegen args.
   394  		if cfg.BuildBuildmode != "default" || cfg.BuildLinkshared {
   395  			if cfg.BuildContext.InstallSuffix != "" {
   396  				cfg.BuildContext.InstallSuffix += "_"
   397  			}
   398  			cfg.BuildContext.InstallSuffix += codegenArg[1:]
   399  		}
   400  	}
   401  	if strings.HasPrefix(runtimeVersion, "go1") && !strings.Contains(os.Args[0], "go_bootstrap") {
   402  		buildGcflags = append(buildGcflags, "-goversion", runtimeVersion)
   403  	}
   404  }
   405  
   406  var runtimeVersion = runtime.Version()
   407  
   408  func runBuild(cmd *base.Command, args []string) {
   409  	InstrumentInit()
   410  	BuildModeInit()
   411  	var b Builder
   412  	b.Init()
   413  
   414  	pkgs := load.PackagesForBuild(args)
   415  
   416  	if len(pkgs) == 1 && pkgs[0].Name == "main" && cfg.BuildO == "" {
   417  		_, cfg.BuildO = path.Split(pkgs[0].ImportPath)
   418  		cfg.BuildO += cfg.ExeSuffix
   419  	}
   420  
   421  	// Special case -o /dev/null by not writing at all.
   422  	if cfg.BuildO == os.DevNull {
   423  		cfg.BuildO = ""
   424  	}
   425  
   426  	// sanity check some often mis-used options
   427  	switch cfg.BuildContext.Compiler {
   428  	case "gccgo":
   429  		if len(buildGcflags) != 0 {
   430  			fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
   431  		}
   432  		if len(cfg.BuildLdflags) != 0 {
   433  			fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
   434  		}
   435  	case "gc":
   436  		if len(buildGccgoflags) != 0 {
   437  			fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
   438  		}
   439  	}
   440  
   441  	depMode := ModeBuild
   442  	if cfg.BuildI {
   443  		depMode = ModeInstall
   444  	}
   445  
   446  	if cfg.BuildO != "" {
   447  		if len(pkgs) > 1 {
   448  			base.Fatalf("go build: cannot use -o with multiple packages")
   449  		} else if len(pkgs) == 0 {
   450  			base.Fatalf("no packages to build")
   451  		}
   452  		p := pkgs[0]
   453  		p.Internal.Target = cfg.BuildO
   454  		p.Stale = true // must build - not up to date
   455  		p.StaleReason = "build -o flag in use"
   456  		a := b.Action(ModeInstall, depMode, p)
   457  		b.Do(a)
   458  		return
   459  	}
   460  
   461  	pkgs = pkgsFilter(load.Packages(args))
   462  
   463  	var a *Action
   464  	if cfg.BuildBuildmode == "shared" {
   465  		if libName, err := libname(args, pkgs); err != nil {
   466  			base.Fatalf("%s", err.Error())
   467  		} else {
   468  			a = b.libaction(libName, pkgs, ModeBuild, depMode)
   469  		}
   470  	} else {
   471  		a = &Action{}
   472  		for _, p := range pkgs {
   473  			a.Deps = append(a.Deps, b.Action(ModeBuild, depMode, p))
   474  		}
   475  	}
   476  	b.Do(a)
   477  }
   478  
   479  var CmdInstall = &base.Command{
   480  	UsageLine: "install [build flags] [packages]",
   481  	Short:     "compile and install packages and dependencies",
   482  	Long: `
   483  Install compiles and installs the packages named by the import paths,
   484  along with their dependencies.
   485  
   486  For more about the build flags, see 'go help build'.
   487  For more about specifying packages, see 'go help packages'.
   488  
   489  See also: go build, go get, go clean.
   490  	`,
   491  }
   492  
   493  // libname returns the filename to use for the shared library when using
   494  // -buildmode=shared. The rules we use are:
   495  // Use arguments for special 'meta' packages:
   496  //	std --> libstd.so
   497  //	std cmd --> libstd,cmd.so
   498  // A single non-meta argument with trailing "/..." is special cased:
   499  //	foo/... --> libfoo.so
   500  //	(A relative path like "./..."  expands the "." first)
   501  // Use import paths for other cases, changing '/' to '-':
   502  //	somelib --> libsubdir-somelib.so
   503  //	./ or ../ --> libsubdir-somelib.so
   504  //	gopkg.in/tomb.v2 -> libgopkg.in-tomb.v2.so
   505  //	a/... b/... ---> liba/c,b/d.so - all matching import paths
   506  // Name parts are joined with ','.
   507  func libname(args []string, pkgs []*load.Package) (string, error) {
   508  	var libname string
   509  	appendName := func(arg string) {
   510  		if libname == "" {
   511  			libname = arg
   512  		} else {
   513  			libname += "," + arg
   514  		}
   515  	}
   516  	var haveNonMeta bool
   517  	for _, arg := range args {
   518  		if load.IsMetaPackage(arg) {
   519  			appendName(arg)
   520  		} else {
   521  			haveNonMeta = true
   522  		}
   523  	}
   524  	if len(libname) == 0 { // non-meta packages only. use import paths
   525  		if len(args) == 1 && strings.HasSuffix(args[0], "/...") {
   526  			// Special case of "foo/..." as mentioned above.
   527  			arg := strings.TrimSuffix(args[0], "/...")
   528  			if build.IsLocalImport(arg) {
   529  				cwd, _ := os.Getwd()
   530  				bp, _ := cfg.BuildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
   531  				if bp.ImportPath != "" && bp.ImportPath != "." {
   532  					arg = bp.ImportPath
   533  				}
   534  			}
   535  			appendName(strings.Replace(arg, "/", "-", -1))
   536  		} else {
   537  			for _, pkg := range pkgs {
   538  				appendName(strings.Replace(pkg.ImportPath, "/", "-", -1))
   539  			}
   540  		}
   541  	} else if haveNonMeta { // have both meta package and a non-meta one
   542  		return "", errors.New("mixing of meta and non-meta packages is not allowed")
   543  	}
   544  	// TODO(mwhudson): Needs to change for platforms that use different naming
   545  	// conventions...
   546  	return "lib" + libname + ".so", nil
   547  }
   548  
   549  func runInstall(cmd *base.Command, args []string) {
   550  	InstrumentInit()
   551  	BuildModeInit()
   552  	InstallPackages(args, false)
   553  }
   554  
   555  func InstallPackages(args []string, forGet bool) {
   556  	if cfg.GOBIN != "" && !filepath.IsAbs(cfg.GOBIN) {
   557  		base.Fatalf("cannot install, GOBIN must be an absolute path")
   558  	}
   559  
   560  	pkgs := pkgsFilter(load.PackagesForBuild(args))
   561  
   562  	for _, p := range pkgs {
   563  		if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
   564  			switch {
   565  			case p.Internal.GobinSubdir:
   566  				base.Errorf("go install: cannot install cross-compiled binaries when GOBIN is set")
   567  			case p.Internal.Cmdline:
   568  				base.Errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
   569  			case p.ConflictDir != "":
   570  				base.Errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
   571  			default:
   572  				base.Errorf("go install: no install location for directory %s outside GOPATH\n"+
   573  					"\tFor more details see: 'go help gopath'", p.Dir)
   574  			}
   575  		}
   576  	}
   577  	base.ExitIfErrors()
   578  
   579  	var b Builder
   580  	b.Init()
   581  	var a *Action
   582  	if cfg.BuildBuildmode == "shared" {
   583  		if libName, err := libname(args, pkgs); err != nil {
   584  			base.Fatalf("%s", err.Error())
   585  		} else {
   586  			a = b.libaction(libName, pkgs, ModeInstall, ModeInstall)
   587  		}
   588  	} else {
   589  		a = &Action{}
   590  		var tools []*Action
   591  		for _, p := range pkgs {
   592  			// During 'go get', don't attempt (and fail) to install packages with only tests.
   593  			// TODO(rsc): It's not clear why 'go get' should be different from 'go install' here. See #20760.
   594  			if forGet && len(p.GoFiles)+len(p.CgoFiles) == 0 && len(p.TestGoFiles)+len(p.XTestGoFiles) > 0 {
   595  				continue
   596  			}
   597  			// If p is a tool, delay the installation until the end of the build.
   598  			// This avoids installing assemblers/compilers that are being executed
   599  			// by other steps in the build.
   600  			// cmd/cgo is handled specially in b.Action, so that we can
   601  			// both build and use it in the same 'go install'.
   602  			Action := b.Action(ModeInstall, ModeInstall, p)
   603  			if load.GoTools[p.ImportPath] == load.ToTool && p.ImportPath != "cmd/cgo" {
   604  				a.Deps = append(a.Deps, Action.Deps...)
   605  				Action.Deps = append(Action.Deps, a)
   606  				tools = append(tools, Action)
   607  				continue
   608  			}
   609  			a.Deps = append(a.Deps, Action)
   610  		}
   611  		if len(tools) > 0 {
   612  			a = &Action{
   613  				Deps: tools,
   614  			}
   615  		}
   616  	}
   617  	b.Do(a)
   618  	base.ExitIfErrors()
   619  
   620  	// Success. If this command is 'go install' with no arguments
   621  	// and the current directory (the implicit argument) is a command,
   622  	// remove any leftover command binary from a previous 'go build'.
   623  	// The binary is installed; it's not needed here anymore.
   624  	// And worse it might be a stale copy, which you don't want to find
   625  	// instead of the installed one if $PATH contains dot.
   626  	// One way to view this behavior is that it is as if 'go install' first
   627  	// runs 'go build' and the moves the generated file to the install dir.
   628  	// See issue 9645.
   629  	if len(args) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
   630  		// Compute file 'go build' would have created.
   631  		// If it exists and is an executable file, remove it.
   632  		_, targ := filepath.Split(pkgs[0].ImportPath)
   633  		targ += cfg.ExeSuffix
   634  		if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory
   635  			fi, err := os.Stat(targ)
   636  			if err == nil {
   637  				m := fi.Mode()
   638  				if m.IsRegular() {
   639  					if m&0111 != 0 || cfg.Goos == "windows" { // windows never sets executable bit
   640  						os.Remove(targ)
   641  					}
   642  				}
   643  			}
   644  		}
   645  	}
   646  }
   647  
   648  // A Builder holds global state about a build.
   649  // It does not hold per-package state, because we
   650  // build packages in parallel, and the builder is shared.
   651  type Builder struct {
   652  	WorkDir     string               // the temporary work directory (ends in filepath.Separator)
   653  	actionCache map[cacheKey]*Action // a cache of already-constructed actions
   654  	mkdirCache  map[string]bool      // a cache of created directories
   655  	flagCache   map[string]bool      // a cache of supported compiler flags
   656  	Print       func(args ...interface{}) (int, error)
   657  
   658  	output    sync.Mutex
   659  	scriptDir string // current directory in printed script
   660  
   661  	exec      sync.Mutex
   662  	readySema chan bool
   663  	ready     actionQueue
   664  }
   665  
   666  // NOTE: Much of Action would not need to be exported if not for test.
   667  // Maybe test functionality should move into this package too?
   668  
   669  // An Action represents a single action in the action graph.
   670  type Action struct {
   671  	Package    *load.Package                 // the package this action works on
   672  	Deps       []*Action                     // actions that must happen before this one
   673  	Func       func(*Builder, *Action) error // the action itself (nil = no-op)
   674  	IgnoreFail bool                          // whether to run f even if dependencies fail
   675  	TestOutput *bytes.Buffer                 // test output buffer
   676  	Args       []string                      // additional args for runProgram
   677  
   678  	triggers []*Action // inverse of deps
   679  	cgo      *Action   // action for cgo binary if needed
   680  
   681  	// Generated files, directories.
   682  	Link   bool   // target is executable, not just package
   683  	Pkgdir string // the -I or -L argument to use when importing this package
   684  	Objdir string // directory for intermediate objects
   685  	Objpkg string // the intermediate package .a file created during the action
   686  	Target string // goal of the action: the created package or executable
   687  
   688  	// Execution state.
   689  	pending  int  // number of deps yet to complete
   690  	priority int  // relative execution priority
   691  	Failed   bool // whether the action failed
   692  }
   693  
   694  // cacheKey is the key for the action cache.
   695  type cacheKey struct {
   696  	mode  BuildMode
   697  	p     *load.Package
   698  	shlib string
   699  }
   700  
   701  // BuildMode specifies the build mode:
   702  // are we just building things or also installing the results?
   703  type BuildMode int
   704  
   705  const (
   706  	ModeBuild BuildMode = iota
   707  	ModeInstall
   708  )
   709  
   710  func (b *Builder) Init() {
   711  	var err error
   712  	b.Print = func(a ...interface{}) (int, error) {
   713  		return fmt.Fprint(os.Stderr, a...)
   714  	}
   715  	b.actionCache = make(map[cacheKey]*Action)
   716  	b.mkdirCache = make(map[string]bool)
   717  
   718  	if cfg.BuildN {
   719  		b.WorkDir = "$WORK"
   720  	} else {
   721  		b.WorkDir, err = ioutil.TempDir("", "go-build")
   722  		if err != nil {
   723  			base.Fatalf("%s", err)
   724  		}
   725  		if cfg.BuildX || cfg.BuildWork {
   726  			fmt.Fprintf(os.Stderr, "WORK=%s\n", b.WorkDir)
   727  		}
   728  		if !cfg.BuildWork {
   729  			workdir := b.WorkDir
   730  			base.AtExit(func() { os.RemoveAll(workdir) })
   731  		}
   732  	}
   733  }
   734  
   735  // readpkglist returns the list of packages that were built into the shared library
   736  // at shlibpath. For the native toolchain this list is stored, newline separated, in
   737  // an ELF note with name "Go\x00\x00" and type 1. For GCCGO it is extracted from the
   738  // .go_export section.
   739  func readpkglist(shlibpath string) (pkgs []*load.Package) {
   740  	var stk load.ImportStack
   741  	if cfg.BuildToolchainName == "gccgo" {
   742  		f, _ := elf.Open(shlibpath)
   743  		sect := f.Section(".go_export")
   744  		data, _ := sect.Data()
   745  		scanner := bufio.NewScanner(bytes.NewBuffer(data))
   746  		for scanner.Scan() {
   747  			t := scanner.Text()
   748  			if strings.HasPrefix(t, "pkgpath ") {
   749  				t = strings.TrimPrefix(t, "pkgpath ")
   750  				t = strings.TrimSuffix(t, ";")
   751  				pkgs = append(pkgs, load.LoadPackage(t, &stk))
   752  			}
   753  		}
   754  	} else {
   755  		pkglistbytes, err := buildid.ReadELFNote(shlibpath, "Go\x00\x00", 1)
   756  		if err != nil {
   757  			base.Fatalf("readELFNote failed: %v", err)
   758  		}
   759  		scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
   760  		for scanner.Scan() {
   761  			t := scanner.Text()
   762  			pkgs = append(pkgs, load.LoadPackage(t, &stk))
   763  		}
   764  	}
   765  	return
   766  }
   767  
   768  // Action returns the action for applying the given operation (mode) to the package.
   769  // depMode is the action to use when building dependencies.
   770  // action never looks for p in a shared library, but may find p's dependencies in a
   771  // shared library if buildLinkshared is true.
   772  func (b *Builder) Action(mode BuildMode, depMode BuildMode, p *load.Package) *Action {
   773  	return b.action1(mode, depMode, p, false, "")
   774  }
   775  
   776  // action1 returns the action for applying the given operation (mode) to the package.
   777  // depMode is the action to use when building dependencies.
   778  // action1 will look for p in a shared library if lookshared is true.
   779  // forShlib is the shared library that p will become part of, if any.
   780  func (b *Builder) action1(mode BuildMode, depMode BuildMode, p *load.Package, lookshared bool, forShlib string) *Action {
   781  	shlib := ""
   782  	if lookshared {
   783  		shlib = p.Shlib
   784  	}
   785  	key := cacheKey{mode, p, shlib}
   786  
   787  	a := b.actionCache[key]
   788  	if a != nil {
   789  		return a
   790  	}
   791  	if shlib != "" {
   792  		key2 := cacheKey{ModeInstall, nil, shlib}
   793  		a = b.actionCache[key2]
   794  		if a != nil {
   795  			b.actionCache[key] = a
   796  			return a
   797  		}
   798  		pkgs := readpkglist(shlib)
   799  		a = b.libaction(filepath.Base(shlib), pkgs, ModeInstall, depMode)
   800  		b.actionCache[key2] = a
   801  		b.actionCache[key] = a
   802  		return a
   803  	}
   804  
   805  	a = &Action{Package: p, Pkgdir: p.Internal.Build.PkgRoot}
   806  	if p.Internal.Pkgdir != "" { // overrides p.t
   807  		a.Pkgdir = p.Internal.Pkgdir
   808  	}
   809  	b.actionCache[key] = a
   810  
   811  	for _, p1 := range p.Internal.Imports {
   812  		if forShlib != "" {
   813  			// p is part of a shared library.
   814  			if p1.Shlib != "" && p1.Shlib != forShlib {
   815  				// p1 is explicitly part of a different shared library.
   816  				// Put the action for that shared library into a.Deps.
   817  				a.Deps = append(a.Deps, b.action1(depMode, depMode, p1, true, p1.Shlib))
   818  			} else {
   819  				// p1 is (implicitly or not) part of this shared library.
   820  				// Put the action for p1 into a.Deps.
   821  				a.Deps = append(a.Deps, b.action1(depMode, depMode, p1, false, forShlib))
   822  			}
   823  		} else {
   824  			// p is not part of a shared library.
   825  			// If p1 is in a shared library, put the action for that into
   826  			// a.Deps, otherwise put the action for p1 into a.Deps.
   827  			a.Deps = append(a.Deps, b.action1(depMode, depMode, p1, cfg.BuildLinkshared, p1.Shlib))
   828  		}
   829  	}
   830  
   831  	// If we are not doing a cross-build, then record the binary we'll
   832  	// generate for cgo as a dependency of the build of any package
   833  	// using cgo, to make sure we do not overwrite the binary while
   834  	// a package is using it. If this is a cross-build, then the cgo we
   835  	// are writing is not the cgo we need to use.
   836  	if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH && !cfg.BuildRace && !cfg.BuildMSan {
   837  		if (len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo") && !cfg.BuildLinkshared && cfg.BuildBuildmode != "shared" {
   838  			var stk load.ImportStack
   839  			p1 := load.LoadPackage("cmd/cgo", &stk)
   840  			if p1.Error != nil {
   841  				base.Fatalf("load cmd/cgo: %v", p1.Error)
   842  			}
   843  			a.cgo = b.Action(depMode, depMode, p1)
   844  			a.Deps = append(a.Deps, a.cgo)
   845  		}
   846  	}
   847  
   848  	if p.Standard {
   849  		switch p.ImportPath {
   850  		case "builtin", "unsafe":
   851  			// Fake packages - nothing to build.
   852  			return a
   853  		}
   854  		// gccgo standard library is "fake" too.
   855  		if cfg.BuildToolchainName == "gccgo" {
   856  			// the target name is needed for cgo.
   857  			a.Target = p.Internal.Target
   858  			return a
   859  		}
   860  	}
   861  
   862  	if !p.Stale && p.Internal.Target != "" {
   863  		// p.Stale==false implies that p.Internal.Target is up-to-date.
   864  		// Record target name for use by actions depending on this one.
   865  		a.Target = p.Internal.Target
   866  		return a
   867  	}
   868  
   869  	if p.Internal.Local && p.Internal.Target == "" {
   870  		// Imported via local path. No permanent target.
   871  		mode = ModeBuild
   872  	}
   873  	work := p.Internal.Pkgdir
   874  	if work == "" {
   875  		work = b.WorkDir
   876  	}
   877  	a.Objdir = filepath.Join(work, a.Package.ImportPath, "_obj") + string(filepath.Separator)
   878  	a.Objpkg = BuildToolchain.Pkgpath(work, a.Package)
   879  	a.Link = p.Name == "main"
   880  
   881  	switch mode {
   882  	case ModeInstall:
   883  		a.Func = BuildInstallFunc
   884  		a.Deps = []*Action{b.action1(ModeBuild, depMode, p, lookshared, forShlib)}
   885  		a.Target = a.Package.Internal.Target
   886  
   887  		// Install header for cgo in c-archive and c-shared modes.
   888  		if p.UsesCgo() && (cfg.BuildBuildmode == "c-archive" || cfg.BuildBuildmode == "c-shared") {
   889  			hdrTarget := a.Target[:len(a.Target)-len(filepath.Ext(a.Target))] + ".h"
   890  			if cfg.BuildContext.Compiler == "gccgo" {
   891  				// For the header file, remove the "lib"
   892  				// added by go/build, so we generate pkg.h
   893  				// rather than libpkg.h.
   894  				dir, file := filepath.Split(hdrTarget)
   895  				file = strings.TrimPrefix(file, "lib")
   896  				hdrTarget = filepath.Join(dir, file)
   897  			}
   898  			ah := &Action{
   899  				Package: a.Package,
   900  				Deps:    []*Action{a.Deps[0]},
   901  				Func:    (*Builder).installHeader,
   902  				Pkgdir:  a.Pkgdir,
   903  				Objdir:  a.Objdir,
   904  				Target:  hdrTarget,
   905  			}
   906  			a.Deps = append(a.Deps, ah)
   907  		}
   908  
   909  	case ModeBuild:
   910  		a.Func = (*Builder).build
   911  		a.Target = a.Objpkg
   912  		if a.Link {
   913  			// An executable file. (This is the name of a temporary file.)
   914  			// Because we run the temporary file in 'go run' and 'go test',
   915  			// the name will show up in ps listings. If the caller has specified
   916  			// a name, use that instead of a.out. The binary is generated
   917  			// in an otherwise empty subdirectory named exe to avoid
   918  			// naming conflicts. The only possible conflict is if we were
   919  			// to create a top-level package named exe.
   920  			name := "a.out"
   921  			if p.Internal.ExeName != "" {
   922  				name = p.Internal.ExeName
   923  			} else if cfg.Goos == "darwin" && cfg.BuildBuildmode == "c-shared" && p.Internal.Target != "" {
   924  				// On OS X, the linker output name gets recorded in the
   925  				// shared library's LC_ID_DYLIB load command.
   926  				// The code invoking the linker knows to pass only the final
   927  				// path element. Arrange that the path element matches what
   928  				// we'll install it as; otherwise the library is only loadable as "a.out".
   929  				_, name = filepath.Split(p.Internal.Target)
   930  			}
   931  			a.Target = a.Objdir + filepath.Join("exe", name) + cfg.ExeSuffix
   932  		}
   933  	}
   934  
   935  	return a
   936  }
   937  
   938  func (b *Builder) libaction(libname string, pkgs []*load.Package, mode, depMode BuildMode) *Action {
   939  	a := &Action{}
   940  	switch mode {
   941  	default:
   942  		base.Fatalf("unrecognized mode %v", mode)
   943  
   944  	case ModeBuild:
   945  		a.Func = (*Builder).linkShared
   946  		a.Target = filepath.Join(b.WorkDir, libname)
   947  		for _, p := range pkgs {
   948  			if p.Internal.Target == "" {
   949  				continue
   950  			}
   951  			a.Deps = append(a.Deps, b.Action(depMode, depMode, p))
   952  		}
   953  
   954  	case ModeInstall:
   955  		// Currently build mode shared forces external linking mode, and
   956  		// external linking mode forces an import of runtime/cgo (and
   957  		// math on arm). So if it was not passed on the command line and
   958  		// it is not present in another shared library, add it here.
   959  		gccgo := cfg.BuildToolchainName == "gccgo"
   960  		if !gccgo {
   961  			seencgo := false
   962  			for _, p := range pkgs {
   963  				seencgo = seencgo || (p.Standard && p.ImportPath == "runtime/cgo")
   964  			}
   965  			if !seencgo {
   966  				var stk load.ImportStack
   967  				p := load.LoadPackage("runtime/cgo", &stk)
   968  				if p.Error != nil {
   969  					base.Fatalf("load runtime/cgo: %v", p.Error)
   970  				}
   971  				load.ComputeStale(p)
   972  				// If runtime/cgo is in another shared library, then that's
   973  				// also the shared library that contains runtime, so
   974  				// something will depend on it and so runtime/cgo's staleness
   975  				// will be checked when processing that library.
   976  				if p.Shlib == "" || p.Shlib == libname {
   977  					pkgs = append([]*load.Package{}, pkgs...)
   978  					pkgs = append(pkgs, p)
   979  				}
   980  			}
   981  			if cfg.Goarch == "arm" {
   982  				seenmath := false
   983  				for _, p := range pkgs {
   984  					seenmath = seenmath || (p.Standard && p.ImportPath == "math")
   985  				}
   986  				if !seenmath {
   987  					var stk load.ImportStack
   988  					p := load.LoadPackage("math", &stk)
   989  					if p.Error != nil {
   990  						base.Fatalf("load math: %v", p.Error)
   991  					}
   992  					load.ComputeStale(p)
   993  					// If math is in another shared library, then that's
   994  					// also the shared library that contains runtime, so
   995  					// something will depend on it and so math's staleness
   996  					// will be checked when processing that library.
   997  					if p.Shlib == "" || p.Shlib == libname {
   998  						pkgs = append([]*load.Package{}, pkgs...)
   999  						pkgs = append(pkgs, p)
  1000  					}
  1001  				}
  1002  			}
  1003  		}
  1004  
  1005  		// Figure out where the library will go.
  1006  		var libdir string
  1007  		for _, p := range pkgs {
  1008  			plibdir := p.Internal.Build.PkgTargetRoot
  1009  			if gccgo {
  1010  				plibdir = filepath.Join(plibdir, "shlibs")
  1011  			}
  1012  			if libdir == "" {
  1013  				libdir = plibdir
  1014  			} else if libdir != plibdir {
  1015  				base.Fatalf("multiple roots %s & %s", libdir, plibdir)
  1016  			}
  1017  		}
  1018  		a.Target = filepath.Join(libdir, libname)
  1019  
  1020  		// Now we can check whether we need to rebuild it.
  1021  		stale := false
  1022  		var built time.Time
  1023  		if fi, err := os.Stat(a.Target); err == nil {
  1024  			built = fi.ModTime()
  1025  		}
  1026  		for _, p := range pkgs {
  1027  			if p.Internal.Target == "" {
  1028  				continue
  1029  			}
  1030  			stale = stale || p.Stale
  1031  			lstat, err := os.Stat(p.Internal.Target)
  1032  			if err != nil || lstat.ModTime().After(built) {
  1033  				stale = true
  1034  			}
  1035  			a.Deps = append(a.Deps, b.action1(depMode, depMode, p, false, a.Target))
  1036  		}
  1037  
  1038  		if stale {
  1039  			a.Func = BuildInstallFunc
  1040  			buildAction := b.libaction(libname, pkgs, ModeBuild, depMode)
  1041  			a.Deps = []*Action{buildAction}
  1042  			for _, p := range pkgs {
  1043  				if p.Internal.Target == "" {
  1044  					continue
  1045  				}
  1046  				shlibnameaction := &Action{}
  1047  				shlibnameaction.Func = (*Builder).installShlibname
  1048  				shlibnameaction.Target = p.Internal.Target[:len(p.Internal.Target)-2] + ".shlibname"
  1049  				a.Deps = append(a.Deps, shlibnameaction)
  1050  				shlibnameaction.Deps = append(shlibnameaction.Deps, buildAction)
  1051  			}
  1052  		}
  1053  	}
  1054  	return a
  1055  }
  1056  
  1057  // ActionList returns the list of actions in the dag rooted at root
  1058  // as visited in a depth-first post-order traversal.
  1059  func ActionList(root *Action) []*Action {
  1060  	seen := map[*Action]bool{}
  1061  	all := []*Action{}
  1062  	var walk func(*Action)
  1063  	walk = func(a *Action) {
  1064  		if seen[a] {
  1065  			return
  1066  		}
  1067  		seen[a] = true
  1068  		for _, a1 := range a.Deps {
  1069  			walk(a1)
  1070  		}
  1071  		all = append(all, a)
  1072  	}
  1073  	walk(root)
  1074  	return all
  1075  }
  1076  
  1077  // allArchiveActions returns a list of the archive dependencies of root.
  1078  // This is needed because if package p depends on package q that is in libr.so, the
  1079  // action graph looks like p->libr.so->q and so just scanning through p's
  1080  // dependencies does not find the import dir for q.
  1081  func allArchiveActions(root *Action) []*Action {
  1082  	seen := map[*Action]bool{}
  1083  	r := []*Action{}
  1084  	var walk func(*Action)
  1085  	walk = func(a *Action) {
  1086  		if seen[a] {
  1087  			return
  1088  		}
  1089  		seen[a] = true
  1090  		if strings.HasSuffix(a.Target, ".so") || a == root {
  1091  			for _, a1 := range a.Deps {
  1092  				walk(a1)
  1093  			}
  1094  		} else if strings.HasSuffix(a.Target, ".a") {
  1095  			r = append(r, a)
  1096  		}
  1097  	}
  1098  	walk(root)
  1099  	return r
  1100  }
  1101  
  1102  // do runs the action graph rooted at root.
  1103  func (b *Builder) Do(root *Action) {
  1104  	if _, ok := cfg.OSArchSupportsCgo[cfg.Goos+"/"+cfg.Goarch]; !ok && cfg.BuildContext.Compiler == "gc" {
  1105  		fmt.Fprintf(os.Stderr, "cmd/go: unsupported GOOS/GOARCH pair %s/%s\n", cfg.Goos, cfg.Goarch)
  1106  		os.Exit(2)
  1107  	}
  1108  	for _, tag := range cfg.BuildContext.BuildTags {
  1109  		if strings.Contains(tag, ",") {
  1110  			fmt.Fprintf(os.Stderr, "cmd/go: -tags space-separated list contains comma\n")
  1111  			os.Exit(2)
  1112  		}
  1113  	}
  1114  
  1115  	// Build list of all actions, assigning depth-first post-order priority.
  1116  	// The original implementation here was a true queue
  1117  	// (using a channel) but it had the effect of getting
  1118  	// distracted by low-level leaf actions to the detriment
  1119  	// of completing higher-level actions. The order of
  1120  	// work does not matter much to overall execution time,
  1121  	// but when running "go test std" it is nice to see each test
  1122  	// results as soon as possible. The priorities assigned
  1123  	// ensure that, all else being equal, the execution prefers
  1124  	// to do what it would have done first in a simple depth-first
  1125  	// dependency order traversal.
  1126  	all := ActionList(root)
  1127  	for i, a := range all {
  1128  		a.priority = i
  1129  	}
  1130  
  1131  	b.readySema = make(chan bool, len(all))
  1132  
  1133  	// Initialize per-action execution state.
  1134  	for _, a := range all {
  1135  		for _, a1 := range a.Deps {
  1136  			a1.triggers = append(a1.triggers, a)
  1137  		}
  1138  		a.pending = len(a.Deps)
  1139  		if a.pending == 0 {
  1140  			b.ready.push(a)
  1141  			b.readySema <- true
  1142  		}
  1143  	}
  1144  
  1145  	// Handle runs a single action and takes care of triggering
  1146  	// any actions that are runnable as a result.
  1147  	handle := func(a *Action) {
  1148  		var err error
  1149  		if a.Func != nil && (!a.Failed || a.IgnoreFail) {
  1150  			err = a.Func(b, a)
  1151  		}
  1152  
  1153  		// The actions run in parallel but all the updates to the
  1154  		// shared work state are serialized through b.exec.
  1155  		b.exec.Lock()
  1156  		defer b.exec.Unlock()
  1157  
  1158  		if err != nil {
  1159  			if err == errPrintedOutput {
  1160  				base.SetExitStatus(2)
  1161  			} else {
  1162  				base.Errorf("%s", err)
  1163  			}
  1164  			a.Failed = true
  1165  		}
  1166  
  1167  		for _, a0 := range a.triggers {
  1168  			if a.Failed {
  1169  				a0.Failed = true
  1170  			}
  1171  			if a0.pending--; a0.pending == 0 {
  1172  				b.ready.push(a0)
  1173  				b.readySema <- true
  1174  			}
  1175  		}
  1176  
  1177  		if a == root {
  1178  			close(b.readySema)
  1179  		}
  1180  	}
  1181  
  1182  	var wg sync.WaitGroup
  1183  
  1184  	// Kick off goroutines according to parallelism.
  1185  	// If we are using the -n flag (just printing commands)
  1186  	// drop the parallelism to 1, both to make the output
  1187  	// deterministic and because there is no real work anyway.
  1188  	par := cfg.BuildP
  1189  	if cfg.BuildN {
  1190  		par = 1
  1191  	}
  1192  	for i := 0; i < par; i++ {
  1193  		wg.Add(1)
  1194  		go func() {
  1195  			defer wg.Done()
  1196  			for {
  1197  				select {
  1198  				case _, ok := <-b.readySema:
  1199  					if !ok {
  1200  						return
  1201  					}
  1202  					// Receiving a value from b.readySema entitles
  1203  					// us to take from the ready queue.
  1204  					b.exec.Lock()
  1205  					a := b.ready.pop()
  1206  					b.exec.Unlock()
  1207  					handle(a)
  1208  				case <-base.Interrupted:
  1209  					base.SetExitStatus(1)
  1210  					return
  1211  				}
  1212  			}
  1213  		}()
  1214  	}
  1215  
  1216  	wg.Wait()
  1217  }
  1218  
  1219  // build is the action for building a single package or command.
  1220  func (b *Builder) build(a *Action) (err error) {
  1221  	// Return an error for binary-only package.
  1222  	// We only reach this if isStale believes the binary form is
  1223  	// either not present or not usable.
  1224  	if a.Package.BinaryOnly {
  1225  		return fmt.Errorf("missing or invalid package binary for binary-only package %s", a.Package.ImportPath)
  1226  	}
  1227  
  1228  	// Return an error if the package has CXX files but it's not using
  1229  	// cgo nor SWIG, since the CXX files can only be processed by cgo
  1230  	// and SWIG.
  1231  	if len(a.Package.CXXFiles) > 0 && !a.Package.UsesCgo() && !a.Package.UsesSwig() {
  1232  		return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
  1233  			a.Package.ImportPath, strings.Join(a.Package.CXXFiles, ","))
  1234  	}
  1235  	// Same as above for Objective-C files
  1236  	if len(a.Package.MFiles) > 0 && !a.Package.UsesCgo() && !a.Package.UsesSwig() {
  1237  		return fmt.Errorf("can't build package %s because it contains Objective-C files (%s) but it's not using cgo nor SWIG",
  1238  			a.Package.ImportPath, strings.Join(a.Package.MFiles, ","))
  1239  	}
  1240  	// Same as above for Fortran files
  1241  	if len(a.Package.FFiles) > 0 && !a.Package.UsesCgo() && !a.Package.UsesSwig() {
  1242  		return fmt.Errorf("can't build package %s because it contains Fortran files (%s) but it's not using cgo nor SWIG",
  1243  			a.Package.ImportPath, strings.Join(a.Package.FFiles, ","))
  1244  	}
  1245  
  1246  	defer func() {
  1247  		if err != nil && err != errPrintedOutput {
  1248  			err = fmt.Errorf("go build %s: %v", a.Package.ImportPath, err)
  1249  		}
  1250  	}()
  1251  	if cfg.BuildN {
  1252  		// In -n mode, print a banner between packages.
  1253  		// The banner is five lines so that when changes to
  1254  		// different sections of the bootstrap script have to
  1255  		// be merged, the banners give patch something
  1256  		// to use to find its context.
  1257  		b.Print("\n#\n# " + a.Package.ImportPath + "\n#\n\n")
  1258  	}
  1259  
  1260  	if cfg.BuildV {
  1261  		b.Print(a.Package.ImportPath + "\n")
  1262  	}
  1263  
  1264  	// Make build directory.
  1265  	objdir := a.Objdir
  1266  	if err := b.Mkdir(objdir); err != nil {
  1267  		return err
  1268  	}
  1269  
  1270  	// make target directory
  1271  	dir, _ := filepath.Split(a.Target)
  1272  	if dir != "" {
  1273  		if err := b.Mkdir(dir); err != nil {
  1274  			return err
  1275  		}
  1276  	}
  1277  
  1278  	var gofiles, cgofiles, objdirCgofiles, cfiles, sfiles, cxxfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
  1279  
  1280  	gofiles = append(gofiles, a.Package.GoFiles...)
  1281  	cgofiles = append(cgofiles, a.Package.CgoFiles...)
  1282  	cfiles = append(cfiles, a.Package.CFiles...)
  1283  	sfiles = append(sfiles, a.Package.SFiles...)
  1284  	cxxfiles = append(cxxfiles, a.Package.CXXFiles...)
  1285  
  1286  	if a.Package.UsesCgo() || a.Package.UsesSwig() {
  1287  		if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.Package); err != nil {
  1288  			return
  1289  		}
  1290  	}
  1291  
  1292  	// Run SWIG on each .swig and .swigcxx file.
  1293  	// Each run will generate two files, a .go file and a .c or .cxx file.
  1294  	// The .go file will use import "C" and is to be processed by cgo.
  1295  	if a.Package.UsesSwig() {
  1296  		outGo, outC, outCXX, err := b.swig(a.Package, objdir, pcCFLAGS)
  1297  		if err != nil {
  1298  			return err
  1299  		}
  1300  		objdirCgofiles = append(objdirCgofiles, outGo...)
  1301  		cfiles = append(cfiles, outC...)
  1302  		cxxfiles = append(cxxfiles, outCXX...)
  1303  	}
  1304  
  1305  	// Run cgo.
  1306  	if a.Package.UsesCgo() || a.Package.UsesSwig() {
  1307  		// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
  1308  		// There is one exception: runtime/cgo's job is to bridge the
  1309  		// cgo and non-cgo worlds, so it necessarily has files in both.
  1310  		// In that case gcc only gets the gcc_* files.
  1311  		var gccfiles []string
  1312  		gccfiles = append(gccfiles, cfiles...)
  1313  		cfiles = nil
  1314  		if a.Package.Standard && a.Package.ImportPath == "runtime/cgo" {
  1315  			filter := func(files, nongcc, gcc []string) ([]string, []string) {
  1316  				for _, f := range files {
  1317  					if strings.HasPrefix(f, "gcc_") {
  1318  						gcc = append(gcc, f)
  1319  					} else {
  1320  						nongcc = append(nongcc, f)
  1321  					}
  1322  				}
  1323  				return nongcc, gcc
  1324  			}
  1325  			sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
  1326  		} else {
  1327  			for _, sfile := range sfiles {
  1328  				data, err := ioutil.ReadFile(filepath.Join(a.Package.Dir, sfile))
  1329  				if err == nil {
  1330  					if bytes.HasPrefix(data, []byte("TEXT")) || bytes.Contains(data, []byte("\nTEXT")) ||
  1331  						bytes.HasPrefix(data, []byte("DATA")) || bytes.Contains(data, []byte("\nDATA")) ||
  1332  						bytes.HasPrefix(data, []byte("GLOBL")) || bytes.Contains(data, []byte("\nGLOBL")) {
  1333  						return fmt.Errorf("package using cgo has Go assembly file %s", sfile)
  1334  					}
  1335  				}
  1336  			}
  1337  			gccfiles = append(gccfiles, sfiles...)
  1338  			sfiles = nil
  1339  		}
  1340  
  1341  		var cgoExe string
  1342  		if a.cgo != nil && a.cgo.Target != "" {
  1343  			cgoExe = a.cgo.Target
  1344  		} else {
  1345  			cgoExe = base.Tool("cgo")
  1346  		}
  1347  		outGo, outObj, err := b.cgo(a, cgoExe, objdir, pcCFLAGS, pcLDFLAGS, cgofiles, objdirCgofiles, gccfiles, cxxfiles, a.Package.MFiles, a.Package.FFiles)
  1348  		if err != nil {
  1349  			return err
  1350  		}
  1351  		if cfg.BuildToolchainName == "gccgo" {
  1352  			cgoObjects = append(cgoObjects, a.Objdir+"_cgo_flags")
  1353  		}
  1354  		cgoObjects = append(cgoObjects, outObj...)
  1355  		gofiles = append(gofiles, outGo...)
  1356  	}
  1357  
  1358  	if len(gofiles) == 0 {
  1359  		return &load.NoGoError{Package: a.Package}
  1360  	}
  1361  
  1362  	// If we're doing coverage, preprocess the .go files and put them in the work directory
  1363  	if a.Package.Internal.CoverMode != "" {
  1364  		for i, file := range gofiles {
  1365  			var sourceFile string
  1366  			var coverFile string
  1367  			var key string
  1368  			if strings.HasSuffix(file, ".cgo1.go") {
  1369  				// cgo files have absolute paths
  1370  				base := filepath.Base(file)
  1371  				sourceFile = file
  1372  				coverFile = objdir + base
  1373  				key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
  1374  			} else {
  1375  				sourceFile = filepath.Join(a.Package.Dir, file)
  1376  				coverFile = objdir + file
  1377  				key = file
  1378  			}
  1379  			cover := a.Package.Internal.CoverVars[key]
  1380  			if cover == nil || base.IsTestFile(file) {
  1381  				// Not covering this file.
  1382  				continue
  1383  			}
  1384  			if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
  1385  				return err
  1386  			}
  1387  			gofiles[i] = coverFile
  1388  		}
  1389  	}
  1390  
  1391  	// Prepare Go import path list.
  1392  	inc := b.includeArgs("-I", allArchiveActions(a))
  1393  
  1394  	// Compile Go.
  1395  	ofile, out, err := BuildToolchain.gc(b, a.Package, a.Objpkg, objdir, len(sfiles) > 0, inc, gofiles)
  1396  	if len(out) > 0 {
  1397  		b.showOutput(a.Package.Dir, a.Package.ImportPath, b.processOutput(out))
  1398  		if err != nil {
  1399  			return errPrintedOutput
  1400  		}
  1401  	}
  1402  	if err != nil {
  1403  		return err
  1404  	}
  1405  	if ofile != a.Objpkg {
  1406  		objects = append(objects, ofile)
  1407  	}
  1408  
  1409  	// Copy .h files named for goos or goarch or goos_goarch
  1410  	// to names using GOOS and GOARCH.
  1411  	// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
  1412  	_goos_goarch := "_" + cfg.Goos + "_" + cfg.Goarch
  1413  	_goos := "_" + cfg.Goos
  1414  	_goarch := "_" + cfg.Goarch
  1415  	for _, file := range a.Package.HFiles {
  1416  		name, ext := fileExtSplit(file)
  1417  		switch {
  1418  		case strings.HasSuffix(name, _goos_goarch):
  1419  			targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
  1420  			if err := b.copyFile(a, objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
  1421  				return err
  1422  			}
  1423  		case strings.HasSuffix(name, _goarch):
  1424  			targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
  1425  			if err := b.copyFile(a, objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
  1426  				return err
  1427  			}
  1428  		case strings.HasSuffix(name, _goos):
  1429  			targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
  1430  			if err := b.copyFile(a, objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
  1431  				return err
  1432  			}
  1433  		}
  1434  	}
  1435  
  1436  	for _, file := range cfiles {
  1437  		out := file[:len(file)-len(".c")] + ".o"
  1438  		if err := BuildToolchain.cc(b, a.Package, objdir, objdir+out, file); err != nil {
  1439  			return err
  1440  		}
  1441  		objects = append(objects, out)
  1442  	}
  1443  
  1444  	// Assemble .s files.
  1445  	if len(sfiles) > 0 {
  1446  		ofiles, err := BuildToolchain.asm(b, a.Package, objdir, sfiles)
  1447  		if err != nil {
  1448  			return err
  1449  		}
  1450  		objects = append(objects, ofiles...)
  1451  	}
  1452  
  1453  	// NOTE(rsc): On Windows, it is critically important that the
  1454  	// gcc-compiled objects (cgoObjects) be listed after the ordinary
  1455  	// objects in the archive. I do not know why this is.
  1456  	// https://golang.org/issue/2601
  1457  	objects = append(objects, cgoObjects...)
  1458  
  1459  	// Add system object files.
  1460  	for _, syso := range a.Package.SysoFiles {
  1461  		objects = append(objects, filepath.Join(a.Package.Dir, syso))
  1462  	}
  1463  
  1464  	// Pack into archive in objdir directory.
  1465  	// If the Go compiler wrote an archive, we only need to add the
  1466  	// object files for non-Go sources to the archive.
  1467  	// If the Go compiler wrote an archive and the package is entirely
  1468  	// Go sources, there is no pack to execute at all.
  1469  	if len(objects) > 0 {
  1470  		if err := BuildToolchain.pack(b, a.Package, objdir, a.Objpkg, objects); err != nil {
  1471  			return err
  1472  		}
  1473  	}
  1474  
  1475  	// Link if needed.
  1476  	if a.Link {
  1477  		// The compiler only cares about direct imports, but the
  1478  		// linker needs the whole dependency tree.
  1479  		all := ActionList(a)
  1480  		all = all[:len(all)-1] // drop a
  1481  		if err := BuildToolchain.ld(b, a, a.Target, all, a.Objpkg, objects); err != nil {
  1482  			return err
  1483  		}
  1484  	}
  1485  
  1486  	return nil
  1487  }
  1488  
  1489  // PkgconfigCmd returns a pkg-config binary name
  1490  // defaultPkgConfig is defined in zdefaultcc.go, written by cmd/dist.
  1491  func (b *Builder) PkgconfigCmd() string {
  1492  	return envList("PKG_CONFIG", cfg.DefaultPkgConfig)[0]
  1493  }
  1494  
  1495  // splitPkgConfigOutput parses the pkg-config output into a slice of
  1496  // flags. pkg-config always uses \ to escape special characters.
  1497  func splitPkgConfigOutput(out []byte) []string {
  1498  	if len(out) == 0 {
  1499  		return nil
  1500  	}
  1501  	var flags []string
  1502  	flag := make([]byte, len(out))
  1503  	r, w := 0, 0
  1504  	for r < len(out) {
  1505  		switch out[r] {
  1506  		case ' ', '\t', '\r', '\n':
  1507  			if w > 0 {
  1508  				flags = append(flags, string(flag[:w]))
  1509  			}
  1510  			w = 0
  1511  		case '\\':
  1512  			r++
  1513  			fallthrough
  1514  		default:
  1515  			if r < len(out) {
  1516  				flag[w] = out[r]
  1517  				w++
  1518  			}
  1519  		}
  1520  		r++
  1521  	}
  1522  	if w > 0 {
  1523  		flags = append(flags, string(flag[:w]))
  1524  	}
  1525  	return flags
  1526  }
  1527  
  1528  // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
  1529  func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, err error) {
  1530  	if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
  1531  		var out []byte
  1532  		out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--cflags", pkgs)
  1533  		if err != nil {
  1534  			b.showOutput(p.Dir, b.PkgconfigCmd()+" --cflags "+strings.Join(pkgs, " "), string(out))
  1535  			b.Print(err.Error() + "\n")
  1536  			err = errPrintedOutput
  1537  			return
  1538  		}
  1539  		if len(out) > 0 {
  1540  			cflags = splitPkgConfigOutput(out)
  1541  		}
  1542  		out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--libs", pkgs)
  1543  		if err != nil {
  1544  			b.showOutput(p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pkgs, " "), string(out))
  1545  			b.Print(err.Error() + "\n")
  1546  			err = errPrintedOutput
  1547  			return
  1548  		}
  1549  		if len(out) > 0 {
  1550  			ldflags = strings.Fields(string(out))
  1551  		}
  1552  	}
  1553  	return
  1554  }
  1555  
  1556  func (b *Builder) installShlibname(a *Action) error {
  1557  	a1 := a.Deps[0]
  1558  	err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666)
  1559  	if err != nil {
  1560  		return err
  1561  	}
  1562  	if cfg.BuildX {
  1563  		b.Showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.Target), a.Target)
  1564  	}
  1565  	return nil
  1566  }
  1567  
  1568  func (b *Builder) linkShared(a *Action) (err error) {
  1569  	allactions := ActionList(a)
  1570  	allactions = allactions[:len(allactions)-1]
  1571  	return BuildToolchain.ldShared(b, a.Deps, a.Target, allactions)
  1572  }
  1573  
  1574  // BuildInstallFunc is the action for installing a single package or executable.
  1575  func BuildInstallFunc(b *Builder, a *Action) (err error) {
  1576  	defer func() {
  1577  		if err != nil && err != errPrintedOutput {
  1578  			err = fmt.Errorf("go install %s: %v", a.Package.ImportPath, err)
  1579  		}
  1580  	}()
  1581  	a1 := a.Deps[0]
  1582  	perm := os.FileMode(0666)
  1583  	if a1.Link {
  1584  		switch cfg.BuildBuildmode {
  1585  		case "c-archive", "c-shared", "plugin":
  1586  		default:
  1587  			perm = 0777
  1588  		}
  1589  	}
  1590  
  1591  	// make target directory
  1592  	dir, _ := filepath.Split(a.Target)
  1593  	if dir != "" {
  1594  		if err := b.Mkdir(dir); err != nil {
  1595  			return err
  1596  		}
  1597  	}
  1598  
  1599  	// remove object dir to keep the amount of
  1600  	// garbage down in a large build. On an operating system
  1601  	// with aggressive buffering, cleaning incrementally like
  1602  	// this keeps the intermediate objects from hitting the disk.
  1603  	if !cfg.BuildWork {
  1604  		defer os.RemoveAll(a1.Objdir)
  1605  		defer os.Remove(a1.Target)
  1606  	}
  1607  
  1608  	return b.moveOrCopyFile(a, a.Target, a1.Target, perm, false)
  1609  }
  1610  
  1611  // includeArgs returns the -I or -L directory list for access
  1612  // to the results of the list of actions.
  1613  func (b *Builder) includeArgs(flag string, all []*Action) []string {
  1614  	inc := []string{}
  1615  	incMap := map[string]bool{
  1616  		b.WorkDir:     true, // handled later
  1617  		cfg.GOROOTpkg: true,
  1618  		"":            true, // ignore empty strings
  1619  	}
  1620  
  1621  	// Look in the temporary space for results of test-specific actions.
  1622  	// This is the $WORK/my/package/_test directory for the
  1623  	// package being built, so there are few of these.
  1624  	for _, a1 := range all {
  1625  		if a1.Package == nil {
  1626  			continue
  1627  		}
  1628  		if dir := a1.Pkgdir; dir != a1.Package.Internal.Build.PkgRoot && !incMap[dir] {
  1629  			incMap[dir] = true
  1630  			inc = append(inc, flag, dir)
  1631  		}
  1632  	}
  1633  
  1634  	// Also look in $WORK for any non-test packages that have
  1635  	// been built but not installed.
  1636  	inc = append(inc, flag, b.WorkDir)
  1637  
  1638  	// Finally, look in the installed package directories for each action.
  1639  	// First add the package dirs corresponding to GOPATH entries
  1640  	// in the original GOPATH order.
  1641  	need := map[string]*build.Package{}
  1642  	for _, a1 := range all {
  1643  		if a1.Package != nil && a1.Pkgdir == a1.Package.Internal.Build.PkgRoot {
  1644  			need[a1.Package.Internal.Build.Root] = a1.Package.Internal.Build
  1645  		}
  1646  	}
  1647  	for _, root := range cfg.Gopath {
  1648  		if p := need[root]; p != nil && !incMap[p.PkgRoot] {
  1649  			incMap[p.PkgRoot] = true
  1650  			inc = append(inc, flag, p.PkgTargetRoot)
  1651  		}
  1652  	}
  1653  
  1654  	// Then add anything that's left.
  1655  	for _, a1 := range all {
  1656  		if a1.Package == nil {
  1657  			continue
  1658  		}
  1659  		if dir := a1.Pkgdir; dir == a1.Package.Internal.Build.PkgRoot && !incMap[dir] {
  1660  			incMap[dir] = true
  1661  			inc = append(inc, flag, a1.Package.Internal.Build.PkgTargetRoot)
  1662  		}
  1663  	}
  1664  
  1665  	return inc
  1666  }
  1667  
  1668  // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
  1669  func (b *Builder) moveOrCopyFile(a *Action, dst, src string, perm os.FileMode, force bool) error {
  1670  	if cfg.BuildN {
  1671  		b.Showcmd("", "mv %s %s", src, dst)
  1672  		return nil
  1673  	}
  1674  
  1675  	// If we can update the mode and rename to the dst, do it.
  1676  	// Otherwise fall back to standard copy.
  1677  
  1678  	// If the destination directory has the group sticky bit set,
  1679  	// we have to copy the file to retain the correct permissions.
  1680  	// https://golang.org/issue/18878
  1681  	if fi, err := os.Stat(filepath.Dir(dst)); err == nil {
  1682  		if fi.IsDir() && (fi.Mode()&os.ModeSetgid) != 0 {
  1683  			return b.copyFile(a, dst, src, perm, force)
  1684  		}
  1685  	}
  1686  
  1687  	// The perm argument is meant to be adjusted according to umask,
  1688  	// but we don't know what the umask is.
  1689  	// Create a dummy file to find out.
  1690  	// This avoids build tags and works even on systems like Plan 9
  1691  	// where the file mask computation incorporates other information.
  1692  	mode := perm
  1693  	f, err := os.OpenFile(filepath.Clean(dst)+"-go-tmp-umask", os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
  1694  	if err == nil {
  1695  		fi, err := f.Stat()
  1696  		if err == nil {
  1697  			mode = fi.Mode() & 0777
  1698  		}
  1699  		name := f.Name()
  1700  		f.Close()
  1701  		os.Remove(name)
  1702  	}
  1703  
  1704  	if err := os.Chmod(src, mode); err == nil {
  1705  		if err := os.Rename(src, dst); err == nil {
  1706  			if cfg.BuildX {
  1707  				b.Showcmd("", "mv %s %s", src, dst)
  1708  			}
  1709  			return nil
  1710  		}
  1711  	}
  1712  
  1713  	return b.copyFile(a, dst, src, perm, force)
  1714  }
  1715  
  1716  // copyFile is like 'cp src dst'.
  1717  func (b *Builder) copyFile(a *Action, dst, src string, perm os.FileMode, force bool) error {
  1718  	if cfg.BuildN || cfg.BuildX {
  1719  		b.Showcmd("", "cp %s %s", src, dst)
  1720  		if cfg.BuildN {
  1721  			return nil
  1722  		}
  1723  	}
  1724  
  1725  	sf, err := os.Open(src)
  1726  	if err != nil {
  1727  		return err
  1728  	}
  1729  	defer sf.Close()
  1730  
  1731  	// Be careful about removing/overwriting dst.
  1732  	// Do not remove/overwrite if dst exists and is a directory
  1733  	// or a non-object file.
  1734  	if fi, err := os.Stat(dst); err == nil {
  1735  		if fi.IsDir() {
  1736  			return fmt.Errorf("build output %q already exists and is a directory", dst)
  1737  		}
  1738  		if !force && fi.Mode().IsRegular() && !isObject(dst) {
  1739  			return fmt.Errorf("build output %q already exists and is not an object file", dst)
  1740  		}
  1741  	}
  1742  
  1743  	// On Windows, remove lingering ~ file from last attempt.
  1744  	if base.ToolIsWindows {
  1745  		if _, err := os.Stat(dst + "~"); err == nil {
  1746  			os.Remove(dst + "~")
  1747  		}
  1748  	}
  1749  
  1750  	mayberemovefile(dst)
  1751  	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1752  	if err != nil && base.ToolIsWindows {
  1753  		// Windows does not allow deletion of a binary file
  1754  		// while it is executing. Try to move it out of the way.
  1755  		// If the move fails, which is likely, we'll try again the
  1756  		// next time we do an install of this binary.
  1757  		if err := os.Rename(dst, dst+"~"); err == nil {
  1758  			os.Remove(dst + "~")
  1759  		}
  1760  		df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1761  	}
  1762  	if err != nil {
  1763  		return err
  1764  	}
  1765  
  1766  	_, err = io.Copy(df, sf)
  1767  	df.Close()
  1768  	if err != nil {
  1769  		mayberemovefile(dst)
  1770  		return fmt.Errorf("copying %s to %s: %v", src, dst, err)
  1771  	}
  1772  	return nil
  1773  }
  1774  
  1775  // Install the cgo export header file, if there is one.
  1776  func (b *Builder) installHeader(a *Action) error {
  1777  	src := a.Objdir + "_cgo_install.h"
  1778  	if _, err := os.Stat(src); os.IsNotExist(err) {
  1779  		// If the file does not exist, there are no exported
  1780  		// functions, and we do not install anything.
  1781  		return nil
  1782  	}
  1783  
  1784  	dir, _ := filepath.Split(a.Target)
  1785  	if dir != "" {
  1786  		if err := b.Mkdir(dir); err != nil {
  1787  			return err
  1788  		}
  1789  	}
  1790  
  1791  	return b.moveOrCopyFile(a, a.Target, src, 0666, true)
  1792  }
  1793  
  1794  // cover runs, in effect,
  1795  //	go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
  1796  func (b *Builder) cover(a *Action, dst, src string, perm os.FileMode, varName string) error {
  1797  	return b.run(a.Objdir, "cover "+a.Package.ImportPath, nil,
  1798  		cfg.BuildToolexec,
  1799  		base.Tool("cover"),
  1800  		"-mode", a.Package.Internal.CoverMode,
  1801  		"-var", varName,
  1802  		"-o", dst,
  1803  		src)
  1804  }
  1805  
  1806  var objectMagic = [][]byte{
  1807  	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
  1808  	{'\x7F', 'E', 'L', 'F'},                   // ELF
  1809  	{0xFE, 0xED, 0xFA, 0xCE},                  // Mach-O big-endian 32-bit
  1810  	{0xFE, 0xED, 0xFA, 0xCF},                  // Mach-O big-endian 64-bit
  1811  	{0xCE, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 32-bit
  1812  	{0xCF, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 64-bit
  1813  	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00},      // PE (Windows) as generated by 6l/8l and gcc
  1814  	{0x00, 0x00, 0x01, 0xEB},                  // Plan 9 i386
  1815  	{0x00, 0x00, 0x8a, 0x97},                  // Plan 9 amd64
  1816  	{0x00, 0x00, 0x06, 0x47},                  // Plan 9 arm
  1817  }
  1818  
  1819  func isObject(s string) bool {
  1820  	f, err := os.Open(s)
  1821  	if err != nil {
  1822  		return false
  1823  	}
  1824  	defer f.Close()
  1825  	buf := make([]byte, 64)
  1826  	io.ReadFull(f, buf)
  1827  	for _, magic := range objectMagic {
  1828  		if bytes.HasPrefix(buf, magic) {
  1829  			return true
  1830  		}
  1831  	}
  1832  	return false
  1833  }
  1834  
  1835  // mayberemovefile removes a file only if it is a regular file
  1836  // When running as a user with sufficient privileges, we may delete
  1837  // even device files, for example, which is not intended.
  1838  func mayberemovefile(s string) {
  1839  	if fi, err := os.Lstat(s); err == nil && !fi.Mode().IsRegular() {
  1840  		return
  1841  	}
  1842  	os.Remove(s)
  1843  }
  1844  
  1845  // fmtcmd formats a command in the manner of fmt.Sprintf but also:
  1846  //
  1847  //	If dir is non-empty and the script is not in dir right now,
  1848  //	fmtcmd inserts "cd dir\n" before the command.
  1849  //
  1850  //	fmtcmd replaces the value of b.WorkDir with $WORK.
  1851  //	fmtcmd replaces the value of goroot with $GOROOT.
  1852  //	fmtcmd replaces the value of b.gobin with $GOBIN.
  1853  //
  1854  //	fmtcmd replaces the name of the current directory with dot (.)
  1855  //	but only when it is at the beginning of a space-separated token.
  1856  //
  1857  func (b *Builder) fmtcmd(dir string, format string, args ...interface{}) string {
  1858  	cmd := fmt.Sprintf(format, args...)
  1859  	if dir != "" && dir != "/" {
  1860  		cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
  1861  		if b.scriptDir != dir {
  1862  			b.scriptDir = dir
  1863  			cmd = "cd " + dir + "\n" + cmd
  1864  		}
  1865  	}
  1866  	if b.WorkDir != "" {
  1867  		cmd = strings.Replace(cmd, b.WorkDir, "$WORK", -1)
  1868  	}
  1869  	return cmd
  1870  }
  1871  
  1872  // showcmd prints the given command to standard output
  1873  // for the implementation of -n or -x.
  1874  func (b *Builder) Showcmd(dir string, format string, args ...interface{}) {
  1875  	b.output.Lock()
  1876  	defer b.output.Unlock()
  1877  	b.Print(b.fmtcmd(dir, format, args...) + "\n")
  1878  }
  1879  
  1880  // showOutput prints "# desc" followed by the given output.
  1881  // The output is expected to contain references to 'dir', usually
  1882  // the source directory for the package that has failed to build.
  1883  // showOutput rewrites mentions of dir with a relative path to dir
  1884  // when the relative path is shorter. This is usually more pleasant.
  1885  // For example, if fmt doesn't compile and we are in src/html,
  1886  // the output is
  1887  //
  1888  //	$ go build
  1889  //	# fmt
  1890  //	../fmt/print.go:1090: undefined: asdf
  1891  //	$
  1892  //
  1893  // instead of
  1894  //
  1895  //	$ go build
  1896  //	# fmt
  1897  //	/usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
  1898  //	$
  1899  //
  1900  // showOutput also replaces references to the work directory with $WORK.
  1901  //
  1902  func (b *Builder) showOutput(dir, desc, out string) {
  1903  	prefix := "# " + desc
  1904  	suffix := "\n" + out
  1905  	if reldir := base.ShortPath(dir); reldir != dir {
  1906  		suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
  1907  		suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
  1908  	}
  1909  	suffix = strings.Replace(suffix, " "+b.WorkDir, " $WORK", -1)
  1910  
  1911  	b.output.Lock()
  1912  	defer b.output.Unlock()
  1913  	b.Print(prefix, suffix)
  1914  }
  1915  
  1916  // errPrintedOutput is a special error indicating that a command failed
  1917  // but that it generated output as well, and that output has already
  1918  // been printed, so there's no point showing 'exit status 1' or whatever
  1919  // the wait status was. The main executor, builder.do, knows not to
  1920  // print this error.
  1921  var errPrintedOutput = errors.New("already printed output - no need to show error")
  1922  
  1923  var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+(:[0-9]+)?\]`)
  1924  var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
  1925  
  1926  // run runs the command given by cmdline in the directory dir.
  1927  // If the command fails, run prints information about the failure
  1928  // and returns a non-nil error.
  1929  func (b *Builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
  1930  	out, err := b.runOut(dir, desc, env, cmdargs...)
  1931  	if len(out) > 0 {
  1932  		if desc == "" {
  1933  			desc = b.fmtcmd(dir, "%s", strings.Join(str.StringList(cmdargs...), " "))
  1934  		}
  1935  		b.showOutput(dir, desc, b.processOutput(out))
  1936  		if err != nil {
  1937  			err = errPrintedOutput
  1938  		}
  1939  	}
  1940  	return err
  1941  }
  1942  
  1943  // processOutput prepares the output of runOut to be output to the console.
  1944  func (b *Builder) processOutput(out []byte) string {
  1945  	if out[len(out)-1] != '\n' {
  1946  		out = append(out, '\n')
  1947  	}
  1948  	messages := string(out)
  1949  	// Fix up output referring to cgo-generated code to be more readable.
  1950  	// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
  1951  	// Replace *[100]_Ctype_foo with *[100]C.foo.
  1952  	// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
  1953  	if !cfg.BuildX && cgoLine.MatchString(messages) {
  1954  		messages = cgoLine.ReplaceAllString(messages, "")
  1955  		messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
  1956  	}
  1957  	return messages
  1958  }
  1959  
  1960  // runOut runs the command given by cmdline in the directory dir.
  1961  // It returns the command output and any errors that occurred.
  1962  func (b *Builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
  1963  	cmdline := str.StringList(cmdargs...)
  1964  	if cfg.BuildN || cfg.BuildX {
  1965  		var envcmdline string
  1966  		for _, e := range env {
  1967  			if j := strings.IndexByte(e, '='); j != -1 {
  1968  				if strings.ContainsRune(e[j+1:], '\'') {
  1969  					envcmdline += fmt.Sprintf("%s=%q", e[:j], e[j+1:])
  1970  				} else {
  1971  					envcmdline += fmt.Sprintf("%s='%s'", e[:j], e[j+1:])
  1972  				}
  1973  				envcmdline += " "
  1974  			}
  1975  		}
  1976  		envcmdline += joinUnambiguously(cmdline)
  1977  		b.Showcmd(dir, "%s", envcmdline)
  1978  		if cfg.BuildN {
  1979  			return nil, nil
  1980  		}
  1981  	}
  1982  
  1983  	nbusy := 0
  1984  	for {
  1985  		var buf bytes.Buffer
  1986  		cmd := exec.Command(cmdline[0], cmdline[1:]...)
  1987  		cmd.Stdout = &buf
  1988  		cmd.Stderr = &buf
  1989  		cmd.Dir = dir
  1990  		cmd.Env = base.MergeEnvLists(env, base.EnvForDir(cmd.Dir, os.Environ()))
  1991  		err := cmd.Run()
  1992  
  1993  		// cmd.Run will fail on Unix if some other process has the binary
  1994  		// we want to run open for writing. This can happen here because
  1995  		// we build and install the cgo command and then run it.
  1996  		// If another command was kicked off while we were writing the
  1997  		// cgo binary, the child process for that command may be holding
  1998  		// a reference to the fd, keeping us from running exec.
  1999  		//
  2000  		// But, you might reasonably wonder, how can this happen?
  2001  		// The cgo fd, like all our fds, is close-on-exec, so that we need
  2002  		// not worry about other processes inheriting the fd accidentally.
  2003  		// The answer is that running a command is fork and exec.
  2004  		// A child forked while the cgo fd is open inherits that fd.
  2005  		// Until the child has called exec, it holds the fd open and the
  2006  		// kernel will not let us run cgo. Even if the child were to close
  2007  		// the fd explicitly, it would still be open from the time of the fork
  2008  		// until the time of the explicit close, and the race would remain.
  2009  		//
  2010  		// On Unix systems, this results in ETXTBSY, which formats
  2011  		// as "text file busy". Rather than hard-code specific error cases,
  2012  		// we just look for that string. If this happens, sleep a little
  2013  		// and try again. We let this happen three times, with increasing
  2014  		// sleep lengths: 100+200+400 ms = 0.7 seconds.
  2015  		//
  2016  		// An alternate solution might be to split the cmd.Run into
  2017  		// separate cmd.Start and cmd.Wait, and then use an RWLock
  2018  		// to make sure that copyFile only executes when no cmd.Start
  2019  		// call is in progress. However, cmd.Start (really syscall.forkExec)
  2020  		// only guarantees that when it returns, the exec is committed to
  2021  		// happen and succeed. It uses a close-on-exec file descriptor
  2022  		// itself to determine this, so we know that when cmd.Start returns,
  2023  		// at least one close-on-exec file descriptor has been closed.
  2024  		// However, we cannot be sure that all of them have been closed,
  2025  		// so the program might still encounter ETXTBSY even with such
  2026  		// an RWLock. The race window would be smaller, perhaps, but not
  2027  		// guaranteed to be gone.
  2028  		//
  2029  		// Sleeping when we observe the race seems to be the most reliable
  2030  		// option we have.
  2031  		//
  2032  		// https://golang.org/issue/3001
  2033  		//
  2034  		if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
  2035  			time.Sleep(100 * time.Millisecond << uint(nbusy))
  2036  			nbusy++
  2037  			continue
  2038  		}
  2039  
  2040  		// err can be something like 'exit status 1'.
  2041  		// Add information about what program was running.
  2042  		// Note that if buf.Bytes() is non-empty, the caller usually
  2043  		// shows buf.Bytes() and does not print err at all, so the
  2044  		// prefix here does not make most output any more verbose.
  2045  		if err != nil {
  2046  			err = errors.New(cmdline[0] + ": " + err.Error())
  2047  		}
  2048  		return buf.Bytes(), err
  2049  	}
  2050  }
  2051  
  2052  // joinUnambiguously prints the slice, quoting where necessary to make the
  2053  // output unambiguous.
  2054  // TODO: See issue 5279. The printing of commands needs a complete redo.
  2055  func joinUnambiguously(a []string) string {
  2056  	var buf bytes.Buffer
  2057  	for i, s := range a {
  2058  		if i > 0 {
  2059  			buf.WriteByte(' ')
  2060  		}
  2061  		q := strconv.Quote(s)
  2062  		if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
  2063  			buf.WriteString(q)
  2064  		} else {
  2065  			buf.WriteString(s)
  2066  		}
  2067  	}
  2068  	return buf.String()
  2069  }
  2070  
  2071  // mkdir makes the named directory.
  2072  func (b *Builder) Mkdir(dir string) error {
  2073  	b.exec.Lock()
  2074  	defer b.exec.Unlock()
  2075  	// We can be a little aggressive about being
  2076  	// sure directories exist. Skip repeated calls.
  2077  	if b.mkdirCache[dir] {
  2078  		return nil
  2079  	}
  2080  	b.mkdirCache[dir] = true
  2081  
  2082  	if cfg.BuildN || cfg.BuildX {
  2083  		b.Showcmd("", "mkdir -p %s", dir)
  2084  		if cfg.BuildN {
  2085  			return nil
  2086  		}
  2087  	}
  2088  
  2089  	if err := os.MkdirAll(dir, 0777); err != nil {
  2090  		return err
  2091  	}
  2092  	return nil
  2093  }
  2094  
  2095  // mkAbs returns an absolute path corresponding to
  2096  // evaluating f in the directory dir.
  2097  // We always pass absolute paths of source files so that
  2098  // the error messages will include the full path to a file
  2099  // in need of attention.
  2100  func mkAbs(dir, f string) string {
  2101  	// Leave absolute paths alone.
  2102  	// Also, during -n mode we use the pseudo-directory $WORK
  2103  	// instead of creating an actual work directory that won't be used.
  2104  	// Leave paths beginning with $WORK alone too.
  2105  	if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
  2106  		return f
  2107  	}
  2108  	return filepath.Join(dir, f)
  2109  }
  2110  
  2111  type toolchain interface {
  2112  	// gc runs the compiler in a specific directory on a set of files
  2113  	// and returns the name of the generated output file.
  2114  	gc(b *Builder, p *load.Package, archive, objdir string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
  2115  	// cc runs the toolchain's C compiler in a directory on a C file
  2116  	// to produce an output file.
  2117  	cc(b *Builder, p *load.Package, objdir, ofile, cfile string) error
  2118  	// asm runs the assembler in a specific directory on specific files
  2119  	// and returns a list of named output files.
  2120  	asm(b *Builder, p *load.Package, objdir string, sfiles []string) ([]string, error)
  2121  	// pkgpath builds an appropriate path for a temporary package file.
  2122  	Pkgpath(basedir string, p *load.Package) string
  2123  	// pack runs the archive packer in a specific directory to create
  2124  	// an archive from a set of object files.
  2125  	// typically it is run in the object directory.
  2126  	pack(b *Builder, p *load.Package, objdir, afile string, ofiles []string) error
  2127  	// ld runs the linker to create an executable starting at mainpkg.
  2128  	ld(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string) error
  2129  	// ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
  2130  	ldShared(b *Builder, toplevelactions []*Action, out string, allactions []*Action) error
  2131  
  2132  	compiler() string
  2133  	linker() string
  2134  }
  2135  
  2136  type noToolchain struct{}
  2137  
  2138  func noCompiler() error {
  2139  	log.Fatalf("unknown compiler %q", cfg.BuildContext.Compiler)
  2140  	return nil
  2141  }
  2142  
  2143  func (noToolchain) compiler() string {
  2144  	noCompiler()
  2145  	return ""
  2146  }
  2147  
  2148  func (noToolchain) linker() string {
  2149  	noCompiler()
  2150  	return ""
  2151  }
  2152  
  2153  func (noToolchain) gc(b *Builder, p *load.Package, archive, objdir string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
  2154  	return "", nil, noCompiler()
  2155  }
  2156  
  2157  func (noToolchain) asm(b *Builder, p *load.Package, objdir string, sfiles []string) ([]string, error) {
  2158  	return nil, noCompiler()
  2159  }
  2160  
  2161  func (noToolchain) Pkgpath(basedir string, p *load.Package) string {
  2162  	noCompiler()
  2163  	return ""
  2164  }
  2165  
  2166  func (noToolchain) pack(b *Builder, p *load.Package, objdir, afile string, ofiles []string) error {
  2167  	return noCompiler()
  2168  }
  2169  
  2170  func (noToolchain) ld(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string) error {
  2171  	return noCompiler()
  2172  }
  2173  
  2174  func (noToolchain) ldShared(b *Builder, toplevelactions []*Action, out string, allactions []*Action) error {
  2175  	return noCompiler()
  2176  }
  2177  
  2178  func (noToolchain) cc(b *Builder, p *load.Package, objdir, ofile, cfile string) error {
  2179  	return noCompiler()
  2180  }
  2181  
  2182  // The Go toolchain.
  2183  type gcToolchain struct{}
  2184  
  2185  func (gcToolchain) compiler() string {
  2186  	return base.Tool("compile")
  2187  }
  2188  
  2189  func (gcToolchain) linker() string {
  2190  	return base.Tool("link")
  2191  }
  2192  
  2193  func (gcToolchain) gc(b *Builder, p *load.Package, archive, objdir string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
  2194  	if archive != "" {
  2195  		ofile = archive
  2196  	} else {
  2197  		out := "_go_.o"
  2198  		ofile = objdir + out
  2199  	}
  2200  
  2201  	pkgpath := p.ImportPath
  2202  	if cfg.BuildBuildmode == "plugin" {
  2203  		if pkgpath == "command-line-arguments" {
  2204  			pkgpath = "plugin/unnamed-" + p.Internal.BuildID
  2205  		}
  2206  	} else if p.Name == "main" {
  2207  		pkgpath = "main"
  2208  	}
  2209  	gcargs := []string{"-p", pkgpath}
  2210  	if p.Standard {
  2211  		gcargs = append(gcargs, "-std")
  2212  	}
  2213  	compilingRuntime := p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal"))
  2214  	if compilingRuntime {
  2215  		// runtime compiles with a special gc flag to emit
  2216  		// additional reflect type data.
  2217  		gcargs = append(gcargs, "-+")
  2218  	}
  2219  
  2220  	// If we're giving the compiler the entire package (no C etc files), tell it that,
  2221  	// so that it can give good error messages about forward declarations.
  2222  	// Exceptions: a few standard packages have forward declarations for
  2223  	// pieces supplied behind-the-scenes by package runtime.
  2224  	extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.FFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
  2225  	if p.Standard {
  2226  		switch p.ImportPath {
  2227  		case "bytes", "internal/poll", "net", "os", "runtime/pprof", "sync", "syscall", "time":
  2228  			extFiles++
  2229  		}
  2230  	}
  2231  	if extFiles == 0 {
  2232  		gcargs = append(gcargs, "-complete")
  2233  	}
  2234  	if cfg.BuildContext.InstallSuffix != "" {
  2235  		gcargs = append(gcargs, "-installsuffix", cfg.BuildContext.InstallSuffix)
  2236  	}
  2237  	if p.Internal.BuildID != "" {
  2238  		gcargs = append(gcargs, "-buildid", p.Internal.BuildID)
  2239  	}
  2240  	platform := cfg.Goos + "/" + cfg.Goarch
  2241  	if p.Internal.OmitDebug || platform == "nacl/amd64p32" || platform == "darwin/arm" || platform == "darwin/arm64" || cfg.Goos == "plan9" {
  2242  		gcargs = append(gcargs, "-dwarf=false")
  2243  	}
  2244  
  2245  	for _, path := range p.Imports {
  2246  		if i := strings.LastIndex(path, "/vendor/"); i >= 0 {
  2247  			gcargs = append(gcargs, "-importmap", path[i+len("/vendor/"):]+"="+path)
  2248  		} else if strings.HasPrefix(path, "vendor/") {
  2249  			gcargs = append(gcargs, "-importmap", path[len("vendor/"):]+"="+path)
  2250  		}
  2251  	}
  2252  
  2253  	gcflags := buildGcflags
  2254  	if compilingRuntime {
  2255  		// Remove -N, if present.
  2256  		// It is not possible to build the runtime with no optimizations,
  2257  		// because the compiler cannot eliminate enough write barriers.
  2258  		gcflags = make([]string, len(buildGcflags))
  2259  		copy(gcflags, buildGcflags)
  2260  		for i := 0; i < len(gcflags); i++ {
  2261  			if gcflags[i] == "-N" {
  2262  				copy(gcflags[i:], gcflags[i+1:])
  2263  				gcflags = gcflags[:len(gcflags)-1]
  2264  				i--
  2265  			}
  2266  		}
  2267  	}
  2268  	args := []interface{}{cfg.BuildToolexec, base.Tool("compile"), "-o", ofile, "-trimpath", b.WorkDir, gcflags, gcargs, "-D", p.Internal.LocalPrefix, importArgs}
  2269  	if ofile == archive {
  2270  		args = append(args, "-pack")
  2271  	}
  2272  	if asmhdr {
  2273  		args = append(args, "-asmhdr", objdir+"go_asm.h")
  2274  	}
  2275  
  2276  	// Add -c=N to use concurrent backend compilation, if possible.
  2277  	if c := gcBackendConcurrency(gcflags); c > 1 {
  2278  		args = append(args, fmt.Sprintf("-c=%d", c))
  2279  	}
  2280  
  2281  	for _, f := range gofiles {
  2282  		args = append(args, mkAbs(p.Dir, f))
  2283  	}
  2284  
  2285  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args...)
  2286  	return ofile, output, err
  2287  }
  2288  
  2289  // gcBackendConcurrency returns the backend compiler concurrency level for a package compilation.
  2290  func gcBackendConcurrency(gcflags []string) int {
  2291  	// First, check whether we can use -c at all for this compilation.
  2292  	canDashC := concurrentGCBackendCompilationEnabledByDefault
  2293  
  2294  	switch e := os.Getenv("GO19CONCURRENTCOMPILATION"); e {
  2295  	case "0":
  2296  		canDashC = false
  2297  	case "1":
  2298  		canDashC = true
  2299  	case "":
  2300  		// Not set. Use default.
  2301  	default:
  2302  		log.Fatalf("GO19CONCURRENTCOMPILATION must be 0, 1, or unset, got %q", e)
  2303  	}
  2304  
  2305  	if os.Getenv("GOEXPERIMENT") != "" {
  2306  		// Concurrent compilation is presumed incompatible with GOEXPERIMENTs.
  2307  		canDashC = false
  2308  	}
  2309  
  2310  CheckFlags:
  2311  	for _, flag := range gcflags {
  2312  		// Concurrent compilation is presumed incompatible with any gcflags,
  2313  		// except for a small whitelist of commonly used flags.
  2314  		// If the user knows better, they can manually add their own -c to the gcflags.
  2315  		switch flag {
  2316  		case "-N", "-l", "-S", "-B", "-C", "-I":
  2317  			// OK
  2318  		default:
  2319  			canDashC = false
  2320  			break CheckFlags
  2321  		}
  2322  	}
  2323  
  2324  	if !canDashC {
  2325  		return 1
  2326  	}
  2327  
  2328  	// Decide how many concurrent backend compilations to allow.
  2329  	//
  2330  	// If we allow too many, in theory we might end up with p concurrent processes,
  2331  	// each with c concurrent backend compiles, all fighting over the same resources.
  2332  	// However, in practice, that seems not to happen too much.
  2333  	// Most build graphs are surprisingly serial, so p==1 for much of the build.
  2334  	// Furthermore, concurrent backend compilation is only enabled for a part
  2335  	// of the overall compiler execution, so c==1 for much of the build.
  2336  	// So don't worry too much about that interaction for now.
  2337  	//
  2338  	// However, in practice, setting c above 4 tends not to help very much.
  2339  	// See the analysis in CL 41192.
  2340  	//
  2341  	// TODO(josharian): attempt to detect whether this particular compilation
  2342  	// is likely to be a bottleneck, e.g. when:
  2343  	//   - it has no successor packages to compile (usually package main)
  2344  	//   - all paths through the build graph pass through it
  2345  	//   - critical path scheduling says it is high priority
  2346  	// and in such a case, set c to runtime.NumCPU.
  2347  	// We do this now when p==1.
  2348  	if cfg.BuildP == 1 {
  2349  		// No process parallelism. Max out c.
  2350  		return runtime.NumCPU()
  2351  	}
  2352  	// Some process parallelism. Set c to min(4, numcpu).
  2353  	c := 4
  2354  	if ncpu := runtime.NumCPU(); ncpu < c {
  2355  		c = ncpu
  2356  	}
  2357  	return c
  2358  }
  2359  
  2360  func (gcToolchain) asm(b *Builder, p *load.Package, objdir string, sfiles []string) ([]string, error) {
  2361  	// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
  2362  	inc := filepath.Join(cfg.GOROOT, "pkg", "include")
  2363  	args := []interface{}{cfg.BuildToolexec, base.Tool("asm"), "-trimpath", b.WorkDir, "-I", objdir, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, buildAsmflags}
  2364  	if p.ImportPath == "runtime" && cfg.Goarch == "386" {
  2365  		for _, arg := range buildAsmflags {
  2366  			if arg == "-dynlink" {
  2367  				args = append(args, "-D=GOBUILDMODE_shared=1")
  2368  			}
  2369  		}
  2370  	}
  2371  	var ofiles []string
  2372  	for _, sfile := range sfiles {
  2373  		ofile := objdir + sfile[:len(sfile)-len(".s")] + ".o"
  2374  		ofiles = append(ofiles, ofile)
  2375  		a := append(args, "-o", ofile, mkAbs(p.Dir, sfile))
  2376  		if err := b.run(p.Dir, p.ImportPath, nil, a...); err != nil {
  2377  			return nil, err
  2378  		}
  2379  	}
  2380  	return ofiles, nil
  2381  }
  2382  
  2383  // toolVerify checks that the command line args writes the same output file
  2384  // if run using newTool instead.
  2385  // Unused now but kept around for future use.
  2386  func toolVerify(b *Builder, p *load.Package, newTool string, ofile string, args []interface{}) error {
  2387  	newArgs := make([]interface{}, len(args))
  2388  	copy(newArgs, args)
  2389  	newArgs[1] = base.Tool(newTool)
  2390  	newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
  2391  	if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
  2392  		return err
  2393  	}
  2394  	data1, err := ioutil.ReadFile(ofile)
  2395  	if err != nil {
  2396  		return err
  2397  	}
  2398  	data2, err := ioutil.ReadFile(ofile + ".new")
  2399  	if err != nil {
  2400  		return err
  2401  	}
  2402  	if !bytes.Equal(data1, data2) {
  2403  		return fmt.Errorf("%s and %s produced different output files:\n%s\n%s", filepath.Base(args[1].(string)), newTool, strings.Join(str.StringList(args...), " "), strings.Join(str.StringList(newArgs...), " "))
  2404  	}
  2405  	os.Remove(ofile + ".new")
  2406  	return nil
  2407  }
  2408  
  2409  func (gcToolchain) Pkgpath(basedir string, p *load.Package) string {
  2410  	end := filepath.FromSlash(p.ImportPath + ".a")
  2411  	return filepath.Join(basedir, end)
  2412  }
  2413  
  2414  func (gcToolchain) pack(b *Builder, p *load.Package, objdir, afile string, ofiles []string) error {
  2415  	var absOfiles []string
  2416  	for _, f := range ofiles {
  2417  		absOfiles = append(absOfiles, mkAbs(objdir, f))
  2418  	}
  2419  	absAfile := mkAbs(objdir, afile)
  2420  
  2421  	// The archive file should have been created by the compiler.
  2422  	// Since it used to not work that way, verify.
  2423  	if !cfg.BuildN {
  2424  		if _, err := os.Stat(absAfile); err != nil {
  2425  			base.Fatalf("os.Stat of archive file failed: %v", err)
  2426  		}
  2427  	}
  2428  
  2429  	if cfg.BuildN || cfg.BuildX {
  2430  		cmdline := str.StringList(base.Tool("pack"), "r", absAfile, absOfiles)
  2431  		b.Showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
  2432  	}
  2433  	if cfg.BuildN {
  2434  		return nil
  2435  	}
  2436  	if err := packInternal(b, absAfile, absOfiles); err != nil {
  2437  		b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
  2438  		return errPrintedOutput
  2439  	}
  2440  	return nil
  2441  }
  2442  
  2443  func packInternal(b *Builder, afile string, ofiles []string) error {
  2444  	dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
  2445  	if err != nil {
  2446  		return err
  2447  	}
  2448  	defer dst.Close() // only for error returns or panics
  2449  	w := bufio.NewWriter(dst)
  2450  
  2451  	for _, ofile := range ofiles {
  2452  		src, err := os.Open(ofile)
  2453  		if err != nil {
  2454  			return err
  2455  		}
  2456  		fi, err := src.Stat()
  2457  		if err != nil {
  2458  			src.Close()
  2459  			return err
  2460  		}
  2461  		// Note: Not using %-16.16s format because we care
  2462  		// about bytes, not runes.
  2463  		name := fi.Name()
  2464  		if len(name) > 16 {
  2465  			name = name[:16]
  2466  		} else {
  2467  			name += strings.Repeat(" ", 16-len(name))
  2468  		}
  2469  		size := fi.Size()
  2470  		fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
  2471  			name, 0, 0, 0, 0644, size)
  2472  		n, err := io.Copy(w, src)
  2473  		src.Close()
  2474  		if err == nil && n < size {
  2475  			err = io.ErrUnexpectedEOF
  2476  		} else if err == nil && n > size {
  2477  			err = fmt.Errorf("file larger than size reported by stat")
  2478  		}
  2479  		if err != nil {
  2480  			return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
  2481  		}
  2482  		if size&1 != 0 {
  2483  			w.WriteByte(0)
  2484  		}
  2485  	}
  2486  
  2487  	if err := w.Flush(); err != nil {
  2488  		return err
  2489  	}
  2490  	return dst.Close()
  2491  }
  2492  
  2493  // setextld sets the appropriate linker flags for the specified compiler.
  2494  func setextld(ldflags []string, compiler []string) []string {
  2495  	for _, f := range ldflags {
  2496  		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
  2497  			// don't override -extld if supplied
  2498  			return ldflags
  2499  		}
  2500  	}
  2501  	ldflags = append(ldflags, "-extld="+compiler[0])
  2502  	if len(compiler) > 1 {
  2503  		extldflags := false
  2504  		add := strings.Join(compiler[1:], " ")
  2505  		for i, f := range ldflags {
  2506  			if f == "-extldflags" && i+1 < len(ldflags) {
  2507  				ldflags[i+1] = add + " " + ldflags[i+1]
  2508  				extldflags = true
  2509  				break
  2510  			} else if strings.HasPrefix(f, "-extldflags=") {
  2511  				ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
  2512  				extldflags = true
  2513  				break
  2514  			}
  2515  		}
  2516  		if !extldflags {
  2517  			ldflags = append(ldflags, "-extldflags="+add)
  2518  		}
  2519  	}
  2520  	return ldflags
  2521  }
  2522  
  2523  func (gcToolchain) ld(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string) error {
  2524  	importArgs := b.includeArgs("-L", allactions)
  2525  	cxx := len(root.Package.CXXFiles) > 0 || len(root.Package.SwigCXXFiles) > 0
  2526  	for _, a := range allactions {
  2527  		if a.Package != nil && (len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0) {
  2528  			cxx = true
  2529  		}
  2530  	}
  2531  	var ldflags []string
  2532  	if cfg.BuildContext.InstallSuffix != "" {
  2533  		ldflags = append(ldflags, "-installsuffix", cfg.BuildContext.InstallSuffix)
  2534  	}
  2535  	if root.Package.Internal.OmitDebug {
  2536  		ldflags = append(ldflags, "-s", "-w")
  2537  	}
  2538  	if cfg.BuildBuildmode == "plugin" {
  2539  		pluginpath := root.Package.ImportPath
  2540  		if pluginpath == "command-line-arguments" {
  2541  			pluginpath = "plugin/unnamed-" + root.Package.Internal.BuildID
  2542  		}
  2543  		ldflags = append(ldflags, "-pluginpath", pluginpath)
  2544  	}
  2545  
  2546  	// If the user has not specified the -extld option, then specify the
  2547  	// appropriate linker. In case of C++ code, use the compiler named
  2548  	// by the CXX environment variable or defaultCXX if CXX is not set.
  2549  	// Else, use the CC environment variable and defaultCC as fallback.
  2550  	var compiler []string
  2551  	if cxx {
  2552  		compiler = envList("CXX", cfg.DefaultCXX)
  2553  	} else {
  2554  		compiler = envList("CC", cfg.DefaultCC)
  2555  	}
  2556  	ldflags = setextld(ldflags, compiler)
  2557  	ldflags = append(ldflags, "-buildmode="+ldBuildmode)
  2558  	if root.Package.Internal.BuildID != "" {
  2559  		ldflags = append(ldflags, "-buildid="+root.Package.Internal.BuildID)
  2560  	}
  2561  	ldflags = append(ldflags, cfg.BuildLdflags...)
  2562  
  2563  	// On OS X when using external linking to build a shared library,
  2564  	// the argument passed here to -o ends up recorded in the final
  2565  	// shared library in the LC_ID_DYLIB load command.
  2566  	// To avoid putting the temporary output directory name there
  2567  	// (and making the resulting shared library useless),
  2568  	// run the link in the output directory so that -o can name
  2569  	// just the final path element.
  2570  	dir := "."
  2571  	if cfg.Goos == "darwin" && cfg.BuildBuildmode == "c-shared" {
  2572  		dir, out = filepath.Split(out)
  2573  	}
  2574  
  2575  	return b.run(dir, root.Package.ImportPath, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, importArgs, ldflags, mainpkg)
  2576  }
  2577  
  2578  func (gcToolchain) ldShared(b *Builder, toplevelactions []*Action, out string, allactions []*Action) error {
  2579  	importArgs := b.includeArgs("-L", allactions)
  2580  	ldflags := []string{"-installsuffix", cfg.BuildContext.InstallSuffix}
  2581  	ldflags = append(ldflags, "-buildmode=shared")
  2582  	ldflags = append(ldflags, cfg.BuildLdflags...)
  2583  	cxx := false
  2584  	for _, a := range allactions {
  2585  		if a.Package != nil && (len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0) {
  2586  			cxx = true
  2587  		}
  2588  	}
  2589  	// If the user has not specified the -extld option, then specify the
  2590  	// appropriate linker. In case of C++ code, use the compiler named
  2591  	// by the CXX environment variable or defaultCXX if CXX is not set.
  2592  	// Else, use the CC environment variable and defaultCC as fallback.
  2593  	var compiler []string
  2594  	if cxx {
  2595  		compiler = envList("CXX", cfg.DefaultCXX)
  2596  	} else {
  2597  		compiler = envList("CC", cfg.DefaultCC)
  2598  	}
  2599  	ldflags = setextld(ldflags, compiler)
  2600  	for _, d := range toplevelactions {
  2601  		if !strings.HasSuffix(d.Target, ".a") { // omit unsafe etc and actions for other shared libraries
  2602  			continue
  2603  		}
  2604  		ldflags = append(ldflags, d.Package.ImportPath+"="+d.Target)
  2605  	}
  2606  	return b.run(".", out, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, importArgs, ldflags)
  2607  }
  2608  
  2609  func (gcToolchain) cc(b *Builder, p *load.Package, objdir, ofile, cfile string) error {
  2610  	return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
  2611  }
  2612  
  2613  // The Gccgo toolchain.
  2614  type gccgoToolchain struct{}
  2615  
  2616  var GccgoName, GccgoBin string
  2617  var gccgoErr error
  2618  
  2619  func init() {
  2620  	GccgoName = os.Getenv("GCCGO")
  2621  	if GccgoName == "" {
  2622  		GccgoName = "gccgo"
  2623  	}
  2624  	GccgoBin, gccgoErr = exec.LookPath(GccgoName)
  2625  }
  2626  
  2627  func (gccgoToolchain) compiler() string {
  2628  	checkGccgoBin()
  2629  	return GccgoBin
  2630  }
  2631  
  2632  func (gccgoToolchain) linker() string {
  2633  	checkGccgoBin()
  2634  	return GccgoBin
  2635  }
  2636  
  2637  func checkGccgoBin() {
  2638  	if gccgoErr == nil {
  2639  		return
  2640  	}
  2641  	fmt.Fprintf(os.Stderr, "cmd/go: gccgo: %s\n", gccgoErr)
  2642  	os.Exit(2)
  2643  }
  2644  
  2645  func (tools gccgoToolchain) gc(b *Builder, p *load.Package, archive, objdir string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
  2646  	out := "_go_.o"
  2647  	ofile = objdir + out
  2648  	gcargs := []string{"-g"}
  2649  	gcargs = append(gcargs, b.gccArchArgs()...)
  2650  	if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  2651  		gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
  2652  	}
  2653  	if p.Internal.LocalPrefix != "" {
  2654  		gcargs = append(gcargs, "-fgo-relative-import-path="+p.Internal.LocalPrefix)
  2655  	}
  2656  
  2657  	// Handle vendor directories
  2658  	savedirs := []string{}
  2659  	for _, incdir := range importArgs {
  2660  		if incdir != "-I" {
  2661  			savedirs = append(savedirs, incdir)
  2662  		}
  2663  	}
  2664  
  2665  	for _, path := range p.Imports {
  2666  		// If this is a new vendor path, add it to the list of importArgs
  2667  		if i := strings.LastIndex(path, "/vendor"); i >= 0 {
  2668  			for _, dir := range savedirs {
  2669  				// Check if the vendor path is already included in dir
  2670  				if strings.HasSuffix(dir, path[:i+len("/vendor")]) {
  2671  					continue
  2672  				}
  2673  				// Make sure this vendor path is not already in the list for importArgs
  2674  				vendorPath := dir + "/" + path[:i+len("/vendor")]
  2675  				for _, imp := range importArgs {
  2676  					if imp == "-I" {
  2677  						continue
  2678  					}
  2679  					// This vendorPath is already in the list
  2680  					if imp == vendorPath {
  2681  						goto nextSuffixPath
  2682  					}
  2683  				}
  2684  				// New vendorPath not yet in the importArgs list, so add it
  2685  				importArgs = append(importArgs, "-I", vendorPath)
  2686  			nextSuffixPath:
  2687  			}
  2688  		} else if strings.HasPrefix(path, "vendor/") {
  2689  			for _, dir := range savedirs {
  2690  				// Make sure this vendor path is not already in the list for importArgs
  2691  				vendorPath := dir + "/" + path[len("/vendor"):]
  2692  				for _, imp := range importArgs {
  2693  					if imp == "-I" {
  2694  						continue
  2695  					}
  2696  					if imp == vendorPath {
  2697  						goto nextPrefixPath
  2698  					}
  2699  				}
  2700  				// This vendor path is needed and not already in the list, so add it
  2701  				importArgs = append(importArgs, "-I", vendorPath)
  2702  			nextPrefixPath:
  2703  			}
  2704  		}
  2705  	}
  2706  
  2707  	args := str.StringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
  2708  	for _, f := range gofiles {
  2709  		args = append(args, mkAbs(p.Dir, f))
  2710  	}
  2711  
  2712  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
  2713  	return ofile, output, err
  2714  }
  2715  
  2716  func (tools gccgoToolchain) asm(b *Builder, p *load.Package, objdir string, sfiles []string) ([]string, error) {
  2717  	var ofiles []string
  2718  	for _, sfile := range sfiles {
  2719  		ofile := objdir + sfile[:len(sfile)-len(".s")] + ".o"
  2720  		ofiles = append(ofiles, ofile)
  2721  		sfile = mkAbs(p.Dir, sfile)
  2722  		defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
  2723  		if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  2724  			defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath)
  2725  		}
  2726  		defs = tools.maybePIC(defs)
  2727  		defs = append(defs, b.gccArchArgs()...)
  2728  		err := b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-xassembler-with-cpp", "-I", objdir, "-c", "-o", ofile, defs, sfile)
  2729  		if err != nil {
  2730  			return nil, err
  2731  		}
  2732  	}
  2733  	return ofiles, nil
  2734  }
  2735  
  2736  func (gccgoToolchain) Pkgpath(basedir string, p *load.Package) string {
  2737  	end := filepath.FromSlash(p.ImportPath + ".a")
  2738  	afile := filepath.Join(basedir, end)
  2739  	// add "lib" to the final element
  2740  	return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
  2741  }
  2742  
  2743  func (gccgoToolchain) pack(b *Builder, p *load.Package, objdir, afile string, ofiles []string) error {
  2744  	var absOfiles []string
  2745  	for _, f := range ofiles {
  2746  		absOfiles = append(absOfiles, mkAbs(objdir, f))
  2747  	}
  2748  	return b.run(p.Dir, p.ImportPath, nil, "ar", "rc", mkAbs(objdir, afile), absOfiles)
  2749  }
  2750  
  2751  func (tools gccgoToolchain) link(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string, buildmode, desc string) error {
  2752  	// gccgo needs explicit linking with all package dependencies,
  2753  	// and all LDFLAGS from cgo dependencies.
  2754  	apackagePathsSeen := make(map[string]bool)
  2755  	afiles := []string{}
  2756  	shlibs := []string{}
  2757  	ldflags := b.gccArchArgs()
  2758  	cgoldflags := []string{}
  2759  	usesCgo := false
  2760  	cxx := false
  2761  	objc := false
  2762  	fortran := false
  2763  	if root.Package != nil {
  2764  		cxx = len(root.Package.CXXFiles) > 0 || len(root.Package.SwigCXXFiles) > 0
  2765  		objc = len(root.Package.MFiles) > 0
  2766  		fortran = len(root.Package.FFiles) > 0
  2767  	}
  2768  
  2769  	readCgoFlags := func(flagsFile string) error {
  2770  		flags, err := ioutil.ReadFile(flagsFile)
  2771  		if err != nil {
  2772  			return err
  2773  		}
  2774  		const ldflagsPrefix = "_CGO_LDFLAGS="
  2775  		for _, line := range strings.Split(string(flags), "\n") {
  2776  			if strings.HasPrefix(line, ldflagsPrefix) {
  2777  				newFlags := strings.Fields(line[len(ldflagsPrefix):])
  2778  				for _, flag := range newFlags {
  2779  					// Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
  2780  					// but they don't mean anything to the linker so filter
  2781  					// them out.
  2782  					if flag != "-g" && !strings.HasPrefix(flag, "-O") {
  2783  						cgoldflags = append(cgoldflags, flag)
  2784  					}
  2785  				}
  2786  			}
  2787  		}
  2788  		return nil
  2789  	}
  2790  
  2791  	readAndRemoveCgoFlags := func(archive string) (string, error) {
  2792  		newa, err := ioutil.TempFile(b.WorkDir, filepath.Base(archive))
  2793  		if err != nil {
  2794  			return "", err
  2795  		}
  2796  		olda, err := os.Open(archive)
  2797  		if err != nil {
  2798  			return "", err
  2799  		}
  2800  		_, err = io.Copy(newa, olda)
  2801  		if err != nil {
  2802  			return "", err
  2803  		}
  2804  		err = olda.Close()
  2805  		if err != nil {
  2806  			return "", err
  2807  		}
  2808  		err = newa.Close()
  2809  		if err != nil {
  2810  			return "", err
  2811  		}
  2812  
  2813  		newarchive := newa.Name()
  2814  		err = b.run(b.WorkDir, desc, nil, "ar", "x", newarchive, "_cgo_flags")
  2815  		if err != nil {
  2816  			return "", err
  2817  		}
  2818  		err = b.run(".", desc, nil, "ar", "d", newarchive, "_cgo_flags")
  2819  		if err != nil {
  2820  			return "", err
  2821  		}
  2822  		err = readCgoFlags(filepath.Join(b.WorkDir, "_cgo_flags"))
  2823  		if err != nil {
  2824  			return "", err
  2825  		}
  2826  		return newarchive, nil
  2827  	}
  2828  
  2829  	actionsSeen := make(map[*Action]bool)
  2830  	// Make a pre-order depth-first traversal of the action graph, taking note of
  2831  	// whether a shared library action has been seen on the way to an action (the
  2832  	// construction of the graph means that if any path to a node passes through
  2833  	// a shared library action, they all do).
  2834  	var walk func(a *Action, seenShlib bool)
  2835  	var err error
  2836  	walk = func(a *Action, seenShlib bool) {
  2837  		if actionsSeen[a] {
  2838  			return
  2839  		}
  2840  		actionsSeen[a] = true
  2841  		if a.Package != nil && !seenShlib {
  2842  			if a.Package.Standard {
  2843  				return
  2844  			}
  2845  			// We record the target of the first time we see a .a file
  2846  			// for a package to make sure that we prefer the 'install'
  2847  			// rather than the 'build' location (which may not exist any
  2848  			// more). We still need to traverse the dependencies of the
  2849  			// build action though so saying
  2850  			// if apackagePathsSeen[a.Package.ImportPath] { return }
  2851  			// doesn't work.
  2852  			if !apackagePathsSeen[a.Package.ImportPath] {
  2853  				apackagePathsSeen[a.Package.ImportPath] = true
  2854  				target := a.Target
  2855  				if len(a.Package.CgoFiles) > 0 || a.Package.UsesSwig() {
  2856  					target, err = readAndRemoveCgoFlags(target)
  2857  					if err != nil {
  2858  						return
  2859  					}
  2860  				}
  2861  				afiles = append(afiles, target)
  2862  			}
  2863  		}
  2864  		if strings.HasSuffix(a.Target, ".so") {
  2865  			shlibs = append(shlibs, a.Target)
  2866  			seenShlib = true
  2867  		}
  2868  		for _, a1 := range a.Deps {
  2869  			walk(a1, seenShlib)
  2870  			if err != nil {
  2871  				return
  2872  			}
  2873  		}
  2874  	}
  2875  	for _, a1 := range root.Deps {
  2876  		walk(a1, false)
  2877  		if err != nil {
  2878  			return err
  2879  		}
  2880  	}
  2881  
  2882  	for _, a := range allactions {
  2883  		// Gather CgoLDFLAGS, but not from standard packages.
  2884  		// The go tool can dig up runtime/cgo from GOROOT and
  2885  		// think that it should use its CgoLDFLAGS, but gccgo
  2886  		// doesn't use runtime/cgo.
  2887  		if a.Package == nil {
  2888  			continue
  2889  		}
  2890  		if !a.Package.Standard {
  2891  			cgoldflags = append(cgoldflags, a.Package.CgoLDFLAGS...)
  2892  		}
  2893  		if len(a.Package.CgoFiles) > 0 {
  2894  			usesCgo = true
  2895  		}
  2896  		if a.Package.UsesSwig() {
  2897  			usesCgo = true
  2898  		}
  2899  		if len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0 {
  2900  			cxx = true
  2901  		}
  2902  		if len(a.Package.MFiles) > 0 {
  2903  			objc = true
  2904  		}
  2905  		if len(a.Package.FFiles) > 0 {
  2906  			fortran = true
  2907  		}
  2908  	}
  2909  
  2910  	for i, o := range ofiles {
  2911  		if filepath.Base(o) == "_cgo_flags" {
  2912  			readCgoFlags(o)
  2913  			ofiles = append(ofiles[:i], ofiles[i+1:]...)
  2914  			break
  2915  		}
  2916  	}
  2917  
  2918  	ldflags = append(ldflags, "-Wl,--whole-archive")
  2919  	ldflags = append(ldflags, afiles...)
  2920  	ldflags = append(ldflags, "-Wl,--no-whole-archive")
  2921  
  2922  	ldflags = append(ldflags, cgoldflags...)
  2923  	ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
  2924  	if root.Package != nil {
  2925  		ldflags = append(ldflags, root.Package.CgoLDFLAGS...)
  2926  	}
  2927  
  2928  	ldflags = str.StringList("-Wl,-(", ldflags, "-Wl,-)")
  2929  
  2930  	for _, shlib := range shlibs {
  2931  		ldflags = append(
  2932  			ldflags,
  2933  			"-L"+filepath.Dir(shlib),
  2934  			"-Wl,-rpath="+filepath.Dir(shlib),
  2935  			"-l"+strings.TrimSuffix(
  2936  				strings.TrimPrefix(filepath.Base(shlib), "lib"),
  2937  				".so"))
  2938  	}
  2939  
  2940  	var realOut string
  2941  	switch buildmode {
  2942  	case "exe":
  2943  		if usesCgo && cfg.Goos == "linux" {
  2944  			ldflags = append(ldflags, "-Wl,-E")
  2945  		}
  2946  
  2947  	case "c-archive":
  2948  		// Link the Go files into a single .o, and also link
  2949  		// in -lgolibbegin.
  2950  		//
  2951  		// We need to use --whole-archive with -lgolibbegin
  2952  		// because it doesn't define any symbols that will
  2953  		// cause the contents to be pulled in; it's just
  2954  		// initialization code.
  2955  		//
  2956  		// The user remains responsible for linking against
  2957  		// -lgo -lpthread -lm in the final link. We can't use
  2958  		// -r to pick them up because we can't combine
  2959  		// split-stack and non-split-stack code in a single -r
  2960  		// link, and libgo picks up non-split-stack code from
  2961  		// libffi.
  2962  		ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
  2963  
  2964  		if nopie := b.gccNoPie(); nopie != "" {
  2965  			ldflags = append(ldflags, nopie)
  2966  		}
  2967  
  2968  		// We are creating an object file, so we don't want a build ID.
  2969  		ldflags = b.disableBuildID(ldflags)
  2970  
  2971  		realOut = out
  2972  		out = out + ".o"
  2973  
  2974  	case "c-shared":
  2975  		ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc", "-lc", "-lgcc")
  2976  	case "shared":
  2977  		ldflags = append(ldflags, "-zdefs", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc")
  2978  
  2979  	default:
  2980  		base.Fatalf("-buildmode=%s not supported for gccgo", buildmode)
  2981  	}
  2982  
  2983  	switch buildmode {
  2984  	case "exe", "c-shared":
  2985  		if cxx {
  2986  			ldflags = append(ldflags, "-lstdc++")
  2987  		}
  2988  		if objc {
  2989  			ldflags = append(ldflags, "-lobjc")
  2990  		}
  2991  		if fortran {
  2992  			fc := os.Getenv("FC")
  2993  			if fc == "" {
  2994  				fc = "gfortran"
  2995  			}
  2996  			// support gfortran out of the box and let others pass the correct link options
  2997  			// via CGO_LDFLAGS
  2998  			if strings.Contains(fc, "gfortran") {
  2999  				ldflags = append(ldflags, "-lgfortran")
  3000  			}
  3001  		}
  3002  	}
  3003  
  3004  	if err := b.run(".", desc, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil {
  3005  		return err
  3006  	}
  3007  
  3008  	switch buildmode {
  3009  	case "c-archive":
  3010  		if err := b.run(".", desc, nil, "ar", "rc", realOut, out); err != nil {
  3011  			return err
  3012  		}
  3013  	}
  3014  	return nil
  3015  }
  3016  
  3017  func (tools gccgoToolchain) ld(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string) error {
  3018  	return tools.link(b, root, out, allactions, mainpkg, ofiles, ldBuildmode, root.Package.ImportPath)
  3019  }
  3020  
  3021  func (tools gccgoToolchain) ldShared(b *Builder, toplevelactions []*Action, out string, allactions []*Action) error {
  3022  	fakeRoot := &Action{}
  3023  	fakeRoot.Deps = toplevelactions
  3024  	return tools.link(b, fakeRoot, out, allactions, "", nil, "shared", out)
  3025  }
  3026  
  3027  func (tools gccgoToolchain) cc(b *Builder, p *load.Package, objdir, ofile, cfile string) error {
  3028  	inc := filepath.Join(cfg.GOROOT, "pkg", "include")
  3029  	cfile = mkAbs(p.Dir, cfile)
  3030  	defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
  3031  	defs = append(defs, b.gccArchArgs()...)
  3032  	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  3033  		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
  3034  	}
  3035  	switch cfg.Goarch {
  3036  	case "386", "amd64":
  3037  		defs = append(defs, "-fsplit-stack")
  3038  	}
  3039  	defs = tools.maybePIC(defs)
  3040  	return b.run(p.Dir, p.ImportPath, nil, envList("CC", cfg.DefaultCC), "-Wall", "-g",
  3041  		"-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
  3042  }
  3043  
  3044  // maybePIC adds -fPIC to the list of arguments if needed.
  3045  func (tools gccgoToolchain) maybePIC(args []string) []string {
  3046  	switch cfg.BuildBuildmode {
  3047  	case "c-shared", "shared", "plugin":
  3048  		args = append(args, "-fPIC")
  3049  	}
  3050  	return args
  3051  }
  3052  
  3053  func gccgoPkgpath(p *load.Package) string {
  3054  	if p.Internal.Build.IsCommand() && !p.Internal.ForceLibrary {
  3055  		return ""
  3056  	}
  3057  	return p.ImportPath
  3058  }
  3059  
  3060  func gccgoCleanPkgpath(p *load.Package) string {
  3061  	clean := func(r rune) rune {
  3062  		switch {
  3063  		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
  3064  			'0' <= r && r <= '9':
  3065  			return r
  3066  		}
  3067  		return '_'
  3068  	}
  3069  	return strings.Map(clean, gccgoPkgpath(p))
  3070  }
  3071  
  3072  // gcc runs the gcc C compiler to create an object from a single C file.
  3073  func (b *Builder) gcc(p *load.Package, out string, flags []string, cfile string) error {
  3074  	return b.ccompile(p, out, flags, cfile, b.GccCmd(p.Dir))
  3075  }
  3076  
  3077  // gxx runs the g++ C++ compiler to create an object from a single C++ file.
  3078  func (b *Builder) gxx(p *load.Package, out string, flags []string, cxxfile string) error {
  3079  	return b.ccompile(p, out, flags, cxxfile, b.GxxCmd(p.Dir))
  3080  }
  3081  
  3082  // gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.
  3083  func (b *Builder) gfortran(p *load.Package, out string, flags []string, ffile string) error {
  3084  	return b.ccompile(p, out, flags, ffile, b.gfortranCmd(p.Dir))
  3085  }
  3086  
  3087  // ccompile runs the given C or C++ compiler and creates an object from a single source file.
  3088  func (b *Builder) ccompile(p *load.Package, outfile string, flags []string, file string, compiler []string) error {
  3089  	file = mkAbs(p.Dir, file)
  3090  	desc := p.ImportPath
  3091  	if !filepath.IsAbs(outfile) {
  3092  		outfile = filepath.Join(p.Dir, outfile)
  3093  	}
  3094  	output, err := b.runOut(filepath.Dir(file), desc, nil, compiler, flags, "-o", outfile, "-c", filepath.Base(file))
  3095  	if len(output) > 0 {
  3096  		// On FreeBSD 11, when we pass -g to clang 3.8 it
  3097  		// invokes its internal assembler with -dwarf-version=2.
  3098  		// When it sees .section .note.GNU-stack, it warns
  3099  		// "DWARF2 only supports one section per compilation unit".
  3100  		// This warning makes no sense, since the section is empty,
  3101  		// but it confuses people.
  3102  		// We work around the problem by detecting the warning
  3103  		// and dropping -g and trying again.
  3104  		if bytes.Contains(output, []byte("DWARF2 only supports one section per compilation unit")) {
  3105  			newFlags := make([]string, 0, len(flags))
  3106  			for _, f := range flags {
  3107  				if !strings.HasPrefix(f, "-g") {
  3108  					newFlags = append(newFlags, f)
  3109  				}
  3110  			}
  3111  			if len(newFlags) < len(flags) {
  3112  				return b.ccompile(p, outfile, newFlags, file, compiler)
  3113  			}
  3114  		}
  3115  
  3116  		b.showOutput(p.Dir, desc, b.processOutput(output))
  3117  		if err != nil {
  3118  			err = errPrintedOutput
  3119  		} else if os.Getenv("GO_BUILDER_NAME") != "" {
  3120  			return errors.New("C compiler warning promoted to error on Go builders")
  3121  		}
  3122  	}
  3123  	return err
  3124  }
  3125  
  3126  // gccld runs the gcc linker to create an executable from a set of object files.
  3127  func (b *Builder) gccld(p *load.Package, out string, flags []string, objs []string) error {
  3128  	var cmd []string
  3129  	if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
  3130  		cmd = b.GxxCmd(p.Dir)
  3131  	} else {
  3132  		cmd = b.GccCmd(p.Dir)
  3133  	}
  3134  	return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, objs, flags)
  3135  }
  3136  
  3137  // gccCmd returns a gcc command line prefix
  3138  // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
  3139  func (b *Builder) GccCmd(objdir string) []string {
  3140  	return b.ccompilerCmd("CC", cfg.DefaultCC, objdir)
  3141  }
  3142  
  3143  // gxxCmd returns a g++ command line prefix
  3144  // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
  3145  func (b *Builder) GxxCmd(objdir string) []string {
  3146  	return b.ccompilerCmd("CXX", cfg.DefaultCXX, objdir)
  3147  }
  3148  
  3149  // gfortranCmd returns a gfortran command line prefix.
  3150  func (b *Builder) gfortranCmd(objdir string) []string {
  3151  	return b.ccompilerCmd("FC", "gfortran", objdir)
  3152  }
  3153  
  3154  // ccompilerCmd returns a command line prefix for the given environment
  3155  // variable and using the default command when the variable is empty.
  3156  func (b *Builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
  3157  	// NOTE: env.go's mkEnv knows that the first three
  3158  	// strings returned are "gcc", "-I", objdir (and cuts them off).
  3159  
  3160  	compiler := envList(envvar, defcmd)
  3161  	a := []string{compiler[0], "-I", objdir}
  3162  	a = append(a, compiler[1:]...)
  3163  
  3164  	// Definitely want -fPIC but on Windows gcc complains
  3165  	// "-fPIC ignored for target (all code is position independent)"
  3166  	if cfg.Goos != "windows" {
  3167  		a = append(a, "-fPIC")
  3168  	}
  3169  	a = append(a, b.gccArchArgs()...)
  3170  	// gcc-4.5 and beyond require explicit "-pthread" flag
  3171  	// for multithreading with pthread library.
  3172  	if cfg.BuildContext.CgoEnabled {
  3173  		switch cfg.Goos {
  3174  		case "windows":
  3175  			a = append(a, "-mthreads")
  3176  		default:
  3177  			a = append(a, "-pthread")
  3178  		}
  3179  	}
  3180  
  3181  	// disable ASCII art in clang errors, if possible
  3182  	if b.gccSupportsFlag("-fno-caret-diagnostics") {
  3183  		a = append(a, "-fno-caret-diagnostics")
  3184  	}
  3185  	// clang is too smart about command-line arguments
  3186  	if b.gccSupportsFlag("-Qunused-arguments") {
  3187  		a = append(a, "-Qunused-arguments")
  3188  	}
  3189  
  3190  	// disable word wrapping in error messages
  3191  	a = append(a, "-fmessage-length=0")
  3192  
  3193  	// Tell gcc not to include the work directory in object files.
  3194  	if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
  3195  		a = append(a, "-fdebug-prefix-map="+b.WorkDir+"=/tmp/go-build")
  3196  	}
  3197  
  3198  	// Tell gcc not to include flags in object files, which defeats the
  3199  	// point of -fdebug-prefix-map above.
  3200  	if b.gccSupportsFlag("-gno-record-gcc-switches") {
  3201  		a = append(a, "-gno-record-gcc-switches")
  3202  	}
  3203  
  3204  	// On OS X, some of the compilers behave as if -fno-common
  3205  	// is always set, and the Mach-O linker in 6l/8l assumes this.
  3206  	// See https://golang.org/issue/3253.
  3207  	if cfg.Goos == "darwin" {
  3208  		a = append(a, "-fno-common")
  3209  	}
  3210  
  3211  	return a
  3212  }
  3213  
  3214  // gccNoPie returns the flag to use to request non-PIE. On systems
  3215  // with PIE (position independent executables) enabled by default,
  3216  // -no-pie must be passed when doing a partial link with -Wl,-r.
  3217  // But -no-pie is not supported by all compilers, and clang spells it -nopie.
  3218  func (b *Builder) gccNoPie() string {
  3219  	if b.gccSupportsFlag("-no-pie") {
  3220  		return "-no-pie"
  3221  	}
  3222  	if b.gccSupportsFlag("-nopie") {
  3223  		return "-nopie"
  3224  	}
  3225  	return ""
  3226  }
  3227  
  3228  // gccSupportsFlag checks to see if the compiler supports a flag.
  3229  func (b *Builder) gccSupportsFlag(flag string) bool {
  3230  	b.exec.Lock()
  3231  	defer b.exec.Unlock()
  3232  	if b, ok := b.flagCache[flag]; ok {
  3233  		return b
  3234  	}
  3235  	if b.flagCache == nil {
  3236  		if cfg.BuildN || cfg.BuildX {
  3237  			b.Showcmd(b.WorkDir, "touch trivial.c")
  3238  		}
  3239  		src := filepath.Join(b.WorkDir, "trivial.c")
  3240  		if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
  3241  			return false
  3242  		}
  3243  		b.flagCache = make(map[string]bool)
  3244  	}
  3245  	cmdArgs := append(envList("CC", cfg.DefaultCC), flag, "-c", "trivial.c")
  3246  	if cfg.BuildN || cfg.BuildX {
  3247  		b.Showcmd(b.WorkDir, "%s", joinUnambiguously(cmdArgs))
  3248  		if cfg.BuildN {
  3249  			return false
  3250  		}
  3251  	}
  3252  	cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
  3253  	cmd.Dir = b.WorkDir
  3254  	cmd.Env = base.MergeEnvLists([]string{"LC_ALL=C"}, base.EnvForDir(cmd.Dir, os.Environ()))
  3255  	out, err := cmd.CombinedOutput()
  3256  	supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
  3257  	b.flagCache[flag] = supported
  3258  	return supported
  3259  }
  3260  
  3261  // gccArchArgs returns arguments to pass to gcc based on the architecture.
  3262  func (b *Builder) gccArchArgs() []string {
  3263  	switch cfg.Goarch {
  3264  	case "386":
  3265  		return []string{"-m32"}
  3266  	case "amd64", "amd64p32":
  3267  		return []string{"-m64"}
  3268  	case "arm":
  3269  		return []string{"-marm"} // not thumb
  3270  	case "s390x":
  3271  		return []string{"-m64", "-march=z196"}
  3272  	case "mips64", "mips64le":
  3273  		return []string{"-mabi=64"}
  3274  	case "mips", "mipsle":
  3275  		return []string{"-mabi=32", "-march=mips32"}
  3276  	}
  3277  	return nil
  3278  }
  3279  
  3280  // envList returns the value of the given environment variable broken
  3281  // into fields, using the default value when the variable is empty.
  3282  func envList(key, def string) []string {
  3283  	v := os.Getenv(key)
  3284  	if v == "" {
  3285  		v = def
  3286  	}
  3287  	return strings.Fields(v)
  3288  }
  3289  
  3290  // CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
  3291  func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, ldflags []string) {
  3292  	defaults := "-g -O2"
  3293  
  3294  	cppflags = str.StringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
  3295  	cflags = str.StringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
  3296  	cxxflags = str.StringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
  3297  	fflags = str.StringList(envList("CGO_FFLAGS", defaults), p.CgoFFLAGS)
  3298  	ldflags = str.StringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
  3299  	return
  3300  }
  3301  
  3302  var cgoRe = regexp.MustCompile(`[/\\:]`)
  3303  
  3304  func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgofiles, objdirCgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) {
  3305  	p := a.Package
  3306  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS := b.CFlags(p)
  3307  	cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
  3308  	cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
  3309  	// If we are compiling Objective-C code, then we need to link against libobjc
  3310  	if len(mfiles) > 0 {
  3311  		cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
  3312  	}
  3313  
  3314  	// Likewise for Fortran, except there are many Fortran compilers.
  3315  	// Support gfortran out of the box and let others pass the correct link options
  3316  	// via CGO_LDFLAGS
  3317  	if len(ffiles) > 0 {
  3318  		fc := os.Getenv("FC")
  3319  		if fc == "" {
  3320  			fc = "gfortran"
  3321  		}
  3322  		if strings.Contains(fc, "gfortran") {
  3323  			cgoLDFLAGS = append(cgoLDFLAGS, "-lgfortran")
  3324  		}
  3325  	}
  3326  
  3327  	if cfg.BuildMSan {
  3328  		cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
  3329  		cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
  3330  	}
  3331  
  3332  	// Allows including _cgo_export.h from .[ch] files in the package.
  3333  	cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", objdir)
  3334  
  3335  	// If we have cgo files in the object directory, then copy any
  3336  	// other cgo files into the object directory, and pass a
  3337  	// -srcdir option to cgo.
  3338  	var srcdirarg []string
  3339  	if len(objdirCgofiles) > 0 {
  3340  		for _, fn := range cgofiles {
  3341  			if err := b.copyFile(a, objdir+filepath.Base(fn), filepath.Join(p.Dir, fn), 0666, false); err != nil {
  3342  				return nil, nil, err
  3343  			}
  3344  		}
  3345  		cgofiles = append(cgofiles, objdirCgofiles...)
  3346  		srcdirarg = []string{"-srcdir", objdir}
  3347  	}
  3348  
  3349  	// cgo
  3350  	// TODO: CGO_FLAGS?
  3351  	gofiles := []string{objdir + "_cgo_gotypes.go"}
  3352  	cfiles := []string{"_cgo_export.c"}
  3353  	for _, fn := range cgofiles {
  3354  		f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
  3355  		gofiles = append(gofiles, objdir+f+"cgo1.go")
  3356  		cfiles = append(cfiles, f+"cgo2.c")
  3357  	}
  3358  
  3359  	// TODO: make cgo not depend on $GOARCH?
  3360  
  3361  	cgoflags := []string{}
  3362  	if p.Standard && p.ImportPath == "runtime/cgo" {
  3363  		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
  3364  	}
  3365  	if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") {
  3366  		cgoflags = append(cgoflags, "-import_syscall=false")
  3367  	}
  3368  
  3369  	// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
  3370  	var cgoenv []string
  3371  	if len(cgoLDFLAGS) > 0 {
  3372  		flags := make([]string, len(cgoLDFLAGS))
  3373  		for i, f := range cgoLDFLAGS {
  3374  			flags[i] = strconv.Quote(f)
  3375  		}
  3376  		cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
  3377  	}
  3378  
  3379  	if cfg.BuildToolchainName == "gccgo" {
  3380  		switch cfg.Goarch {
  3381  		case "386", "amd64":
  3382  			cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
  3383  		}
  3384  		cgoflags = append(cgoflags, "-gccgo")
  3385  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  3386  			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
  3387  		}
  3388  	}
  3389  
  3390  	switch cfg.BuildBuildmode {
  3391  	case "c-archive", "c-shared":
  3392  		// Tell cgo that if there are any exported functions
  3393  		// it should generate a header file that C code can
  3394  		// #include.
  3395  		cgoflags = append(cgoflags, "-exportheader="+objdir+"_cgo_install.h")
  3396  	}
  3397  
  3398  	if err := b.run(p.Dir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, srcdirarg, "-objdir", objdir, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil {
  3399  		return nil, nil, err
  3400  	}
  3401  	outGo = append(outGo, gofiles...)
  3402  
  3403  	// gcc
  3404  	cflags := str.StringList(cgoCPPFLAGS, cgoCFLAGS)
  3405  	for _, cfile := range cfiles {
  3406  		ofile := objdir + cfile[:len(cfile)-1] + "o"
  3407  		if err := b.gcc(p, ofile, cflags, objdir+cfile); err != nil {
  3408  			return nil, nil, err
  3409  		}
  3410  		outObj = append(outObj, ofile)
  3411  	}
  3412  
  3413  	for _, file := range gccfiles {
  3414  		base := filepath.Base(file)
  3415  		ofile := objdir + cgoRe.ReplaceAllString(base[:len(base)-1], "_") + "o"
  3416  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  3417  			return nil, nil, err
  3418  		}
  3419  		outObj = append(outObj, ofile)
  3420  	}
  3421  
  3422  	cxxflags := str.StringList(cgoCPPFLAGS, cgoCXXFLAGS)
  3423  	for _, file := range gxxfiles {
  3424  		// Append .o to the file, just in case the pkg has file.c and file.cpp
  3425  		ofile := objdir + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
  3426  		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
  3427  			return nil, nil, err
  3428  		}
  3429  		outObj = append(outObj, ofile)
  3430  	}
  3431  
  3432  	for _, file := range mfiles {
  3433  		// Append .o to the file, just in case the pkg has file.c and file.m
  3434  		ofile := objdir + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
  3435  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  3436  			return nil, nil, err
  3437  		}
  3438  		outObj = append(outObj, ofile)
  3439  	}
  3440  
  3441  	fflags := str.StringList(cgoCPPFLAGS, cgoFFLAGS)
  3442  	for _, file := range ffiles {
  3443  		// Append .o to the file, just in case the pkg has file.c and file.f
  3444  		ofile := objdir + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
  3445  		if err := b.gfortran(p, ofile, fflags, file); err != nil {
  3446  			return nil, nil, err
  3447  		}
  3448  		outObj = append(outObj, ofile)
  3449  	}
  3450  
  3451  	switch cfg.BuildToolchainName {
  3452  	case "gc":
  3453  		importGo := objdir + "_cgo_import.go"
  3454  		if err := b.dynimport(p, objdir, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil {
  3455  			return nil, nil, err
  3456  		}
  3457  		outGo = append(outGo, importGo)
  3458  
  3459  		ofile := objdir + "_all.o"
  3460  		if err := b.collect(p, objdir, ofile, cgoLDFLAGS, outObj); err != nil {
  3461  			return nil, nil, err
  3462  		}
  3463  		outObj = []string{ofile}
  3464  
  3465  	case "gccgo":
  3466  		defunC := objdir + "_cgo_defun.c"
  3467  		defunObj := objdir + "_cgo_defun.o"
  3468  		if err := BuildToolchain.cc(b, p, objdir, defunObj, defunC); err != nil {
  3469  			return nil, nil, err
  3470  		}
  3471  		outObj = append(outObj, defunObj)
  3472  
  3473  	default:
  3474  		noCompiler()
  3475  	}
  3476  
  3477  	return outGo, outObj, nil
  3478  }
  3479  
  3480  // dynimport creates a Go source file named importGo containing
  3481  // //go:cgo_import_dynamic directives for each symbol or library
  3482  // dynamically imported by the object files outObj.
  3483  func (b *Builder) dynimport(p *load.Package, objdir, importGo, cgoExe string, cflags, cgoLDFLAGS, outObj []string) error {
  3484  	cfile := objdir + "_cgo_main.c"
  3485  	ofile := objdir + "_cgo_main.o"
  3486  	if err := b.gcc(p, ofile, cflags, cfile); err != nil {
  3487  		return err
  3488  	}
  3489  
  3490  	linkobj := str.StringList(ofile, outObj, p.SysoFiles)
  3491  	dynobj := objdir + "_cgo_.o"
  3492  
  3493  	// we need to use -pie for Linux/ARM to get accurate imported sym
  3494  	ldflags := cgoLDFLAGS
  3495  	if (cfg.Goarch == "arm" && cfg.Goos == "linux") || cfg.Goos == "android" {
  3496  		ldflags = append(ldflags, "-pie")
  3497  	}
  3498  	if err := b.gccld(p, dynobj, ldflags, linkobj); err != nil {
  3499  		return err
  3500  	}
  3501  
  3502  	// cgo -dynimport
  3503  	var cgoflags []string
  3504  	if p.Standard && p.ImportPath == "runtime/cgo" {
  3505  		cgoflags = []string{"-dynlinker"} // record path to dynamic linker
  3506  	}
  3507  	return b.run(p.Dir, p.ImportPath, nil, cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
  3508  }
  3509  
  3510  // collect partially links the object files outObj into a single
  3511  // relocatable object file named ofile.
  3512  func (b *Builder) collect(p *load.Package, objdir, ofile string, cgoLDFLAGS, outObj []string) error {
  3513  	// When linking relocatable objects, various flags need to be
  3514  	// filtered out as they are inapplicable and can cause some linkers
  3515  	// to fail.
  3516  	var ldflags []string
  3517  	for i := 0; i < len(cgoLDFLAGS); i++ {
  3518  		f := cgoLDFLAGS[i]
  3519  		switch {
  3520  		// skip "-lc" or "-l somelib"
  3521  		case strings.HasPrefix(f, "-l"):
  3522  			if f == "-l" {
  3523  				i++
  3524  			}
  3525  		// skip "-framework X" on Darwin
  3526  		case cfg.Goos == "darwin" && f == "-framework":
  3527  			i++
  3528  		// skip "*.{dylib,so,dll,o,a}"
  3529  		case strings.HasSuffix(f, ".dylib"),
  3530  			strings.HasSuffix(f, ".so"),
  3531  			strings.HasSuffix(f, ".dll"),
  3532  			strings.HasSuffix(f, ".o"),
  3533  			strings.HasSuffix(f, ".a"):
  3534  		// Remove any -fsanitize=foo flags.
  3535  		// Otherwise the compiler driver thinks that we are doing final link
  3536  		// and links sanitizer runtime into the object file. But we are not doing
  3537  		// the final link, we will link the resulting object file again. And
  3538  		// so the program ends up with two copies of sanitizer runtime.
  3539  		// See issue 8788 for details.
  3540  		case strings.HasPrefix(f, "-fsanitize="):
  3541  			continue
  3542  		// runpath flags not applicable unless building a shared
  3543  		// object or executable; see issue 12115 for details. This
  3544  		// is necessary as Go currently does not offer a way to
  3545  		// specify the set of LDFLAGS that only apply to shared
  3546  		// objects.
  3547  		case strings.HasPrefix(f, "-Wl,-rpath"):
  3548  			if f == "-Wl,-rpath" || f == "-Wl,-rpath-link" {
  3549  				// Skip following argument to -rpath* too.
  3550  				i++
  3551  			}
  3552  		default:
  3553  			ldflags = append(ldflags, f)
  3554  		}
  3555  	}
  3556  
  3557  	ldflags = append(ldflags, "-Wl,-r", "-nostdlib")
  3558  
  3559  	if flag := b.gccNoPie(); flag != "" {
  3560  		ldflags = append(ldflags, flag)
  3561  	}
  3562  
  3563  	// We are creating an object file, so we don't want a build ID.
  3564  	ldflags = b.disableBuildID(ldflags)
  3565  
  3566  	return b.gccld(p, ofile, ldflags, outObj)
  3567  }
  3568  
  3569  // Run SWIG on all SWIG input files.
  3570  // TODO: Don't build a shared library, once SWIG emits the necessary
  3571  // pragmas for external linking.
  3572  func (b *Builder) swig(p *load.Package, objdir string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
  3573  	if err := b.swigVersionCheck(); err != nil {
  3574  		return nil, nil, nil, err
  3575  	}
  3576  
  3577  	intgosize, err := b.swigIntSize(objdir)
  3578  	if err != nil {
  3579  		return nil, nil, nil, err
  3580  	}
  3581  
  3582  	for _, f := range p.SwigFiles {
  3583  		goFile, cFile, err := b.swigOne(p, f, objdir, pcCFLAGS, false, intgosize)
  3584  		if err != nil {
  3585  			return nil, nil, nil, err
  3586  		}
  3587  		if goFile != "" {
  3588  			outGo = append(outGo, goFile)
  3589  		}
  3590  		if cFile != "" {
  3591  			outC = append(outC, cFile)
  3592  		}
  3593  	}
  3594  	for _, f := range p.SwigCXXFiles {
  3595  		goFile, cxxFile, err := b.swigOne(p, f, objdir, pcCFLAGS, true, intgosize)
  3596  		if err != nil {
  3597  			return nil, nil, nil, err
  3598  		}
  3599  		if goFile != "" {
  3600  			outGo = append(outGo, goFile)
  3601  		}
  3602  		if cxxFile != "" {
  3603  			outCXX = append(outCXX, cxxFile)
  3604  		}
  3605  	}
  3606  	return outGo, outC, outCXX, nil
  3607  }
  3608  
  3609  // Make sure SWIG is new enough.
  3610  var (
  3611  	swigCheckOnce sync.Once
  3612  	swigCheck     error
  3613  )
  3614  
  3615  func (b *Builder) swigDoVersionCheck() error {
  3616  	out, err := b.runOut("", "", nil, "swig", "-version")
  3617  	if err != nil {
  3618  		return err
  3619  	}
  3620  	re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
  3621  	matches := re.FindSubmatch(out)
  3622  	if matches == nil {
  3623  		// Can't find version number; hope for the best.
  3624  		return nil
  3625  	}
  3626  
  3627  	major, err := strconv.Atoi(string(matches[1]))
  3628  	if err != nil {
  3629  		// Can't find version number; hope for the best.
  3630  		return nil
  3631  	}
  3632  	const errmsg = "must have SWIG version >= 3.0.6"
  3633  	if major < 3 {
  3634  		return errors.New(errmsg)
  3635  	}
  3636  	if major > 3 {
  3637  		// 4.0 or later
  3638  		return nil
  3639  	}
  3640  
  3641  	// We have SWIG version 3.x.
  3642  	if len(matches[2]) > 0 {
  3643  		minor, err := strconv.Atoi(string(matches[2][1:]))
  3644  		if err != nil {
  3645  			return nil
  3646  		}
  3647  		if minor > 0 {
  3648  			// 3.1 or later
  3649  			return nil
  3650  		}
  3651  	}
  3652  
  3653  	// We have SWIG version 3.0.x.
  3654  	if len(matches[3]) > 0 {
  3655  		patch, err := strconv.Atoi(string(matches[3][1:]))
  3656  		if err != nil {
  3657  			return nil
  3658  		}
  3659  		if patch < 6 {
  3660  			// Before 3.0.6.
  3661  			return errors.New(errmsg)
  3662  		}
  3663  	}
  3664  
  3665  	return nil
  3666  }
  3667  
  3668  func (b *Builder) swigVersionCheck() error {
  3669  	swigCheckOnce.Do(func() {
  3670  		swigCheck = b.swigDoVersionCheck()
  3671  	})
  3672  	return swigCheck
  3673  }
  3674  
  3675  // Find the value to pass for the -intgosize option to swig.
  3676  var (
  3677  	swigIntSizeOnce  sync.Once
  3678  	swigIntSize      string
  3679  	swigIntSizeError error
  3680  )
  3681  
  3682  // This code fails to build if sizeof(int) <= 32
  3683  const swigIntSizeCode = `
  3684  package main
  3685  const i int = 1 << 32
  3686  `
  3687  
  3688  // Determine the size of int on the target system for the -intgosize option
  3689  // of swig >= 2.0.9. Run only once.
  3690  func (b *Builder) swigDoIntSize(objdir string) (intsize string, err error) {
  3691  	if cfg.BuildN {
  3692  		return "$INTBITS", nil
  3693  	}
  3694  	src := filepath.Join(b.WorkDir, "swig_intsize.go")
  3695  	if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
  3696  		return
  3697  	}
  3698  	srcs := []string{src}
  3699  
  3700  	p := load.GoFilesPackage(srcs)
  3701  
  3702  	if _, _, e := BuildToolchain.gc(b, p, "", objdir, false, nil, srcs); e != nil {
  3703  		return "32", nil
  3704  	}
  3705  	return "64", nil
  3706  }
  3707  
  3708  // Determine the size of int on the target system for the -intgosize option
  3709  // of swig >= 2.0.9.
  3710  func (b *Builder) swigIntSize(objdir string) (intsize string, err error) {
  3711  	swigIntSizeOnce.Do(func() {
  3712  		swigIntSize, swigIntSizeError = b.swigDoIntSize(objdir)
  3713  	})
  3714  	return swigIntSize, swigIntSizeError
  3715  }
  3716  
  3717  // Run SWIG on one SWIG input file.
  3718  func (b *Builder) swigOne(p *load.Package, file, objdir string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
  3719  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _ := b.CFlags(p)
  3720  	var cflags []string
  3721  	if cxx {
  3722  		cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
  3723  	} else {
  3724  		cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
  3725  	}
  3726  
  3727  	n := 5 // length of ".swig"
  3728  	if cxx {
  3729  		n = 8 // length of ".swigcxx"
  3730  	}
  3731  	base := file[:len(file)-n]
  3732  	goFile := base + ".go"
  3733  	gccBase := base + "_wrap."
  3734  	gccExt := "c"
  3735  	if cxx {
  3736  		gccExt = "cxx"
  3737  	}
  3738  
  3739  	gccgo := cfg.BuildToolchainName == "gccgo"
  3740  
  3741  	// swig
  3742  	args := []string{
  3743  		"-go",
  3744  		"-cgo",
  3745  		"-intgosize", intgosize,
  3746  		"-module", base,
  3747  		"-o", objdir + gccBase + gccExt,
  3748  		"-outdir", objdir,
  3749  	}
  3750  
  3751  	for _, f := range cflags {
  3752  		if len(f) > 3 && f[:2] == "-I" {
  3753  			args = append(args, f)
  3754  		}
  3755  	}
  3756  
  3757  	if gccgo {
  3758  		args = append(args, "-gccgo")
  3759  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  3760  			args = append(args, "-go-pkgpath", pkgpath)
  3761  		}
  3762  	}
  3763  	if cxx {
  3764  		args = append(args, "-c++")
  3765  	}
  3766  
  3767  	out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file)
  3768  	if err != nil {
  3769  		if len(out) > 0 {
  3770  			if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
  3771  				return "", "", errors.New("must have SWIG version >= 3.0.6")
  3772  			}
  3773  			b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig error
  3774  			return "", "", errPrintedOutput
  3775  		}
  3776  		return "", "", err
  3777  	}
  3778  	if len(out) > 0 {
  3779  		b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig warning
  3780  	}
  3781  
  3782  	return goFile, objdir + gccBase + gccExt, nil
  3783  }
  3784  
  3785  // disableBuildID adjusts a linker command line to avoid creating a
  3786  // build ID when creating an object file rather than an executable or
  3787  // shared library. Some systems, such as Ubuntu, always add
  3788  // --build-id to every link, but we don't want a build ID when we are
  3789  // producing an object file. On some of those system a plain -r (not
  3790  // -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a
  3791  // plain -r. I don't know how to turn off --build-id when using clang
  3792  // other than passing a trailing --build-id=none. So that is what we
  3793  // do, but only on systems likely to support it, which is to say,
  3794  // systems that normally use gold or the GNU linker.
  3795  func (b *Builder) disableBuildID(ldflags []string) []string {
  3796  	switch cfg.Goos {
  3797  	case "android", "dragonfly", "linux", "netbsd":
  3798  		ldflags = append(ldflags, "-Wl,--build-id=none")
  3799  	}
  3800  	return ldflags
  3801  }
  3802  
  3803  // An actionQueue is a priority queue of actions.
  3804  type actionQueue []*Action
  3805  
  3806  // Implement heap.Interface
  3807  func (q *actionQueue) Len() int           { return len(*q) }
  3808  func (q *actionQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
  3809  func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
  3810  func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*Action)) }
  3811  func (q *actionQueue) Pop() interface{} {
  3812  	n := len(*q) - 1
  3813  	x := (*q)[n]
  3814  	*q = (*q)[:n]
  3815  	return x
  3816  }
  3817  
  3818  func (q *actionQueue) push(a *Action) {
  3819  	heap.Push(q, a)
  3820  }
  3821  
  3822  func (q *actionQueue) pop() *Action {
  3823  	return heap.Pop(q).(*Action)
  3824  }
  3825  
  3826  func InstrumentInit() {
  3827  	if !cfg.BuildRace && !cfg.BuildMSan {
  3828  		return
  3829  	}
  3830  	if cfg.BuildRace && cfg.BuildMSan {
  3831  		fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0])
  3832  		os.Exit(2)
  3833  	}
  3834  	if cfg.BuildMSan && (cfg.Goos != "linux" || cfg.Goarch != "amd64") {
  3835  		fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
  3836  		os.Exit(2)
  3837  	}
  3838  	if cfg.Goarch != "amd64" || cfg.Goos != "linux" && cfg.Goos != "freebsd" && cfg.Goos != "darwin" && cfg.Goos != "windows" {
  3839  		fmt.Fprintf(os.Stderr, "go %s: -race and -msan are only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
  3840  		os.Exit(2)
  3841  	}
  3842  	if !cfg.BuildContext.CgoEnabled {
  3843  		fmt.Fprintf(os.Stderr, "go %s: -race requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0])
  3844  		os.Exit(2)
  3845  	}
  3846  	if cfg.BuildRace {
  3847  		buildGcflags = append(buildGcflags, "-race")
  3848  		cfg.BuildLdflags = append(cfg.BuildLdflags, "-race")
  3849  	} else {
  3850  		buildGcflags = append(buildGcflags, "-msan")
  3851  		cfg.BuildLdflags = append(cfg.BuildLdflags, "-msan")
  3852  	}
  3853  	if cfg.BuildContext.InstallSuffix != "" {
  3854  		cfg.BuildContext.InstallSuffix += "_"
  3855  	}
  3856  
  3857  	if cfg.BuildRace {
  3858  		cfg.BuildContext.InstallSuffix += "race"
  3859  		cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "race")
  3860  	} else {
  3861  		cfg.BuildContext.InstallSuffix += "msan"
  3862  		cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "msan")
  3863  	}
  3864  }
  3865  
  3866  // ExecCmd is the command to use to run user binaries.
  3867  // Normally it is empty, meaning run the binaries directly.
  3868  // If cross-compiling and running on a remote system or
  3869  // simulator, it is typically go_GOOS_GOARCH_exec, with
  3870  // the target GOOS and GOARCH substituted.
  3871  // The -exec flag overrides these defaults.
  3872  var ExecCmd []string
  3873  
  3874  // FindExecCmd derives the value of ExecCmd to use.
  3875  // It returns that value and leaves ExecCmd set for direct use.
  3876  func FindExecCmd() []string {
  3877  	if ExecCmd != nil {
  3878  		return ExecCmd
  3879  	}
  3880  	ExecCmd = []string{} // avoid work the second time
  3881  	if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH {
  3882  		return ExecCmd
  3883  	}
  3884  	path, err := exec.LookPath(fmt.Sprintf("go_%s_%s_exec", cfg.Goos, cfg.Goarch))
  3885  	if err == nil {
  3886  		ExecCmd = []string{path}
  3887  	}
  3888  	return ExecCmd
  3889  }