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