github.com/robhaswell/grandperspective-scan@v0.1.0/test/go-go1.7.1/src/cmd/go/build.go (about)

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