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