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