github.com/ader1990/go@v0.0.0-20140630135419-8c24447fa791/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  	"errors"
    12  	"flag"
    13  	"fmt"
    14  	"go/build"
    15  	"io"
    16  	"io/ioutil"
    17  	"log"
    18  	"os"
    19  	"os/exec"
    20  	"path"
    21  	"path/filepath"
    22  	"regexp"
    23  	"runtime"
    24  	"strconv"
    25  	"strings"
    26  	"sync"
    27  	"time"
    28  )
    29  
    30  var cmdBuild = &Command{
    31  	UsageLine: "build [-o output] [-i] [build flags] [packages]",
    32  	Short:     "compile packages and dependencies",
    33  	Long: `
    34  Build compiles the packages named by the import paths,
    35  along with their dependencies, but it does not install the results.
    36  
    37  If the arguments are a list of .go files, build treats them as a list
    38  of source files specifying a single package.
    39  
    40  When the command line specifies a single main package,
    41  build writes the resulting executable to output.
    42  Otherwise build compiles the packages but discards the results,
    43  serving only as a check that the packages can be built.
    44  
    45  The -o flag specifies the output file name. If not specified, the
    46  output file name depends on the arguments and derives from the name
    47  of the package, such as p.a for package p, unless p is 'main'. If
    48  the package is main and file names are provided, the file name
    49  derives from the first file name mentioned, such as f1 for 'go build
    50  f1.go f2.go'; with no files provided ('go build'), the output file
    51  name is the base name of the containing directory.
    52  
    53  The -i flag installs the packages that are dependencies of the target.
    54  
    55  The build flags are shared by the build, clean, get, install, list, run,
    56  and test commands:
    57  
    58  	-a
    59  		force rebuilding of packages that are already up-to-date.
    60  	-n
    61  		print the commands but do not run them.
    62  	-p n
    63  		the number of builds that can be run in parallel.
    64  		The default is the number of CPUs available.
    65  	-race
    66  		enable data race detection.
    67  		Supported only on linux/amd64, darwin/amd64 and windows/amd64.
    68  	-v
    69  		print the names of packages as they are compiled.
    70  	-work
    71  		print the name of the temporary work directory and
    72  		do not delete it when exiting.
    73  	-x
    74  		print the commands.
    75  
    76  	-ccflags 'arg list'
    77  		arguments to pass on each 5c, 6c, or 8c compiler invocation.
    78  	-compiler name
    79  		name of compiler to use, as in runtime.Compiler (gccgo or gc).
    80  	-gccgoflags 'arg list'
    81  		arguments to pass on each gccgo compiler/linker invocation.
    82  	-gcflags 'arg list'
    83  		arguments to pass on each 5g, 6g, or 8g compiler invocation.
    84  	-installsuffix suffix
    85  		a suffix to use in the name of the package installation directory,
    86  		in order to keep output separate from default builds.
    87  		If using the -race flag, the install suffix is automatically set to race
    88  		or, if set explicitly, has _race appended to it.
    89  	-ldflags 'flag list'
    90  		arguments to pass on each 5l, 6l, or 8l linker invocation.
    91  	-tags 'tag list'
    92  		a list of build tags to consider satisfied during the build.
    93  		For more information about build tags, see the description of
    94  		build constraints in the documentation for the go/build package.
    95  
    96  The list flags accept a space-separated list of strings. To embed spaces
    97  in an element in the list, surround it with either single or double quotes.
    98  
    99  For more about specifying packages, see 'go help packages'.
   100  For more about where packages and binaries are installed,
   101  run 'go help gopath'.  For more about calling between Go and C/C++,
   102  run 'go help c'.
   103  
   104  See also: go install, go get, go clean.
   105  	`,
   106  }
   107  
   108  func init() {
   109  	// break init cycle
   110  	cmdBuild.Run = runBuild
   111  	cmdInstall.Run = runInstall
   112  
   113  	cmdBuild.Flag.BoolVar(&buildI, "i", false, "")
   114  
   115  	addBuildFlags(cmdBuild)
   116  	addBuildFlags(cmdInstall)
   117  }
   118  
   119  // Flags set by multiple commands.
   120  var buildA bool               // -a flag
   121  var buildN bool               // -n flag
   122  var buildP = runtime.NumCPU() // -p flag
   123  var buildV bool               // -v flag
   124  var buildX bool               // -x flag
   125  var buildI bool               // -i flag
   126  var buildO = cmdBuild.Flag.String("o", "", "output file")
   127  var buildWork bool           // -work flag
   128  var buildGcflags []string    // -gcflags flag
   129  var buildCcflags []string    // -ccflags flag
   130  var buildLdflags []string    // -ldflags flag
   131  var buildGccgoflags []string // -gccgoflags flag
   132  var buildRace bool           // -race flag
   133  
   134  var buildContext = build.Default
   135  var buildToolchain toolchain = noToolchain{}
   136  
   137  // buildCompiler implements flag.Var.
   138  // It implements Set by updating both
   139  // buildToolchain and buildContext.Compiler.
   140  type buildCompiler struct{}
   141  
   142  func (c buildCompiler) Set(value string) error {
   143  	switch value {
   144  	case "gc":
   145  		buildToolchain = gcToolchain{}
   146  	case "gccgo":
   147  		buildToolchain = gccgoToolchain{}
   148  	default:
   149  		return fmt.Errorf("unknown compiler %q", value)
   150  	}
   151  	buildContext.Compiler = value
   152  	return nil
   153  }
   154  
   155  func (c buildCompiler) String() string {
   156  	return buildContext.Compiler
   157  }
   158  
   159  func init() {
   160  	switch build.Default.Compiler {
   161  	case "gc":
   162  		buildToolchain = gcToolchain{}
   163  	case "gccgo":
   164  		buildToolchain = gccgoToolchain{}
   165  	}
   166  }
   167  
   168  // addBuildFlags adds the flags common to the build, clean, get,
   169  // install, list, run, and test commands.
   170  func addBuildFlags(cmd *Command) {
   171  	// NOTE: If you add flags here, also add them to testflag.go.
   172  	cmd.Flag.BoolVar(&buildA, "a", false, "")
   173  	cmd.Flag.BoolVar(&buildN, "n", false, "")
   174  	cmd.Flag.IntVar(&buildP, "p", buildP, "")
   175  	cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
   176  	cmd.Flag.BoolVar(&buildV, "v", false, "")
   177  	cmd.Flag.BoolVar(&buildX, "x", false, "")
   178  	cmd.Flag.BoolVar(&buildWork, "work", false, "")
   179  	cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
   180  	cmd.Flag.Var((*stringsFlag)(&buildCcflags), "ccflags", "")
   181  	cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
   182  	cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
   183  	cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
   184  	cmd.Flag.Var(buildCompiler{}, "compiler", "")
   185  	cmd.Flag.BoolVar(&buildRace, "race", false, "")
   186  }
   187  
   188  func addBuildFlagsNX(cmd *Command) {
   189  	cmd.Flag.BoolVar(&buildN, "n", false, "")
   190  	cmd.Flag.BoolVar(&buildX, "x", false, "")
   191  }
   192  
   193  func isSpaceByte(c byte) bool {
   194  	return c == ' ' || c == '\t' || c == '\n' || c == '\r'
   195  }
   196  
   197  // fileExtSplit expects a filename and returns the name
   198  // and ext (without the dot). If the file has no
   199  // extension, ext will be empty.
   200  func fileExtSplit(file string) (name, ext string) {
   201  	dotExt := filepath.Ext(file)
   202  	name = file[:len(file)-len(dotExt)]
   203  	if dotExt != "" {
   204  		ext = dotExt[1:]
   205  	}
   206  	return
   207  }
   208  
   209  type stringsFlag []string
   210  
   211  func (v *stringsFlag) Set(s string) error {
   212  	var err error
   213  	*v, err = splitQuotedFields(s)
   214  	if *v == nil {
   215  		*v = []string{}
   216  	}
   217  	return err
   218  }
   219  
   220  func splitQuotedFields(s string) ([]string, error) {
   221  	// Split fields allowing '' or "" around elements.
   222  	// Quotes further inside the string do not count.
   223  	var f []string
   224  	for len(s) > 0 {
   225  		for len(s) > 0 && isSpaceByte(s[0]) {
   226  			s = s[1:]
   227  		}
   228  		if len(s) == 0 {
   229  			break
   230  		}
   231  		// Accepted quoted string. No unescaping inside.
   232  		if s[0] == '"' || s[0] == '\'' {
   233  			quote := s[0]
   234  			s = s[1:]
   235  			i := 0
   236  			for i < len(s) && s[i] != quote {
   237  				i++
   238  			}
   239  			if i >= len(s) {
   240  				return nil, fmt.Errorf("unterminated %c string", quote)
   241  			}
   242  			f = append(f, s[:i])
   243  			s = s[i+1:]
   244  			continue
   245  		}
   246  		i := 0
   247  		for i < len(s) && !isSpaceByte(s[i]) {
   248  			i++
   249  		}
   250  		f = append(f, s[:i])
   251  		s = s[i:]
   252  	}
   253  	return f, nil
   254  }
   255  
   256  func (v *stringsFlag) String() string {
   257  	return "<stringsFlag>"
   258  }
   259  
   260  func runBuild(cmd *Command, args []string) {
   261  	raceInit()
   262  	var b builder
   263  	b.init()
   264  
   265  	pkgs := packagesForBuild(args)
   266  
   267  	if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" {
   268  		_, *buildO = path.Split(pkgs[0].ImportPath)
   269  		*buildO += exeSuffix
   270  	}
   271  
   272  	// sanity check some often mis-used options
   273  	switch buildContext.Compiler {
   274  	case "gccgo":
   275  		if len(buildGcflags) != 0 {
   276  			fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
   277  		}
   278  		if len(buildLdflags) != 0 {
   279  			fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
   280  		}
   281  	case "gc":
   282  		if len(buildGccgoflags) != 0 {
   283  			fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
   284  		}
   285  	}
   286  
   287  	if *buildO != "" {
   288  		if len(pkgs) > 1 {
   289  			fatalf("go build: cannot use -o with multiple packages")
   290  		}
   291  		p := pkgs[0]
   292  		p.target = "" // must build - not up to date
   293  		a := b.action(modeInstall, modeBuild, p)
   294  		a.target = *buildO
   295  		b.do(a)
   296  		return
   297  	}
   298  
   299  	a := &action{}
   300  	depMode := modeBuild
   301  	if buildI {
   302  		depMode = modeInstall
   303  	}
   304  	for _, p := range packages(args) {
   305  		a.deps = append(a.deps, b.action(modeBuild, depMode, p))
   306  	}
   307  	b.do(a)
   308  }
   309  
   310  var cmdInstall = &Command{
   311  	UsageLine: "install [build flags] [packages]",
   312  	Short:     "compile and install packages and dependencies",
   313  	Long: `
   314  Install compiles and installs the packages named by the import paths,
   315  along with their dependencies.
   316  
   317  For more about the build flags, see 'go help build'.
   318  For more about specifying packages, see 'go help packages'.
   319  
   320  See also: go build, go get, go clean.
   321  	`,
   322  }
   323  
   324  func runInstall(cmd *Command, args []string) {
   325  	raceInit()
   326  	pkgs := packagesForBuild(args)
   327  
   328  	for _, p := range pkgs {
   329  		if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
   330  			if p.cmdline {
   331  				errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
   332  			} else if p.ConflictDir != "" {
   333  				errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
   334  			} else {
   335  				errorf("go install: no install location for directory %s outside GOPATH", p.Dir)
   336  			}
   337  		}
   338  	}
   339  	exitIfErrors()
   340  
   341  	var b builder
   342  	b.init()
   343  	a := &action{}
   344  	for _, p := range pkgs {
   345  		a.deps = append(a.deps, b.action(modeInstall, modeInstall, p))
   346  	}
   347  	b.do(a)
   348  }
   349  
   350  // Global build parameters (used during package load)
   351  var (
   352  	goarch    string
   353  	goos      string
   354  	archChar  string
   355  	exeSuffix string
   356  )
   357  
   358  func init() {
   359  	goarch = buildContext.GOARCH
   360  	goos = buildContext.GOOS
   361  	if goos == "windows" {
   362  		exeSuffix = ".exe"
   363  	}
   364  	var err error
   365  	archChar, err = build.ArchChar(goarch)
   366  	if err != nil {
   367  		if _, isgc := buildToolchain.(gcToolchain); isgc {
   368  			fatalf("%s", err)
   369  		}
   370  		// archChar is only required for gcToolchain, if we're using
   371  		// another toolchain leave it blank.
   372  		archChar = ""
   373  	}
   374  }
   375  
   376  // A builder holds global state about a build.
   377  // It does not hold per-package state, because we
   378  // build packages in parallel, and the builder is shared.
   379  type builder struct {
   380  	work        string               // the temporary work directory (ends in filepath.Separator)
   381  	actionCache map[cacheKey]*action // a cache of already-constructed actions
   382  	mkdirCache  map[string]bool      // a cache of created directories
   383  	print       func(args ...interface{}) (int, error)
   384  
   385  	output    sync.Mutex
   386  	scriptDir string // current directory in printed script
   387  
   388  	exec      sync.Mutex
   389  	readySema chan bool
   390  	ready     actionQueue
   391  }
   392  
   393  // An action represents a single action in the action graph.
   394  type action struct {
   395  	p          *Package      // the package this action works on
   396  	deps       []*action     // actions that must happen before this one
   397  	triggers   []*action     // inverse of deps
   398  	cgo        *action       // action for cgo binary if needed
   399  	args       []string      // additional args for runProgram
   400  	testOutput *bytes.Buffer // test output buffer
   401  
   402  	f          func(*builder, *action) error // the action itself (nil = no-op)
   403  	ignoreFail bool                          // whether to run f even if dependencies fail
   404  
   405  	// Generated files, directories.
   406  	link   bool   // target is executable, not just package
   407  	pkgdir string // the -I or -L argument to use when importing this package
   408  	objdir string // directory for intermediate objects
   409  	objpkg string // the intermediate package .a file created during the action
   410  	target string // goal of the action: the created package or executable
   411  
   412  	// Execution state.
   413  	pending  int  // number of deps yet to complete
   414  	priority int  // relative execution priority
   415  	failed   bool // whether the action failed
   416  }
   417  
   418  // cacheKey is the key for the action cache.
   419  type cacheKey struct {
   420  	mode buildMode
   421  	p    *Package
   422  }
   423  
   424  // buildMode specifies the build mode:
   425  // are we just building things or also installing the results?
   426  type buildMode int
   427  
   428  const (
   429  	modeBuild buildMode = iota
   430  	modeInstall
   431  )
   432  
   433  var (
   434  	goroot       = filepath.Clean(runtime.GOROOT())
   435  	gobin        = os.Getenv("GOBIN")
   436  	gorootBin    = filepath.Join(goroot, "bin")
   437  	gorootSrcPkg = filepath.Join(goroot, "src/pkg")
   438  	gorootPkg    = filepath.Join(goroot, "pkg")
   439  	gorootSrc    = filepath.Join(goroot, "src")
   440  )
   441  
   442  func (b *builder) init() {
   443  	var err error
   444  	b.print = func(a ...interface{}) (int, error) {
   445  		return fmt.Fprint(os.Stderr, a...)
   446  	}
   447  	b.actionCache = make(map[cacheKey]*action)
   448  	b.mkdirCache = make(map[string]bool)
   449  
   450  	if buildN {
   451  		b.work = "$WORK"
   452  	} else {
   453  		b.work, err = ioutil.TempDir("", "go-build")
   454  		if err != nil {
   455  			fatalf("%s", err)
   456  		}
   457  		if buildX || buildWork {
   458  			fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
   459  		}
   460  		if !buildWork {
   461  			workdir := b.work
   462  			atexit(func() { os.RemoveAll(workdir) })
   463  		}
   464  	}
   465  }
   466  
   467  // goFilesPackage creates a package for building a collection of Go files
   468  // (typically named on the command line).  The target is named p.a for
   469  // package p or named after the first Go file for package main.
   470  func goFilesPackage(gofiles []string) *Package {
   471  	// TODO: Remove this restriction.
   472  	for _, f := range gofiles {
   473  		if !strings.HasSuffix(f, ".go") {
   474  			fatalf("named files must be .go files")
   475  		}
   476  	}
   477  
   478  	var stk importStack
   479  	ctxt := buildContext
   480  	ctxt.UseAllFiles = true
   481  
   482  	// Synthesize fake "directory" that only shows the named files,
   483  	// to make it look like this is a standard package or
   484  	// command directory.  So that local imports resolve
   485  	// consistently, the files must all be in the same directory.
   486  	var dirent []os.FileInfo
   487  	var dir string
   488  	for _, file := range gofiles {
   489  		fi, err := os.Stat(file)
   490  		if err != nil {
   491  			fatalf("%s", err)
   492  		}
   493  		if fi.IsDir() {
   494  			fatalf("%s is a directory, should be a Go file", file)
   495  		}
   496  		dir1, _ := filepath.Split(file)
   497  		if dir == "" {
   498  			dir = dir1
   499  		} else if dir != dir1 {
   500  			fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
   501  		}
   502  		dirent = append(dirent, fi)
   503  	}
   504  	ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
   505  
   506  	if !filepath.IsAbs(dir) {
   507  		dir = filepath.Join(cwd, dir)
   508  	}
   509  
   510  	bp, err := ctxt.ImportDir(dir, 0)
   511  	pkg := new(Package)
   512  	pkg.local = true
   513  	pkg.cmdline = true
   514  	pkg.load(&stk, bp, err)
   515  	pkg.localPrefix = dirToImportPath(dir)
   516  	pkg.ImportPath = "command-line-arguments"
   517  	pkg.target = ""
   518  
   519  	if pkg.Name == "main" {
   520  		_, elem := filepath.Split(gofiles[0])
   521  		exe := elem[:len(elem)-len(".go")] + exeSuffix
   522  		if *buildO == "" {
   523  			*buildO = exe
   524  		}
   525  		if gobin != "" {
   526  			pkg.target = filepath.Join(gobin, exe)
   527  		}
   528  	} else {
   529  		if *buildO == "" {
   530  			*buildO = pkg.Name + ".a"
   531  		}
   532  	}
   533  	pkg.Target = pkg.target
   534  	pkg.Stale = true
   535  
   536  	computeStale(pkg)
   537  	return pkg
   538  }
   539  
   540  // action returns the action for applying the given operation (mode) to the package.
   541  // depMode is the action to use when building dependencies.
   542  func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action {
   543  	key := cacheKey{mode, p}
   544  	a := b.actionCache[key]
   545  	if a != nil {
   546  		return a
   547  	}
   548  
   549  	a = &action{p: p, pkgdir: p.build.PkgRoot}
   550  	if p.pkgdir != "" { // overrides p.t
   551  		a.pkgdir = p.pkgdir
   552  	}
   553  
   554  	b.actionCache[key] = a
   555  
   556  	for _, p1 := range p.imports {
   557  		a.deps = append(a.deps, b.action(depMode, depMode, p1))
   558  	}
   559  
   560  	// If we are not doing a cross-build, then record the binary we'll
   561  	// generate for cgo as a dependency of the build of any package
   562  	// using cgo, to make sure we do not overwrite the binary while
   563  	// a package is using it.  If this is a cross-build, then the cgo we
   564  	// are writing is not the cgo we need to use.
   565  	if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace {
   566  		if len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo" {
   567  			var stk importStack
   568  			p1 := loadPackage("cmd/cgo", &stk)
   569  			if p1.Error != nil {
   570  				fatalf("load cmd/cgo: %v", p1.Error)
   571  			}
   572  			a.cgo = b.action(depMode, depMode, p1)
   573  			a.deps = append(a.deps, a.cgo)
   574  		}
   575  	}
   576  
   577  	if p.Standard {
   578  		switch p.ImportPath {
   579  		case "builtin", "unsafe":
   580  			// Fake packages - nothing to build.
   581  			return a
   582  		}
   583  		// gccgo standard library is "fake" too.
   584  		if _, ok := buildToolchain.(gccgoToolchain); ok {
   585  			// the target name is needed for cgo.
   586  			a.target = p.target
   587  			return a
   588  		}
   589  	}
   590  
   591  	if !p.Stale && p.target != "" {
   592  		// p.Stale==false implies that p.target is up-to-date.
   593  		// Record target name for use by actions depending on this one.
   594  		a.target = p.target
   595  		return a
   596  	}
   597  
   598  	if p.local && p.target == "" {
   599  		// Imported via local path.  No permanent target.
   600  		mode = modeBuild
   601  	}
   602  	work := p.pkgdir
   603  	if work == "" {
   604  		work = b.work
   605  	}
   606  	a.objdir = filepath.Join(work, a.p.ImportPath, "_obj") + string(filepath.Separator)
   607  	a.objpkg = buildToolchain.pkgpath(work, a.p)
   608  	a.link = p.Name == "main"
   609  
   610  	switch mode {
   611  	case modeInstall:
   612  		a.f = (*builder).install
   613  		a.deps = []*action{b.action(modeBuild, depMode, p)}
   614  		a.target = a.p.target
   615  	case modeBuild:
   616  		a.f = (*builder).build
   617  		a.target = a.objpkg
   618  		if a.link {
   619  			// An executable file. (This is the name of a temporary file.)
   620  			// Because we run the temporary file in 'go run' and 'go test',
   621  			// the name will show up in ps listings. If the caller has specified
   622  			// a name, use that instead of a.out. The binary is generated
   623  			// in an otherwise empty subdirectory named exe to avoid
   624  			// naming conflicts.  The only possible conflict is if we were
   625  			// to create a top-level package named exe.
   626  			name := "a.out"
   627  			if p.exeName != "" {
   628  				name = p.exeName
   629  			}
   630  			a.target = a.objdir + filepath.Join("exe", name) + exeSuffix
   631  		}
   632  	}
   633  
   634  	return a
   635  }
   636  
   637  // actionList returns the list of actions in the dag rooted at root
   638  // as visited in a depth-first post-order traversal.
   639  func actionList(root *action) []*action {
   640  	seen := map[*action]bool{}
   641  	all := []*action{}
   642  	var walk func(*action)
   643  	walk = func(a *action) {
   644  		if seen[a] {
   645  			return
   646  		}
   647  		seen[a] = true
   648  		for _, a1 := range a.deps {
   649  			walk(a1)
   650  		}
   651  		all = append(all, a)
   652  	}
   653  	walk(root)
   654  	return all
   655  }
   656  
   657  // do runs the action graph rooted at root.
   658  func (b *builder) do(root *action) {
   659  	// Build list of all actions, assigning depth-first post-order priority.
   660  	// The original implementation here was a true queue
   661  	// (using a channel) but it had the effect of getting
   662  	// distracted by low-level leaf actions to the detriment
   663  	// of completing higher-level actions.  The order of
   664  	// work does not matter much to overall execution time,
   665  	// but when running "go test std" it is nice to see each test
   666  	// results as soon as possible.  The priorities assigned
   667  	// ensure that, all else being equal, the execution prefers
   668  	// to do what it would have done first in a simple depth-first
   669  	// dependency order traversal.
   670  	all := actionList(root)
   671  	for i, a := range all {
   672  		a.priority = i
   673  	}
   674  
   675  	b.readySema = make(chan bool, len(all))
   676  
   677  	// Initialize per-action execution state.
   678  	for _, a := range all {
   679  		for _, a1 := range a.deps {
   680  			a1.triggers = append(a1.triggers, a)
   681  		}
   682  		a.pending = len(a.deps)
   683  		if a.pending == 0 {
   684  			b.ready.push(a)
   685  			b.readySema <- true
   686  		}
   687  	}
   688  
   689  	// Handle runs a single action and takes care of triggering
   690  	// any actions that are runnable as a result.
   691  	handle := func(a *action) {
   692  		var err error
   693  		if a.f != nil && (!a.failed || a.ignoreFail) {
   694  			err = a.f(b, a)
   695  		}
   696  
   697  		// The actions run in parallel but all the updates to the
   698  		// shared work state are serialized through b.exec.
   699  		b.exec.Lock()
   700  		defer b.exec.Unlock()
   701  
   702  		if err != nil {
   703  			if err == errPrintedOutput {
   704  				setExitStatus(2)
   705  			} else {
   706  				errorf("%s", err)
   707  			}
   708  			a.failed = true
   709  		}
   710  
   711  		for _, a0 := range a.triggers {
   712  			if a.failed {
   713  				a0.failed = true
   714  			}
   715  			if a0.pending--; a0.pending == 0 {
   716  				b.ready.push(a0)
   717  				b.readySema <- true
   718  			}
   719  		}
   720  
   721  		if a == root {
   722  			close(b.readySema)
   723  		}
   724  	}
   725  
   726  	var wg sync.WaitGroup
   727  
   728  	// Kick off goroutines according to parallelism.
   729  	// If we are using the -n flag (just printing commands)
   730  	// drop the parallelism to 1, both to make the output
   731  	// deterministic and because there is no real work anyway.
   732  	par := buildP
   733  	if buildN {
   734  		par = 1
   735  	}
   736  	for i := 0; i < par; i++ {
   737  		wg.Add(1)
   738  		go func() {
   739  			defer wg.Done()
   740  			for {
   741  				select {
   742  				case _, ok := <-b.readySema:
   743  					if !ok {
   744  						return
   745  					}
   746  					// Receiving a value from b.readySema entitles
   747  					// us to take from the ready queue.
   748  					b.exec.Lock()
   749  					a := b.ready.pop()
   750  					b.exec.Unlock()
   751  					handle(a)
   752  				case <-interrupted:
   753  					setExitStatus(1)
   754  					return
   755  				}
   756  			}
   757  		}()
   758  	}
   759  
   760  	wg.Wait()
   761  }
   762  
   763  // hasString reports whether s appears in the list of strings.
   764  func hasString(strings []string, s string) bool {
   765  	for _, t := range strings {
   766  		if s == t {
   767  			return true
   768  		}
   769  	}
   770  	return false
   771  }
   772  
   773  // build is the action for building a single package or command.
   774  func (b *builder) build(a *action) (err error) {
   775  	// Return an error if the package has CXX files but it's not using
   776  	// cgo nor SWIG, since the CXX files can only be processed by cgo
   777  	// and SWIG (it's possible to have packages with C files without
   778  	// using cgo, they will get compiled with the plan9 C compiler and
   779  	// linked with the rest of the package).
   780  	if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
   781  		return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
   782  			a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
   783  	}
   784  	// Same as above for Objective-C files
   785  	if len(a.p.MFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
   786  		return fmt.Errorf("can't build package %s because it contains Objective-C files (%s) but it's not using cgo nor SWIG",
   787  			a.p.ImportPath, strings.Join(a.p.MFiles, ","))
   788  	}
   789  	defer func() {
   790  		if err != nil && err != errPrintedOutput {
   791  			err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
   792  		}
   793  	}()
   794  	if buildN {
   795  		// In -n mode, print a banner between packages.
   796  		// The banner is five lines so that when changes to
   797  		// different sections of the bootstrap script have to
   798  		// be merged, the banners give patch something
   799  		// to use to find its context.
   800  		fmt.Printf("\n#\n# %s\n#\n\n", a.p.ImportPath)
   801  	}
   802  
   803  	if buildV {
   804  		fmt.Fprintf(os.Stderr, "%s\n", a.p.ImportPath)
   805  	}
   806  
   807  	if a.p.Standard && a.p.ImportPath == "runtime" && buildContext.Compiler == "gc" &&
   808  		!hasString(a.p.HFiles, "zasm_"+buildContext.GOOS+"_"+buildContext.GOARCH+".h") {
   809  		return fmt.Errorf("%s/%s must be bootstrapped using make%v", buildContext.GOOS, buildContext.GOARCH, defaultSuffix())
   810  	}
   811  
   812  	// Make build directory.
   813  	obj := a.objdir
   814  	if err := b.mkdir(obj); err != nil {
   815  		return err
   816  	}
   817  
   818  	// make target directory
   819  	dir, _ := filepath.Split(a.target)
   820  	if dir != "" {
   821  		if err := b.mkdir(dir); err != nil {
   822  			return err
   823  		}
   824  	}
   825  
   826  	var gofiles, cfiles, sfiles, objects, cgoObjects []string
   827  
   828  	gofiles = append(gofiles, a.p.GoFiles...)
   829  	cfiles = append(cfiles, a.p.CFiles...)
   830  	sfiles = append(sfiles, a.p.SFiles...)
   831  
   832  	// Run cgo.
   833  	if a.p.usesCgo() {
   834  		// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
   835  		// There is one exception: runtime/cgo's job is to bridge the
   836  		// cgo and non-cgo worlds, so it necessarily has files in both.
   837  		// In that case gcc only gets the gcc_* files.
   838  		var gccfiles []string
   839  		if a.p.Standard && a.p.ImportPath == "runtime/cgo" {
   840  			filter := func(files, nongcc, gcc []string) ([]string, []string) {
   841  				for _, f := range files {
   842  					if strings.HasPrefix(f, "gcc_") {
   843  						gcc = append(gcc, f)
   844  					} else {
   845  						nongcc = append(nongcc, f)
   846  					}
   847  				}
   848  				return nongcc, gcc
   849  			}
   850  			cfiles, gccfiles = filter(cfiles, cfiles[:0], gccfiles)
   851  			sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
   852  		} else {
   853  			gccfiles = append(cfiles, sfiles...)
   854  			cfiles = nil
   855  			sfiles = nil
   856  		}
   857  
   858  		cgoExe := tool("cgo")
   859  		if a.cgo != nil && a.cgo.target != "" {
   860  			cgoExe = a.cgo.target
   861  		}
   862  		outGo, outObj, err := b.cgo(a.p, cgoExe, obj, gccfiles, a.p.CXXFiles, a.p.MFiles)
   863  		if err != nil {
   864  			return err
   865  		}
   866  		cgoObjects = append(cgoObjects, outObj...)
   867  		gofiles = append(gofiles, outGo...)
   868  	}
   869  
   870  	// Run SWIG.
   871  	if a.p.usesSwig() {
   872  		// In a package using SWIG, any .c or .s files are
   873  		// compiled with gcc.
   874  		gccfiles := append(cfiles, sfiles...)
   875  		cfiles = nil
   876  		sfiles = nil
   877  		outGo, outObj, err := b.swig(a.p, obj, gccfiles, a.p.CXXFiles, a.p.MFiles)
   878  		if err != nil {
   879  			return err
   880  		}
   881  		cgoObjects = append(cgoObjects, outObj...)
   882  		gofiles = append(gofiles, outGo...)
   883  	}
   884  
   885  	if len(gofiles) == 0 {
   886  		return &build.NoGoError{a.p.Dir}
   887  	}
   888  
   889  	// If we're doing coverage, preprocess the .go files and put them in the work directory
   890  	if a.p.coverMode != "" {
   891  		for i, file := range gofiles {
   892  			var sourceFile string
   893  			var coverFile string
   894  			var key string
   895  			if strings.HasSuffix(file, ".cgo1.go") {
   896  				// cgo files have absolute paths
   897  				base := filepath.Base(file)
   898  				sourceFile = file
   899  				coverFile = filepath.Join(obj, base)
   900  				key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
   901  			} else {
   902  				sourceFile = filepath.Join(a.p.Dir, file)
   903  				coverFile = filepath.Join(obj, file)
   904  				key = file
   905  			}
   906  			cover := a.p.coverVars[key]
   907  			if cover == nil || isTestFile(file) {
   908  				// Not covering this file.
   909  				continue
   910  			}
   911  			if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
   912  				return err
   913  			}
   914  			gofiles[i] = coverFile
   915  		}
   916  	}
   917  
   918  	// Prepare Go import path list.
   919  	inc := b.includeArgs("-I", a.deps)
   920  
   921  	// Compile Go.
   922  	ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, inc, gofiles)
   923  	if len(out) > 0 {
   924  		b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
   925  		if err != nil {
   926  			return errPrintedOutput
   927  		}
   928  	}
   929  	if err != nil {
   930  		return err
   931  	}
   932  	if ofile != a.objpkg {
   933  		objects = append(objects, ofile)
   934  	}
   935  
   936  	// Copy .h files named for goos or goarch or goos_goarch
   937  	// to names using GOOS and GOARCH.
   938  	// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
   939  	_goos_goarch := "_" + goos + "_" + goarch
   940  	_goos := "_" + goos
   941  	_goarch := "_" + goarch
   942  	for _, file := range a.p.HFiles {
   943  		name, ext := fileExtSplit(file)
   944  		switch {
   945  		case strings.HasSuffix(name, _goos_goarch):
   946  			targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
   947  			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
   948  				return err
   949  			}
   950  		case strings.HasSuffix(name, _goarch):
   951  			targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
   952  			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
   953  				return err
   954  			}
   955  		case strings.HasSuffix(name, _goos):
   956  			targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
   957  			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
   958  				return err
   959  			}
   960  		}
   961  	}
   962  
   963  	objExt := archChar
   964  	if _, ok := buildToolchain.(gccgoToolchain); ok {
   965  		objExt = "o"
   966  	}
   967  
   968  	for _, file := range cfiles {
   969  		out := file[:len(file)-len(".c")] + "." + objExt
   970  		if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
   971  			return err
   972  		}
   973  		objects = append(objects, out)
   974  	}
   975  
   976  	// Assemble .s files.
   977  	for _, file := range sfiles {
   978  		out := file[:len(file)-len(".s")] + "." + objExt
   979  		if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
   980  			return err
   981  		}
   982  		objects = append(objects, out)
   983  	}
   984  
   985  	// NOTE(rsc): On Windows, it is critically important that the
   986  	// gcc-compiled objects (cgoObjects) be listed after the ordinary
   987  	// objects in the archive.  I do not know why this is.
   988  	// http://golang.org/issue/2601
   989  	objects = append(objects, cgoObjects...)
   990  
   991  	// Add system object files.
   992  	for _, syso := range a.p.SysoFiles {
   993  		objects = append(objects, filepath.Join(a.p.Dir, syso))
   994  	}
   995  
   996  	// Pack into archive in obj directory.
   997  	// If the Go compiler wrote an archive, we only need to add the
   998  	// object files for non-Go sources to the archive.
   999  	// If the Go compiler wrote an archive and the package is entirely
  1000  	// Go sources, there is no pack to execute at all.
  1001  	if len(objects) > 0 {
  1002  		if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
  1003  			return err
  1004  		}
  1005  	}
  1006  
  1007  	// Link if needed.
  1008  	if a.link {
  1009  		// The compiler only cares about direct imports, but the
  1010  		// linker needs the whole dependency tree.
  1011  		all := actionList(a)
  1012  		all = all[:len(all)-1] // drop a
  1013  		if err := buildToolchain.ld(b, a.p, a.target, all, a.objpkg, objects); err != nil {
  1014  			return err
  1015  		}
  1016  	}
  1017  
  1018  	return nil
  1019  }
  1020  
  1021  // install is the action for installing a single package or executable.
  1022  func (b *builder) install(a *action) (err error) {
  1023  	defer func() {
  1024  		if err != nil && err != errPrintedOutput {
  1025  			err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err)
  1026  		}
  1027  	}()
  1028  	a1 := a.deps[0]
  1029  	perm := os.FileMode(0644)
  1030  	if a1.link {
  1031  		perm = 0755
  1032  	}
  1033  
  1034  	// make target directory
  1035  	dir, _ := filepath.Split(a.target)
  1036  	if dir != "" {
  1037  		if err := b.mkdir(dir); err != nil {
  1038  			return err
  1039  		}
  1040  	}
  1041  
  1042  	// remove object dir to keep the amount of
  1043  	// garbage down in a large build.  On an operating system
  1044  	// with aggressive buffering, cleaning incrementally like
  1045  	// this keeps the intermediate objects from hitting the disk.
  1046  	if !buildWork {
  1047  		defer os.RemoveAll(a1.objdir)
  1048  		defer os.Remove(a1.target)
  1049  	}
  1050  
  1051  	return b.moveOrCopyFile(a, a.target, a1.target, perm)
  1052  }
  1053  
  1054  // includeArgs returns the -I or -L directory list for access
  1055  // to the results of the list of actions.
  1056  func (b *builder) includeArgs(flag string, all []*action) []string {
  1057  	inc := []string{}
  1058  	incMap := map[string]bool{
  1059  		b.work:    true, // handled later
  1060  		gorootPkg: true,
  1061  		"":        true, // ignore empty strings
  1062  	}
  1063  
  1064  	// Look in the temporary space for results of test-specific actions.
  1065  	// This is the $WORK/my/package/_test directory for the
  1066  	// package being built, so there are few of these.
  1067  	for _, a1 := range all {
  1068  		if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
  1069  			incMap[dir] = true
  1070  			inc = append(inc, flag, dir)
  1071  		}
  1072  	}
  1073  
  1074  	// Also look in $WORK for any non-test packages that have
  1075  	// been built but not installed.
  1076  	inc = append(inc, flag, b.work)
  1077  
  1078  	// Finally, look in the installed package directories for each action.
  1079  	for _, a1 := range all {
  1080  		if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
  1081  			incMap[dir] = true
  1082  			if _, ok := buildToolchain.(gccgoToolchain); ok {
  1083  				dir = filepath.Join(dir, "gccgo_"+goos+"_"+goarch)
  1084  			} else {
  1085  				dir = filepath.Join(dir, goos+"_"+goarch)
  1086  				if buildContext.InstallSuffix != "" {
  1087  					dir += "_" + buildContext.InstallSuffix
  1088  				}
  1089  			}
  1090  			inc = append(inc, flag, dir)
  1091  		}
  1092  	}
  1093  
  1094  	return inc
  1095  }
  1096  
  1097  // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
  1098  func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode) error {
  1099  	if buildN {
  1100  		b.showcmd("", "mv %s %s", src, dst)
  1101  		return nil
  1102  	}
  1103  
  1104  	// If we can update the mode and rename to the dst, do it.
  1105  	// Otherwise fall back to standard copy.
  1106  	if err := os.Chmod(src, perm); err == nil {
  1107  		if err := os.Rename(src, dst); err == nil {
  1108  			if buildX {
  1109  				b.showcmd("", "mv %s %s", src, dst)
  1110  			}
  1111  			return nil
  1112  		}
  1113  	}
  1114  
  1115  	return b.copyFile(a, dst, src, perm)
  1116  }
  1117  
  1118  // copyFile is like 'cp src dst'.
  1119  func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode) error {
  1120  	if buildN || buildX {
  1121  		b.showcmd("", "cp %s %s", src, dst)
  1122  		if buildN {
  1123  			return nil
  1124  		}
  1125  	}
  1126  
  1127  	sf, err := os.Open(src)
  1128  	if err != nil {
  1129  		return err
  1130  	}
  1131  	defer sf.Close()
  1132  
  1133  	// Be careful about removing/overwriting dst.
  1134  	// Do not remove/overwrite if dst exists and is a directory
  1135  	// or a non-object file.
  1136  	if fi, err := os.Stat(dst); err == nil {
  1137  		if fi.IsDir() {
  1138  			return fmt.Errorf("build output %q already exists and is a directory", dst)
  1139  		}
  1140  		if !isObject(dst) {
  1141  			return fmt.Errorf("build output %q already exists and is not an object file", dst)
  1142  		}
  1143  	}
  1144  
  1145  	// On Windows, remove lingering ~ file from last attempt.
  1146  	if toolIsWindows {
  1147  		if _, err := os.Stat(dst + "~"); err == nil {
  1148  			os.Remove(dst + "~")
  1149  		}
  1150  	}
  1151  
  1152  	os.Remove(dst)
  1153  	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1154  	if err != nil && toolIsWindows {
  1155  		// Windows does not allow deletion of a binary file
  1156  		// while it is executing.  Try to move it out of the way.
  1157  		// If the move fails, which is likely, we'll try again the
  1158  		// next time we do an install of this binary.
  1159  		if err := os.Rename(dst, dst+"~"); err == nil {
  1160  			os.Remove(dst + "~")
  1161  		}
  1162  		df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1163  	}
  1164  	if err != nil {
  1165  		return err
  1166  	}
  1167  
  1168  	_, err = io.Copy(df, sf)
  1169  	df.Close()
  1170  	if err != nil {
  1171  		os.Remove(dst)
  1172  		return fmt.Errorf("copying %s to %s: %v", src, dst, err)
  1173  	}
  1174  	return nil
  1175  }
  1176  
  1177  // cover runs, in effect,
  1178  //	go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
  1179  func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
  1180  	return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
  1181  		tool("cover"),
  1182  		"-mode", a.p.coverMode,
  1183  		"-var", varName,
  1184  		"-o", dst,
  1185  		src)
  1186  }
  1187  
  1188  var objectMagic = [][]byte{
  1189  	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'},        // Package archive
  1190  	{'\x7F', 'E', 'L', 'F'},                          // ELF
  1191  	{0xFE, 0xED, 0xFA, 0xCE},                         // Mach-O big-endian 32-bit
  1192  	{0xFE, 0xED, 0xFA, 0xCF},                         // Mach-O big-endian 64-bit
  1193  	{0xCE, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 32-bit
  1194  	{0xCF, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 64-bit
  1195  	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x04, 0x00}, // PE (Windows) as generated by 6l/8l
  1196  	{0x00, 0x00, 0x01, 0xEB},                         // Plan 9 i386
  1197  	{0x00, 0x00, 0x8a, 0x97},                         // Plan 9 amd64
  1198  }
  1199  
  1200  func isObject(s string) bool {
  1201  	f, err := os.Open(s)
  1202  	if err != nil {
  1203  		return false
  1204  	}
  1205  	defer f.Close()
  1206  	buf := make([]byte, 64)
  1207  	io.ReadFull(f, buf)
  1208  	for _, magic := range objectMagic {
  1209  		if bytes.HasPrefix(buf, magic) {
  1210  			return true
  1211  		}
  1212  	}
  1213  	return false
  1214  }
  1215  
  1216  // fmtcmd formats a command in the manner of fmt.Sprintf but also:
  1217  //
  1218  //	If dir is non-empty and the script is not in dir right now,
  1219  //	fmtcmd inserts "cd dir\n" before the command.
  1220  //
  1221  //	fmtcmd replaces the value of b.work with $WORK.
  1222  //	fmtcmd replaces the value of goroot with $GOROOT.
  1223  //	fmtcmd replaces the value of b.gobin with $GOBIN.
  1224  //
  1225  //	fmtcmd replaces the name of the current directory with dot (.)
  1226  //	but only when it is at the beginning of a space-separated token.
  1227  //
  1228  func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
  1229  	cmd := fmt.Sprintf(format, args...)
  1230  	if dir != "" && dir != "/" {
  1231  		cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
  1232  		if b.scriptDir != dir {
  1233  			b.scriptDir = dir
  1234  			cmd = "cd " + dir + "\n" + cmd
  1235  		}
  1236  	}
  1237  	if b.work != "" {
  1238  		cmd = strings.Replace(cmd, b.work, "$WORK", -1)
  1239  	}
  1240  	return cmd
  1241  }
  1242  
  1243  // showcmd prints the given command to standard output
  1244  // for the implementation of -n or -x.
  1245  func (b *builder) showcmd(dir string, format string, args ...interface{}) {
  1246  	b.output.Lock()
  1247  	defer b.output.Unlock()
  1248  	b.print(b.fmtcmd(dir, format, args...) + "\n")
  1249  }
  1250  
  1251  // showOutput prints "# desc" followed by the given output.
  1252  // The output is expected to contain references to 'dir', usually
  1253  // the source directory for the package that has failed to build.
  1254  // showOutput rewrites mentions of dir with a relative path to dir
  1255  // when the relative path is shorter.  This is usually more pleasant.
  1256  // For example, if fmt doesn't compile and we are in src/pkg/html,
  1257  // the output is
  1258  //
  1259  //	$ go build
  1260  //	# fmt
  1261  //	../fmt/print.go:1090: undefined: asdf
  1262  //	$
  1263  //
  1264  // instead of
  1265  //
  1266  //	$ go build
  1267  //	# fmt
  1268  //	/usr/gopher/go/src/pkg/fmt/print.go:1090: undefined: asdf
  1269  //	$
  1270  //
  1271  // showOutput also replaces references to the work directory with $WORK.
  1272  //
  1273  func (b *builder) showOutput(dir, desc, out string) {
  1274  	prefix := "# " + desc
  1275  	suffix := "\n" + out
  1276  	if reldir := shortPath(dir); reldir != dir {
  1277  		suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
  1278  		suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
  1279  	}
  1280  	suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
  1281  
  1282  	b.output.Lock()
  1283  	defer b.output.Unlock()
  1284  	b.print(prefix, suffix)
  1285  }
  1286  
  1287  // shortPath returns an absolute or relative name for path, whatever is shorter.
  1288  func shortPath(path string) string {
  1289  	if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
  1290  		return rel
  1291  	}
  1292  	return path
  1293  }
  1294  
  1295  // relPaths returns a copy of paths with absolute paths
  1296  // made relative to the current directory if they would be shorter.
  1297  func relPaths(paths []string) []string {
  1298  	var out []string
  1299  	pwd, _ := os.Getwd()
  1300  	for _, p := range paths {
  1301  		rel, err := filepath.Rel(pwd, p)
  1302  		if err == nil && len(rel) < len(p) {
  1303  			p = rel
  1304  		}
  1305  		out = append(out, p)
  1306  	}
  1307  	return out
  1308  }
  1309  
  1310  // errPrintedOutput is a special error indicating that a command failed
  1311  // but that it generated output as well, and that output has already
  1312  // been printed, so there's no point showing 'exit status 1' or whatever
  1313  // the wait status was.  The main executor, builder.do, knows not to
  1314  // print this error.
  1315  var errPrintedOutput = errors.New("already printed output - no need to show error")
  1316  
  1317  var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
  1318  var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
  1319  
  1320  // run runs the command given by cmdline in the directory dir.
  1321  // If the command fails, run prints information about the failure
  1322  // and returns a non-nil error.
  1323  func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
  1324  	out, err := b.runOut(dir, desc, env, cmdargs...)
  1325  	if len(out) > 0 {
  1326  		if desc == "" {
  1327  			desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
  1328  		}
  1329  		b.showOutput(dir, desc, b.processOutput(out))
  1330  		if err != nil {
  1331  			err = errPrintedOutput
  1332  		}
  1333  	}
  1334  	return err
  1335  }
  1336  
  1337  // processOutput prepares the output of runOut to be output to the console.
  1338  func (b *builder) processOutput(out []byte) string {
  1339  	if out[len(out)-1] != '\n' {
  1340  		out = append(out, '\n')
  1341  	}
  1342  	messages := string(out)
  1343  	// Fix up output referring to cgo-generated code to be more readable.
  1344  	// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
  1345  	// Replace *[100]_Ctype_foo with *[100]C.foo.
  1346  	// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
  1347  	if !buildX && cgoLine.MatchString(messages) {
  1348  		messages = cgoLine.ReplaceAllString(messages, "")
  1349  		messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
  1350  	}
  1351  	return messages
  1352  }
  1353  
  1354  // runOut runs the command given by cmdline in the directory dir.
  1355  // It returns the command output and any errors that occurred.
  1356  func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
  1357  	cmdline := stringList(cmdargs...)
  1358  	if buildN || buildX {
  1359  		var envcmdline string
  1360  		for i := range env {
  1361  			envcmdline += env[i]
  1362  			envcmdline += " "
  1363  		}
  1364  		envcmdline += joinUnambiguously(cmdline)
  1365  		b.showcmd(dir, "%s", envcmdline)
  1366  		if buildN {
  1367  			return nil, nil
  1368  		}
  1369  	}
  1370  
  1371  	nbusy := 0
  1372  	for {
  1373  		var buf bytes.Buffer
  1374  		cmd := exec.Command(cmdline[0], cmdline[1:]...)
  1375  		cmd.Stdout = &buf
  1376  		cmd.Stderr = &buf
  1377  		cmd.Dir = dir
  1378  		cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir))
  1379  		err := cmd.Run()
  1380  
  1381  		// cmd.Run will fail on Unix if some other process has the binary
  1382  		// we want to run open for writing.  This can happen here because
  1383  		// we build and install the cgo command and then run it.
  1384  		// If another command was kicked off while we were writing the
  1385  		// cgo binary, the child process for that command may be holding
  1386  		// a reference to the fd, keeping us from running exec.
  1387  		//
  1388  		// But, you might reasonably wonder, how can this happen?
  1389  		// The cgo fd, like all our fds, is close-on-exec, so that we need
  1390  		// not worry about other processes inheriting the fd accidentally.
  1391  		// The answer is that running a command is fork and exec.
  1392  		// A child forked while the cgo fd is open inherits that fd.
  1393  		// Until the child has called exec, it holds the fd open and the
  1394  		// kernel will not let us run cgo.  Even if the child were to close
  1395  		// the fd explicitly, it would still be open from the time of the fork
  1396  		// until the time of the explicit close, and the race would remain.
  1397  		//
  1398  		// On Unix systems, this results in ETXTBSY, which formats
  1399  		// as "text file busy".  Rather than hard-code specific error cases,
  1400  		// we just look for that string.  If this happens, sleep a little
  1401  		// and try again.  We let this happen three times, with increasing
  1402  		// sleep lengths: 100+200+400 ms = 0.7 seconds.
  1403  		//
  1404  		// An alternate solution might be to split the cmd.Run into
  1405  		// separate cmd.Start and cmd.Wait, and then use an RWLock
  1406  		// to make sure that copyFile only executes when no cmd.Start
  1407  		// call is in progress.  However, cmd.Start (really syscall.forkExec)
  1408  		// only guarantees that when it returns, the exec is committed to
  1409  		// happen and succeed.  It uses a close-on-exec file descriptor
  1410  		// itself to determine this, so we know that when cmd.Start returns,
  1411  		// at least one close-on-exec file descriptor has been closed.
  1412  		// However, we cannot be sure that all of them have been closed,
  1413  		// so the program might still encounter ETXTBSY even with such
  1414  		// an RWLock.  The race window would be smaller, perhaps, but not
  1415  		// guaranteed to be gone.
  1416  		//
  1417  		// Sleeping when we observe the race seems to be the most reliable
  1418  		// option we have.
  1419  		//
  1420  		// http://golang.org/issue/3001
  1421  		//
  1422  		if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
  1423  			time.Sleep(100 * time.Millisecond << uint(nbusy))
  1424  			nbusy++
  1425  			continue
  1426  		}
  1427  
  1428  		return buf.Bytes(), err
  1429  	}
  1430  }
  1431  
  1432  // joinUnambiguously prints the slice, quoting where necessary to make the
  1433  // output unambiguous.
  1434  // TODO: See issue 5279. The printing of commands needs a complete redo.
  1435  func joinUnambiguously(a []string) string {
  1436  	var buf bytes.Buffer
  1437  	for i, s := range a {
  1438  		if i > 0 {
  1439  			buf.WriteByte(' ')
  1440  		}
  1441  		q := strconv.Quote(s)
  1442  		if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
  1443  			buf.WriteString(q)
  1444  		} else {
  1445  			buf.WriteString(s)
  1446  		}
  1447  	}
  1448  	return buf.String()
  1449  }
  1450  
  1451  // mkdir makes the named directory.
  1452  func (b *builder) mkdir(dir string) error {
  1453  	b.exec.Lock()
  1454  	defer b.exec.Unlock()
  1455  	// We can be a little aggressive about being
  1456  	// sure directories exist.  Skip repeated calls.
  1457  	if b.mkdirCache[dir] {
  1458  		return nil
  1459  	}
  1460  	b.mkdirCache[dir] = true
  1461  
  1462  	if buildN || buildX {
  1463  		b.showcmd("", "mkdir -p %s", dir)
  1464  		if buildN {
  1465  			return nil
  1466  		}
  1467  	}
  1468  
  1469  	if err := os.MkdirAll(dir, 0777); err != nil {
  1470  		return err
  1471  	}
  1472  	return nil
  1473  }
  1474  
  1475  // mkAbs returns an absolute path corresponding to
  1476  // evaluating f in the directory dir.
  1477  // We always pass absolute paths of source files so that
  1478  // the error messages will include the full path to a file
  1479  // in need of attention.
  1480  func mkAbs(dir, f string) string {
  1481  	// Leave absolute paths alone.
  1482  	// Also, during -n mode we use the pseudo-directory $WORK
  1483  	// instead of creating an actual work directory that won't be used.
  1484  	// Leave paths beginning with $WORK alone too.
  1485  	if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
  1486  		return f
  1487  	}
  1488  	return filepath.Join(dir, f)
  1489  }
  1490  
  1491  type toolchain interface {
  1492  	// gc runs the compiler in a specific directory on a set of files
  1493  	// and returns the name of the generated output file.
  1494  	// The compiler runs in the directory dir.
  1495  	gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
  1496  	// cc runs the toolchain's C compiler in a directory on a C file
  1497  	// to produce an output file.
  1498  	cc(b *builder, p *Package, objdir, ofile, cfile string) error
  1499  	// asm runs the assembler in a specific directory on a specific file
  1500  	// to generate the named output file.
  1501  	asm(b *builder, p *Package, obj, ofile, sfile string) error
  1502  	// pkgpath builds an appropriate path for a temporary package file.
  1503  	pkgpath(basedir string, p *Package) string
  1504  	// pack runs the archive packer in a specific directory to create
  1505  	// an archive from a set of object files.
  1506  	// typically it is run in the object directory.
  1507  	pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
  1508  	// ld runs the linker to create a package starting at mainpkg.
  1509  	ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error
  1510  
  1511  	compiler() string
  1512  	linker() string
  1513  }
  1514  
  1515  type noToolchain struct{}
  1516  
  1517  func noCompiler() error {
  1518  	log.Fatalf("unknown compiler %q", buildContext.Compiler)
  1519  	return nil
  1520  }
  1521  
  1522  func (noToolchain) compiler() string {
  1523  	noCompiler()
  1524  	return ""
  1525  }
  1526  
  1527  func (noToolchain) linker() string {
  1528  	noCompiler()
  1529  	return ""
  1530  }
  1531  
  1532  func (noToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
  1533  	return "", nil, noCompiler()
  1534  }
  1535  
  1536  func (noToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
  1537  	return noCompiler()
  1538  }
  1539  
  1540  func (noToolchain) pkgpath(basedir string, p *Package) string {
  1541  	noCompiler()
  1542  	return ""
  1543  }
  1544  
  1545  func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  1546  	return noCompiler()
  1547  }
  1548  
  1549  func (noToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
  1550  	return noCompiler()
  1551  }
  1552  
  1553  func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  1554  	return noCompiler()
  1555  }
  1556  
  1557  // The Go toolchain.
  1558  type gcToolchain struct{}
  1559  
  1560  func (gcToolchain) compiler() string {
  1561  	return tool(archChar + "g")
  1562  }
  1563  
  1564  func (gcToolchain) linker() string {
  1565  	return tool(archChar + "l")
  1566  }
  1567  
  1568  func (gcToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
  1569  	if archive != "" {
  1570  		ofile = archive
  1571  	} else {
  1572  		out := "_go_." + archChar
  1573  		ofile = obj + out
  1574  	}
  1575  
  1576  	gcargs := []string{"-p", p.ImportPath}
  1577  	if p.Standard && p.ImportPath == "runtime" {
  1578  		// runtime compiles with a special 6g flag to emit
  1579  		// additional reflect type data.
  1580  		gcargs = append(gcargs, "-+")
  1581  	}
  1582  
  1583  	// If we're giving the compiler the entire package (no C etc files), tell it that,
  1584  	// so that it can give good error messages about forward declarations.
  1585  	// Exceptions: a few standard packages have forward declarations for
  1586  	// pieces supplied behind-the-scenes by package runtime.
  1587  	extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
  1588  	if p.Standard {
  1589  		switch p.ImportPath {
  1590  		case "os", "runtime/pprof", "sync", "time":
  1591  			extFiles++
  1592  		}
  1593  	}
  1594  	if extFiles == 0 {
  1595  		gcargs = append(gcargs, "-complete")
  1596  	}
  1597  	if buildContext.InstallSuffix != "" {
  1598  		gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
  1599  	}
  1600  
  1601  	args := stringList(tool(archChar+"g"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
  1602  	if ofile == archive {
  1603  		args = append(args, "-pack")
  1604  	}
  1605  	for _, f := range gofiles {
  1606  		args = append(args, mkAbs(p.Dir, f))
  1607  	}
  1608  
  1609  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
  1610  	return ofile, output, err
  1611  }
  1612  
  1613  func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
  1614  	sfile = mkAbs(p.Dir, sfile)
  1615  	return b.run(p.Dir, p.ImportPath, nil, tool(archChar+"a"), "-trimpath", b.work, "-I", obj, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile)
  1616  }
  1617  
  1618  func (gcToolchain) pkgpath(basedir string, p *Package) string {
  1619  	end := filepath.FromSlash(p.ImportPath + ".a")
  1620  	return filepath.Join(basedir, end)
  1621  }
  1622  
  1623  func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  1624  	var absOfiles []string
  1625  	for _, f := range ofiles {
  1626  		absOfiles = append(absOfiles, mkAbs(objDir, f))
  1627  	}
  1628  	cmd := "c"
  1629  	absAfile := mkAbs(objDir, afile)
  1630  	appending := false
  1631  	if _, err := os.Stat(absAfile); err == nil {
  1632  		appending = true
  1633  		cmd = "r"
  1634  	}
  1635  
  1636  	cmdline := stringList("pack", cmd, absAfile, absOfiles)
  1637  
  1638  	if appending {
  1639  		if buildN || buildX {
  1640  			b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
  1641  		}
  1642  		if buildN {
  1643  			return nil
  1644  		}
  1645  		if err := packInternal(b, absAfile, absOfiles); err != nil {
  1646  			b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
  1647  			return errPrintedOutput
  1648  		}
  1649  		return nil
  1650  	}
  1651  
  1652  	// Need actual pack.
  1653  	cmdline[0] = tool("pack")
  1654  	return b.run(p.Dir, p.ImportPath, nil, cmdline)
  1655  }
  1656  
  1657  func packInternal(b *builder, afile string, ofiles []string) error {
  1658  	dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
  1659  	if err != nil {
  1660  		return err
  1661  	}
  1662  	defer dst.Close() // only for error returns or panics
  1663  	w := bufio.NewWriter(dst)
  1664  
  1665  	for _, ofile := range ofiles {
  1666  		src, err := os.Open(ofile)
  1667  		if err != nil {
  1668  			return err
  1669  		}
  1670  		fi, err := src.Stat()
  1671  		if err != nil {
  1672  			src.Close()
  1673  			return err
  1674  		}
  1675  		// Note: Not using %-16.16s format because we care
  1676  		// about bytes, not runes.
  1677  		name := fi.Name()
  1678  		if len(name) > 16 {
  1679  			name = name[:16]
  1680  		} else {
  1681  			name += strings.Repeat(" ", 16-len(name))
  1682  		}
  1683  		size := fi.Size()
  1684  		fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
  1685  			name, 0, 0, 0, 0644, size)
  1686  		n, err := io.Copy(w, src)
  1687  		src.Close()
  1688  		if err == nil && n < size {
  1689  			err = io.ErrUnexpectedEOF
  1690  		} else if err == nil && n > size {
  1691  			err = fmt.Errorf("file larger than size reported by stat")
  1692  		}
  1693  		if err != nil {
  1694  			return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
  1695  		}
  1696  		if size&1 != 0 {
  1697  			w.WriteByte(0)
  1698  		}
  1699  	}
  1700  
  1701  	if err := w.Flush(); err != nil {
  1702  		return err
  1703  	}
  1704  	return dst.Close()
  1705  }
  1706  
  1707  func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
  1708  	importArgs := b.includeArgs("-L", allactions)
  1709  	cxx := false
  1710  	for _, a := range allactions {
  1711  		if a.p != nil && len(a.p.CXXFiles) > 0 {
  1712  			cxx = true
  1713  		}
  1714  	}
  1715  	ldflags := buildLdflags
  1716  	// Limit slice capacity so that concurrent appends do not race on the shared array.
  1717  	ldflags = ldflags[:len(ldflags):len(ldflags)]
  1718  	if buildContext.InstallSuffix != "" {
  1719  		ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
  1720  	}
  1721  	if p.omitDWARF {
  1722  		ldflags = append(ldflags, "-w")
  1723  	}
  1724  
  1725  	// If the user has not specified the -extld option, then specify the
  1726  	// appropriate linker. In case of C++ code, use the compiler named
  1727  	// by the CXX environment variable or defaultCXX if CXX is not set.
  1728  	// Else, use the CC environment variable and defaultCC as fallback.
  1729  	extld := false
  1730  	for _, f := range ldflags {
  1731  		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
  1732  			extld = true
  1733  			break
  1734  		}
  1735  	}
  1736  	if !extld {
  1737  		var compiler []string
  1738  		if cxx {
  1739  			compiler = envList("CXX", defaultCXX)
  1740  		} else {
  1741  			compiler = envList("CC", defaultCC)
  1742  		}
  1743  		ldflags = append(ldflags, "-extld="+compiler[0])
  1744  		if len(compiler) > 1 {
  1745  			extldflags := false
  1746  			add := strings.Join(compiler[1:], " ")
  1747  			for i, f := range ldflags {
  1748  				if f == "-extldflags" && i+1 < len(ldflags) {
  1749  					ldflags[i+1] = add + " " + ldflags[i+1]
  1750  					extldflags = true
  1751  					break
  1752  				} else if strings.HasPrefix(f, "-extldflags=") {
  1753  					ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
  1754  					extldflags = true
  1755  					break
  1756  				}
  1757  			}
  1758  			if !extldflags {
  1759  				ldflags = append(ldflags, "-extldflags="+add)
  1760  			}
  1761  		}
  1762  	}
  1763  	return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, ldflags, mainpkg)
  1764  }
  1765  
  1766  func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  1767  	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
  1768  	cfile = mkAbs(p.Dir, cfile)
  1769  	args := stringList(tool(archChar+"c"), "-F", "-V", "-w", "-trimpath", b.work, "-I", objdir, "-I", inc, "-o", ofile, buildCcflags, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, cfile)
  1770  	return b.run(p.Dir, p.ImportPath, nil, args)
  1771  }
  1772  
  1773  // The Gccgo toolchain.
  1774  type gccgoToolchain struct{}
  1775  
  1776  var gccgoBin, _ = exec.LookPath("gccgo")
  1777  
  1778  func (gccgoToolchain) compiler() string {
  1779  	return gccgoBin
  1780  }
  1781  
  1782  func (gccgoToolchain) linker() string {
  1783  	return gccgoBin
  1784  }
  1785  
  1786  func (gccgoToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
  1787  	out := p.Name + ".o"
  1788  	ofile = obj + out
  1789  	gcargs := []string{"-g"}
  1790  	gcargs = append(gcargs, b.gccArchArgs()...)
  1791  	if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  1792  		gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
  1793  	}
  1794  	if p.localPrefix != "" {
  1795  		gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
  1796  	}
  1797  	args := stringList("gccgo", importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
  1798  	for _, f := range gofiles {
  1799  		args = append(args, mkAbs(p.Dir, f))
  1800  	}
  1801  
  1802  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
  1803  	return ofile, output, err
  1804  }
  1805  
  1806  func (gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
  1807  	sfile = mkAbs(p.Dir, sfile)
  1808  	defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
  1809  	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  1810  		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
  1811  	}
  1812  	defs = append(defs, b.gccArchArgs()...)
  1813  	return b.run(p.Dir, p.ImportPath, nil, "gccgo", "-I", obj, "-o", ofile, defs, sfile)
  1814  }
  1815  
  1816  func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
  1817  	end := filepath.FromSlash(p.ImportPath + ".a")
  1818  	afile := filepath.Join(basedir, end)
  1819  	// add "lib" to the final element
  1820  	return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
  1821  }
  1822  
  1823  func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  1824  	var absOfiles []string
  1825  	for _, f := range ofiles {
  1826  		absOfiles = append(absOfiles, mkAbs(objDir, f))
  1827  	}
  1828  	return b.run(p.Dir, p.ImportPath, nil, "ar", "cru", mkAbs(objDir, afile), absOfiles)
  1829  }
  1830  
  1831  func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
  1832  	// gccgo needs explicit linking with all package dependencies,
  1833  	// and all LDFLAGS from cgo dependencies.
  1834  	apackagesSeen := make(map[*Package]bool)
  1835  	afiles := []string{}
  1836  	ldflags := b.gccArchArgs()
  1837  	cgoldflags := []string{}
  1838  	usesCgo := false
  1839  	cxx := false
  1840  	objc := false
  1841  
  1842  	// Prefer the output of an install action to the output of a build action,
  1843  	// because the install action will delete the output of the build action.
  1844  	// Iterate over the list backward (reverse dependency order) so that we
  1845  	// always see the install before the build.
  1846  	for i := len(allactions) - 1; i >= 0; i-- {
  1847  		a := allactions[i]
  1848  		if !a.p.Standard {
  1849  			if a.p != nil && !apackagesSeen[a.p] {
  1850  				apackagesSeen[a.p] = true
  1851  				if a.p.fake {
  1852  					// move _test files to the top of the link order
  1853  					afiles = append([]string{a.target}, afiles...)
  1854  				} else {
  1855  					afiles = append(afiles, a.target)
  1856  				}
  1857  			}
  1858  		}
  1859  	}
  1860  
  1861  	for _, a := range allactions {
  1862  		if a.p != nil {
  1863  			cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
  1864  			if len(a.p.CgoFiles) > 0 {
  1865  				usesCgo = true
  1866  			}
  1867  			if a.p.usesSwig() {
  1868  				usesCgo = true
  1869  			}
  1870  			if len(a.p.CXXFiles) > 0 {
  1871  				cxx = true
  1872  			}
  1873  			if len(a.p.MFiles) > 0 {
  1874  				objc = true
  1875  			}
  1876  		}
  1877  	}
  1878  	ldflags = append(ldflags, afiles...)
  1879  	ldflags = append(ldflags, cgoldflags...)
  1880  	ldflags = append(ldflags, p.CgoLDFLAGS...)
  1881  	if usesCgo && goos == "linux" {
  1882  		ldflags = append(ldflags, "-Wl,-E")
  1883  	}
  1884  	if cxx {
  1885  		ldflags = append(ldflags, "-lstdc++")
  1886  	}
  1887  	if objc {
  1888  		ldflags = append(ldflags, "-lobjc")
  1889  	}
  1890  	return b.run(".", p.ImportPath, nil, "gccgo", "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
  1891  }
  1892  
  1893  func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  1894  	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
  1895  	cfile = mkAbs(p.Dir, cfile)
  1896  	defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
  1897  	defs = append(defs, b.gccArchArgs()...)
  1898  	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  1899  		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
  1900  	}
  1901  	// TODO: Support using clang here (during gccgo build)?
  1902  	return b.run(p.Dir, p.ImportPath, nil, "gcc", "-Wall", "-g",
  1903  		"-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
  1904  }
  1905  
  1906  func gccgoPkgpath(p *Package) string {
  1907  	if p.build.IsCommand() && !p.forceLibrary {
  1908  		return ""
  1909  	}
  1910  	return p.ImportPath
  1911  }
  1912  
  1913  func gccgoCleanPkgpath(p *Package) string {
  1914  	clean := func(r rune) rune {
  1915  		switch {
  1916  		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
  1917  			'0' <= r && r <= '9':
  1918  			return r
  1919  		}
  1920  		return '_'
  1921  	}
  1922  	return strings.Map(clean, gccgoPkgpath(p))
  1923  }
  1924  
  1925  // libgcc returns the filename for libgcc, as determined by invoking gcc with
  1926  // the -print-libgcc-file-name option.
  1927  func (b *builder) libgcc(p *Package) (string, error) {
  1928  	var buf bytes.Buffer
  1929  
  1930  	gccCmd := b.gccCmd(p.Dir)
  1931  
  1932  	prev := b.print
  1933  	if buildN {
  1934  		// In -n mode we temporarily swap out the builder's
  1935  		// print function to capture the command-line. This
  1936  		// let's us assign it to $LIBGCC and produce a valid
  1937  		// buildscript for cgo packages.
  1938  		b.print = func(a ...interface{}) (int, error) {
  1939  			return fmt.Fprint(&buf, a...)
  1940  		}
  1941  	}
  1942  	f, err := b.runOut(p.Dir, p.ImportPath, nil, gccCmd, "-print-libgcc-file-name")
  1943  	if err != nil {
  1944  		return "", fmt.Errorf("gcc -print-libgcc-file-name: %v (%s)", err, f)
  1945  	}
  1946  	if buildN {
  1947  		s := fmt.Sprintf("LIBGCC=$(%s)\n", buf.Next(buf.Len()-1))
  1948  		b.print = prev
  1949  		b.print(s)
  1950  		return "$LIBGCC", nil
  1951  	}
  1952  
  1953  	// clang might not be able to find libgcc, and in that case,
  1954  	// it will simply return "libgcc.a", which is of no use to us.
  1955  	if strings.Contains(gccCmd[0], "clang") && !filepath.IsAbs(string(f)) {
  1956  		return "", nil
  1957  	}
  1958  
  1959  	return strings.Trim(string(f), "\r\n"), nil
  1960  }
  1961  
  1962  // gcc runs the gcc C compiler to create an object from a single C file.
  1963  func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
  1964  	return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
  1965  }
  1966  
  1967  // gxx runs the g++ C++ compiler to create an object from a single C++ file.
  1968  func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
  1969  	return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
  1970  }
  1971  
  1972  // ccompile runs the given C or C++ compiler and creates an object from a single source file.
  1973  func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error {
  1974  	file = mkAbs(p.Dir, file)
  1975  	return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file)
  1976  }
  1977  
  1978  // gccld runs the gcc linker to create an executable from a set of object files.
  1979  func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
  1980  	var cmd []string
  1981  	if len(p.CXXFiles) > 0 {
  1982  		cmd = b.gxxCmd(p.Dir)
  1983  	} else {
  1984  		cmd = b.gccCmd(p.Dir)
  1985  	}
  1986  	return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
  1987  }
  1988  
  1989  // gccCmd returns a gcc command line prefix
  1990  // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
  1991  func (b *builder) gccCmd(objdir string) []string {
  1992  	return b.ccompilerCmd("CC", defaultCC, objdir)
  1993  }
  1994  
  1995  // gxxCmd returns a g++ command line prefix
  1996  // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
  1997  func (b *builder) gxxCmd(objdir string) []string {
  1998  	return b.ccompilerCmd("CXX", defaultCXX, objdir)
  1999  }
  2000  
  2001  // ccompilerCmd returns a command line prefix for the given environment
  2002  // variable and using the default command when the variable is empty.
  2003  func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
  2004  	// NOTE: env.go's mkEnv knows that the first three
  2005  	// strings returned are "gcc", "-I", objdir (and cuts them off).
  2006  
  2007  	compiler := envList(envvar, defcmd)
  2008  	a := []string{compiler[0], "-I", objdir}
  2009  	a = append(a, compiler[1:]...)
  2010  
  2011  	// Definitely want -fPIC but on Windows gcc complains
  2012  	// "-fPIC ignored for target (all code is position independent)"
  2013  	if goos != "windows" {
  2014  		a = append(a, "-fPIC")
  2015  	}
  2016  	a = append(a, b.gccArchArgs()...)
  2017  	// gcc-4.5 and beyond require explicit "-pthread" flag
  2018  	// for multithreading with pthread library.
  2019  	if buildContext.CgoEnabled {
  2020  		switch goos {
  2021  		case "windows":
  2022  			a = append(a, "-mthreads")
  2023  		default:
  2024  			a = append(a, "-pthread")
  2025  		}
  2026  	}
  2027  
  2028  	if strings.Contains(a[0], "clang") {
  2029  		// disable ASCII art in clang errors, if possible
  2030  		a = append(a, "-fno-caret-diagnostics")
  2031  		// clang is too smart about command-line arguments
  2032  		a = append(a, "-Qunused-arguments")
  2033  	}
  2034  
  2035  	// disable word wrapping in error messages
  2036  	a = append(a, "-fmessage-length=0")
  2037  
  2038  	// On OS X, some of the compilers behave as if -fno-common
  2039  	// is always set, and the Mach-O linker in 6l/8l assumes this.
  2040  	// See http://golang.org/issue/3253.
  2041  	if goos == "darwin" {
  2042  		a = append(a, "-fno-common")
  2043  	}
  2044  
  2045  	return a
  2046  }
  2047  
  2048  // gccArchArgs returns arguments to pass to gcc based on the architecture.
  2049  func (b *builder) gccArchArgs() []string {
  2050  	switch archChar {
  2051  	case "8":
  2052  		return []string{"-m32"}
  2053  	case "6":
  2054  		return []string{"-m64"}
  2055  	case "5":
  2056  		return []string{"-marm"} // not thumb
  2057  	}
  2058  	return nil
  2059  }
  2060  
  2061  // envList returns the value of the given environment variable broken
  2062  // into fields, using the default value when the variable is empty.
  2063  func envList(key, def string) []string {
  2064  	v := os.Getenv(key)
  2065  	if v == "" {
  2066  		v = def
  2067  	}
  2068  	return strings.Fields(v)
  2069  }
  2070  
  2071  // Return the flags to use when invoking the C or C++ compilers, or cgo.
  2072  func (b *builder) cflags(p *Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) {
  2073  	var defaults string
  2074  	if def {
  2075  		defaults = "-g -O2"
  2076  	}
  2077  
  2078  	cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
  2079  	cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
  2080  	cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
  2081  	ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
  2082  	return
  2083  }
  2084  
  2085  var cgoRe = regexp.MustCompile(`[/\\:]`)
  2086  
  2087  var (
  2088  	cgoLibGccFile     string
  2089  	cgoLibGccErr      error
  2090  	cgoLibGccFileOnce sync.Once
  2091  )
  2092  
  2093  func (b *builder) cgo(p *Package, cgoExe, obj string, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
  2094  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true)
  2095  	_, cgoexeCFLAGS, _, _ := b.cflags(p, false)
  2096  
  2097  	// If we are compiling Objective-C code, then we need to link against libobjc
  2098  	if len(mfiles) > 0 {
  2099  		cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
  2100  	}
  2101  
  2102  	if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
  2103  		out, err := b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
  2104  		if err != nil {
  2105  			b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
  2106  			b.print(err.Error() + "\n")
  2107  			return nil, nil, errPrintedOutput
  2108  		}
  2109  		if len(out) > 0 {
  2110  			cgoCPPFLAGS = append(cgoCPPFLAGS, strings.Fields(string(out))...)
  2111  		}
  2112  		out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
  2113  		if err != nil {
  2114  			b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
  2115  			b.print(err.Error() + "\n")
  2116  			return nil, nil, errPrintedOutput
  2117  		}
  2118  		if len(out) > 0 {
  2119  			cgoLDFLAGS = append(cgoLDFLAGS, strings.Fields(string(out))...)
  2120  		}
  2121  	}
  2122  
  2123  	// Allows including _cgo_export.h from .[ch] files in the package.
  2124  	cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
  2125  
  2126  	// cgo
  2127  	// TODO: CGOPKGPATH, CGO_FLAGS?
  2128  	gofiles := []string{obj + "_cgo_gotypes.go"}
  2129  	cfiles := []string{"_cgo_main.c", "_cgo_export.c"}
  2130  	for _, fn := range p.CgoFiles {
  2131  		f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
  2132  		gofiles = append(gofiles, obj+f+"cgo1.go")
  2133  		cfiles = append(cfiles, f+"cgo2.c")
  2134  	}
  2135  	defunC := obj + "_cgo_defun.c"
  2136  
  2137  	cgoflags := []string{}
  2138  	// TODO: make cgo not depend on $GOARCH?
  2139  
  2140  	objExt := archChar
  2141  
  2142  	if p.Standard && p.ImportPath == "runtime/cgo" {
  2143  		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
  2144  	}
  2145  	if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/cgo") {
  2146  		cgoflags = append(cgoflags, "-import_syscall=false")
  2147  	}
  2148  
  2149  	// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
  2150  	var cgoenv []string
  2151  	if len(cgoLDFLAGS) > 0 {
  2152  		flags := make([]string, len(cgoLDFLAGS))
  2153  		for i, f := range cgoLDFLAGS {
  2154  			flags[i] = strconv.Quote(f)
  2155  		}
  2156  		cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
  2157  	}
  2158  
  2159  	if _, ok := buildToolchain.(gccgoToolchain); ok {
  2160  		cgoflags = append(cgoflags, "-gccgo")
  2161  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  2162  			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
  2163  		}
  2164  		objExt = "o"
  2165  	}
  2166  	if err := b.run(p.Dir, p.ImportPath, cgoenv, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, p.CgoFiles); err != nil {
  2167  		return nil, nil, err
  2168  	}
  2169  	outGo = append(outGo, gofiles...)
  2170  
  2171  	// cc _cgo_defun.c
  2172  	defunObj := obj + "_cgo_defun." + objExt
  2173  	if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
  2174  		return nil, nil, err
  2175  	}
  2176  	outObj = append(outObj, defunObj)
  2177  
  2178  	// gcc
  2179  	var linkobj []string
  2180  
  2181  	var bareLDFLAGS []string
  2182  	// filter out -lsomelib, -l somelib, *.{so,dll,dylib}, and (on Darwin) -framework X
  2183  	for i := 0; i < len(cgoLDFLAGS); i++ {
  2184  		f := cgoLDFLAGS[i]
  2185  		switch {
  2186  		// skip "-lc" or "-l somelib"
  2187  		case strings.HasPrefix(f, "-l"):
  2188  			if f == "-l" {
  2189  				i++
  2190  			}
  2191  		// skip "-framework X" on Darwin
  2192  		case goos == "darwin" && f == "-framework":
  2193  			i++
  2194  		// skip "*.{dylib,so,dll}"
  2195  		case strings.HasSuffix(f, ".dylib"),
  2196  			strings.HasSuffix(f, ".so"),
  2197  			strings.HasSuffix(f, ".dll"):
  2198  			continue
  2199  		default:
  2200  			bareLDFLAGS = append(bareLDFLAGS, f)
  2201  		}
  2202  	}
  2203  
  2204  	cgoLibGccFileOnce.Do(func() {
  2205  		cgoLibGccFile, cgoLibGccErr = b.libgcc(p)
  2206  	})
  2207  	if cgoLibGccFile == "" && cgoLibGccErr != nil {
  2208  		return nil, nil, err
  2209  	}
  2210  
  2211  	var staticLibs []string
  2212  	if goos == "windows" {
  2213  		// libmingw32 and libmingwex might also use libgcc, so libgcc must come last,
  2214  		// and they also have some inter-dependencies, so must use linker groups.
  2215  		staticLibs = []string{"-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group"}
  2216  	}
  2217  	if cgoLibGccFile != "" {
  2218  		staticLibs = append(staticLibs, cgoLibGccFile)
  2219  	}
  2220  
  2221  	cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
  2222  	for _, cfile := range cfiles {
  2223  		ofile := obj + cfile[:len(cfile)-1] + "o"
  2224  		if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
  2225  			return nil, nil, err
  2226  		}
  2227  		linkobj = append(linkobj, ofile)
  2228  		if !strings.HasSuffix(ofile, "_cgo_main.o") {
  2229  			outObj = append(outObj, ofile)
  2230  		}
  2231  	}
  2232  
  2233  	for _, file := range gccfiles {
  2234  		ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
  2235  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  2236  			return nil, nil, err
  2237  		}
  2238  		linkobj = append(linkobj, ofile)
  2239  		outObj = append(outObj, ofile)
  2240  	}
  2241  
  2242  	cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
  2243  	for _, file := range gxxfiles {
  2244  		// Append .o to the file, just in case the pkg has file.c and file.cpp
  2245  		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
  2246  		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
  2247  			return nil, nil, err
  2248  		}
  2249  		linkobj = append(linkobj, ofile)
  2250  		outObj = append(outObj, ofile)
  2251  	}
  2252  
  2253  	for _, file := range mfiles {
  2254  		// Append .o to the file, just in case the pkg has file.c and file.m
  2255  		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
  2256  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  2257  			return nil, nil, err
  2258  		}
  2259  		linkobj = append(linkobj, ofile)
  2260  		outObj = append(outObj, ofile)
  2261  	}
  2262  
  2263  	linkobj = append(linkobj, p.SysoFiles...)
  2264  	dynobj := obj + "_cgo_.o"
  2265  	if goarch == "arm" && goos == "linux" { // we need to use -pie for Linux/ARM to get accurate imported sym
  2266  		cgoLDFLAGS = append(cgoLDFLAGS, "-pie")
  2267  	}
  2268  	if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil {
  2269  		return nil, nil, err
  2270  	}
  2271  	if goarch == "arm" && goos == "linux" { // but we don't need -pie for normal cgo programs
  2272  		cgoLDFLAGS = cgoLDFLAGS[0 : len(cgoLDFLAGS)-1]
  2273  	}
  2274  
  2275  	if _, ok := buildToolchain.(gccgoToolchain); ok {
  2276  		// we don't use dynimport when using gccgo.
  2277  		return outGo, outObj, nil
  2278  	}
  2279  
  2280  	// cgo -dynimport
  2281  	importC := obj + "_cgo_import.c"
  2282  	cgoflags = []string{}
  2283  	if p.Standard && p.ImportPath == "runtime/cgo" {
  2284  		cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
  2285  	}
  2286  	if err := b.run(p.Dir, p.ImportPath, nil, cgoExe, "-objdir", obj, "-dynimport", dynobj, "-dynout", importC, cgoflags); err != nil {
  2287  		return nil, nil, err
  2288  	}
  2289  
  2290  	// cc _cgo_import.ARCH
  2291  	importObj := obj + "_cgo_import." + objExt
  2292  	if err := buildToolchain.cc(b, p, obj, importObj, importC); err != nil {
  2293  		return nil, nil, err
  2294  	}
  2295  
  2296  	ofile := obj + "_all.o"
  2297  	var gccObjs, nonGccObjs []string
  2298  	for _, f := range outObj {
  2299  		if strings.HasSuffix(f, ".o") {
  2300  			gccObjs = append(gccObjs, f)
  2301  		} else {
  2302  			nonGccObjs = append(nonGccObjs, f)
  2303  		}
  2304  	}
  2305  	if err := b.gccld(p, ofile, stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs), gccObjs); err != nil {
  2306  		return nil, nil, err
  2307  	}
  2308  
  2309  	// NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
  2310  	// must be processed before the gcc-generated objects.
  2311  	// Put it first.  http://golang.org/issue/2601
  2312  	outObj = stringList(importObj, nonGccObjs, ofile)
  2313  
  2314  	return outGo, outObj, nil
  2315  }
  2316  
  2317  // Run SWIG on all SWIG input files.
  2318  // TODO: Don't build a shared library, once SWIG emits the necessary
  2319  // pragmas for external linking.
  2320  func (b *builder) swig(p *Package, obj string, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
  2321  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
  2322  	cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
  2323  	cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
  2324  
  2325  	for _, file := range gccfiles {
  2326  		ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
  2327  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  2328  			return nil, nil, err
  2329  		}
  2330  		outObj = append(outObj, ofile)
  2331  	}
  2332  
  2333  	for _, file := range gxxfiles {
  2334  		// Append .o to the file, just in case the pkg has file.c and file.cpp
  2335  		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
  2336  		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
  2337  			return nil, nil, err
  2338  		}
  2339  		outObj = append(outObj, ofile)
  2340  	}
  2341  
  2342  	for _, file := range mfiles {
  2343  		// Append .o to the file, just in case the pkg has file.c and file.cpp
  2344  		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
  2345  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  2346  			return nil, nil, err
  2347  		}
  2348  		outObj = append(outObj, ofile)
  2349  	}
  2350  
  2351  	if err := b.swigVersionCheck(); err != nil {
  2352  		return nil, nil, err
  2353  	}
  2354  
  2355  	intgosize, err := b.swigIntSize(obj)
  2356  	if err != nil {
  2357  		return nil, nil, err
  2358  	}
  2359  
  2360  	for _, f := range p.SwigFiles {
  2361  		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, false, intgosize)
  2362  		if err != nil {
  2363  			return nil, nil, err
  2364  		}
  2365  		if goFile != "" {
  2366  			outGo = append(outGo, goFile)
  2367  		}
  2368  		if objFile != "" {
  2369  			outObj = append(outObj, objFile)
  2370  		}
  2371  		if gccObjFile != "" {
  2372  			outObj = append(outObj, gccObjFile)
  2373  		}
  2374  	}
  2375  	for _, f := range p.SwigCXXFiles {
  2376  		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, true, intgosize)
  2377  		if err != nil {
  2378  			return nil, nil, err
  2379  		}
  2380  		if goFile != "" {
  2381  			outGo = append(outGo, goFile)
  2382  		}
  2383  		if objFile != "" {
  2384  			outObj = append(outObj, objFile)
  2385  		}
  2386  		if gccObjFile != "" {
  2387  			outObj = append(outObj, gccObjFile)
  2388  		}
  2389  	}
  2390  	return outGo, outObj, nil
  2391  }
  2392  
  2393  // Make sure SWIG is new enough.
  2394  var (
  2395  	swigCheckOnce sync.Once
  2396  	swigCheck     error
  2397  )
  2398  
  2399  func (b *builder) swigDoVersionCheck() error {
  2400  	out, err := b.runOut("", "", nil, "swig", "-version")
  2401  	if err != nil {
  2402  		return err
  2403  	}
  2404  	re := regexp.MustCompile(`[vV]ersion +([\d])`)
  2405  	matches := re.FindSubmatch(out)
  2406  	if matches == nil {
  2407  		// Can't find version number; hope for the best.
  2408  		return nil
  2409  	}
  2410  	major, err := strconv.Atoi(string(matches[1]))
  2411  	if err != nil {
  2412  		// Can't find version number; hope for the best.
  2413  		return nil
  2414  	}
  2415  	if major < 3 {
  2416  		return errors.New("must have SWIG version >= 3.0")
  2417  	}
  2418  	return nil
  2419  }
  2420  
  2421  func (b *builder) swigVersionCheck() error {
  2422  	swigCheckOnce.Do(func() {
  2423  		swigCheck = b.swigDoVersionCheck()
  2424  	})
  2425  	return swigCheck
  2426  }
  2427  
  2428  // This code fails to build if sizeof(int) <= 32
  2429  const swigIntSizeCode = `
  2430  package main
  2431  const i int = 1 << 32
  2432  `
  2433  
  2434  // Determine the size of int on the target system for the -intgosize option
  2435  // of swig >= 2.0.9
  2436  func (b *builder) swigIntSize(obj string) (intsize string, err error) {
  2437  	if buildN {
  2438  		return "$INTBITS", nil
  2439  	}
  2440  	src := filepath.Join(b.work, "swig_intsize.go")
  2441  	if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0644); err != nil {
  2442  		return
  2443  	}
  2444  	srcs := []string{src}
  2445  
  2446  	p := goFilesPackage(srcs)
  2447  
  2448  	if _, _, e := buildToolchain.gc(b, p, "", obj, nil, srcs); e != nil {
  2449  		return "32", nil
  2450  	}
  2451  	return "64", nil
  2452  }
  2453  
  2454  // Run SWIG on one SWIG input file.
  2455  func (b *builder) swigOne(p *Package, file, obj string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
  2456  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
  2457  	var cflags []string
  2458  	if cxx {
  2459  		cflags = stringList(cgoCPPFLAGS, cgoCXXFLAGS)
  2460  	} else {
  2461  		cflags = stringList(cgoCPPFLAGS, cgoCFLAGS)
  2462  	}
  2463  
  2464  	n := 5 // length of ".swig"
  2465  	if cxx {
  2466  		n = 8 // length of ".swigcxx"
  2467  	}
  2468  	base := file[:len(file)-n]
  2469  	goFile := base + ".go"
  2470  	cBase := base + "_gc."
  2471  	gccBase := base + "_wrap."
  2472  	gccExt := "c"
  2473  	if cxx {
  2474  		gccExt = "cxx"
  2475  	}
  2476  
  2477  	_, gccgo := buildToolchain.(gccgoToolchain)
  2478  
  2479  	// swig
  2480  	args := []string{
  2481  		"-go",
  2482  		"-intgosize", intgosize,
  2483  		"-module", base,
  2484  		"-o", obj + gccBase + gccExt,
  2485  		"-outdir", obj,
  2486  	}
  2487  	if gccgo {
  2488  		args = append(args, "-gccgo")
  2489  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  2490  			args = append(args, "-go-pkgpath", pkgpath)
  2491  		}
  2492  	}
  2493  	if cxx {
  2494  		args = append(args, "-c++")
  2495  	}
  2496  
  2497  	if out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file); err != nil {
  2498  		if len(out) > 0 {
  2499  			if bytes.Contains(out, []byte("Unrecognized option -intgosize")) {
  2500  				return "", "", "", errors.New("must have SWIG version >= 3.0")
  2501  			}
  2502  			b.showOutput(p.Dir, p.ImportPath, b.processOutput(out))
  2503  			return "", "", "", errPrintedOutput
  2504  		}
  2505  		return "", "", "", err
  2506  	}
  2507  
  2508  	var cObj string
  2509  	if !gccgo {
  2510  		// cc
  2511  		cObj = obj + cBase + archChar
  2512  		if err := buildToolchain.cc(b, p, obj, cObj, obj+cBase+"c"); err != nil {
  2513  			return "", "", "", err
  2514  		}
  2515  	}
  2516  
  2517  	// gcc
  2518  	gccObj := obj + gccBase + "o"
  2519  	if !cxx {
  2520  		if err := b.gcc(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
  2521  			return "", "", "", err
  2522  		}
  2523  	} else {
  2524  		if err := b.gxx(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
  2525  			return "", "", "", err
  2526  		}
  2527  	}
  2528  
  2529  	return obj + goFile, cObj, gccObj, nil
  2530  }
  2531  
  2532  // An actionQueue is a priority queue of actions.
  2533  type actionQueue []*action
  2534  
  2535  // Implement heap.Interface
  2536  func (q *actionQueue) Len() int           { return len(*q) }
  2537  func (q *actionQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
  2538  func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
  2539  func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) }
  2540  func (q *actionQueue) Pop() interface{} {
  2541  	n := len(*q) - 1
  2542  	x := (*q)[n]
  2543  	*q = (*q)[:n]
  2544  	return x
  2545  }
  2546  
  2547  func (q *actionQueue) push(a *action) {
  2548  	heap.Push(q, a)
  2549  }
  2550  
  2551  func (q *actionQueue) pop() *action {
  2552  	return heap.Pop(q).(*action)
  2553  }
  2554  
  2555  func raceInit() {
  2556  	if !buildRace {
  2557  		return
  2558  	}
  2559  	if goarch != "amd64" || goos != "linux" && goos != "darwin" && goos != "windows" {
  2560  		fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
  2561  		os.Exit(2)
  2562  	}
  2563  	buildGcflags = append(buildGcflags, "-race")
  2564  	buildLdflags = append(buildLdflags, "-race")
  2565  	buildCcflags = append(buildCcflags, "-D", "RACE")
  2566  	if buildContext.InstallSuffix != "" {
  2567  		buildContext.InstallSuffix += "_"
  2568  	}
  2569  	buildContext.InstallSuffix += "race"
  2570  	buildContext.BuildTags = append(buildContext.BuildTags, "race")
  2571  }
  2572  
  2573  // defaultSuffix returns file extension used for command files in
  2574  // current os environment.
  2575  func defaultSuffix() string {
  2576  	switch runtime.GOOS {
  2577  	case "windows":
  2578  		return ".bat"
  2579  	case "plan9":
  2580  		return ".rc"
  2581  	default:
  2582  		return ".bash"
  2583  	}
  2584  }