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