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