github.com/roboticscm/goman@v0.0.0-20210203095141-87c07b4a0a55/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.HFiles, "zasm_"+buildContext.GOOS+"_"+buildContext.GOARCH+".h") {
   817  		return fmt.Errorf("%s/%s must be bootstrapped using make%v", buildContext.GOOS, buildContext.GOARCH, defaultSuffix())
   818  	}
   819  
   820  	// Make build directory.
   821  	obj := a.objdir
   822  	if err := b.mkdir(obj); err != nil {
   823  		return err
   824  	}
   825  
   826  	// make target directory
   827  	dir, _ := filepath.Split(a.target)
   828  	if dir != "" {
   829  		if err := b.mkdir(dir); err != nil {
   830  			return err
   831  		}
   832  	}
   833  
   834  	var gofiles, cfiles, sfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
   835  
   836  	gofiles = append(gofiles, a.p.GoFiles...)
   837  	cfiles = append(cfiles, a.p.CFiles...)
   838  	sfiles = append(sfiles, a.p.SFiles...)
   839  
   840  	if a.p.usesCgo() || a.p.usesSwig() {
   841  		if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.p); err != nil {
   842  			return
   843  		}
   844  	}
   845  	// Run cgo.
   846  	if a.p.usesCgo() {
   847  		// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
   848  		// There is one exception: runtime/cgo's job is to bridge the
   849  		// cgo and non-cgo worlds, so it necessarily has files in both.
   850  		// In that case gcc only gets the gcc_* files.
   851  		var gccfiles []string
   852  		if a.p.Standard && a.p.ImportPath == "runtime/cgo" {
   853  			filter := func(files, nongcc, gcc []string) ([]string, []string) {
   854  				for _, f := range files {
   855  					if strings.HasPrefix(f, "gcc_") {
   856  						gcc = append(gcc, f)
   857  					} else {
   858  						nongcc = append(nongcc, f)
   859  					}
   860  				}
   861  				return nongcc, gcc
   862  			}
   863  			cfiles, gccfiles = filter(cfiles, cfiles[:0], gccfiles)
   864  			sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
   865  		} else {
   866  			gccfiles = append(cfiles, sfiles...)
   867  			cfiles = nil
   868  			sfiles = nil
   869  		}
   870  
   871  		cgoExe := tool("cgo")
   872  		if a.cgo != nil && a.cgo.target != "" {
   873  			cgoExe = a.cgo.target
   874  		}
   875  		outGo, outObj, err := b.cgo(a.p, cgoExe, obj, pcCFLAGS, pcLDFLAGS, gccfiles, a.p.CXXFiles, a.p.MFiles)
   876  		if err != nil {
   877  			return err
   878  		}
   879  		cgoObjects = append(cgoObjects, outObj...)
   880  		gofiles = append(gofiles, outGo...)
   881  	}
   882  
   883  	// Run SWIG.
   884  	if a.p.usesSwig() {
   885  		// In a package using SWIG, any .c or .s files are
   886  		// compiled with gcc.
   887  		gccfiles := append(cfiles, sfiles...)
   888  		cxxfiles, mfiles := a.p.CXXFiles, a.p.MFiles
   889  		cfiles = nil
   890  		sfiles = nil
   891  
   892  		// Don't build c/c++ files twice if cgo is enabled (mainly for pkg-config).
   893  		if a.p.usesCgo() {
   894  			cxxfiles = nil
   895  			gccfiles = nil
   896  			mfiles = nil
   897  		}
   898  
   899  		outGo, outObj, err := b.swig(a.p, obj, pcCFLAGS, gccfiles, cxxfiles, mfiles)
   900  		if err != nil {
   901  			return err
   902  		}
   903  		cgoObjects = append(cgoObjects, outObj...)
   904  		gofiles = append(gofiles, outGo...)
   905  	}
   906  
   907  	if len(gofiles) == 0 {
   908  		return &build.NoGoError{Dir: a.p.Dir}
   909  	}
   910  
   911  	// If we're doing coverage, preprocess the .go files and put them in the work directory
   912  	if a.p.coverMode != "" {
   913  		for i, file := range gofiles {
   914  			var sourceFile string
   915  			var coverFile string
   916  			var key string
   917  			if strings.HasSuffix(file, ".cgo1.go") {
   918  				// cgo files have absolute paths
   919  				base := filepath.Base(file)
   920  				sourceFile = file
   921  				coverFile = filepath.Join(obj, base)
   922  				key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
   923  			} else {
   924  				sourceFile = filepath.Join(a.p.Dir, file)
   925  				coverFile = filepath.Join(obj, file)
   926  				key = file
   927  			}
   928  			cover := a.p.coverVars[key]
   929  			if cover == nil || isTestFile(file) {
   930  				// Not covering this file.
   931  				continue
   932  			}
   933  			if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
   934  				return err
   935  			}
   936  			gofiles[i] = coverFile
   937  		}
   938  	}
   939  
   940  	// Prepare Go import path list.
   941  	inc := b.includeArgs("-I", a.deps)
   942  
   943  	// Compile Go.
   944  	ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, inc, gofiles)
   945  	if len(out) > 0 {
   946  		b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
   947  		if err != nil {
   948  			return errPrintedOutput
   949  		}
   950  	}
   951  	if err != nil {
   952  		return err
   953  	}
   954  	if ofile != a.objpkg {
   955  		objects = append(objects, ofile)
   956  	}
   957  
   958  	// Copy .h files named for goos or goarch or goos_goarch
   959  	// to names using GOOS and GOARCH.
   960  	// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
   961  	_goos_goarch := "_" + goos + "_" + goarch
   962  	_goos := "_" + goos
   963  	_goarch := "_" + goarch
   964  	for _, file := range a.p.HFiles {
   965  		name, ext := fileExtSplit(file)
   966  		switch {
   967  		case strings.HasSuffix(name, _goos_goarch):
   968  			targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
   969  			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
   970  				return err
   971  			}
   972  		case strings.HasSuffix(name, _goarch):
   973  			targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
   974  			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
   975  				return err
   976  			}
   977  		case strings.HasSuffix(name, _goos):
   978  			targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
   979  			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
   980  				return err
   981  			}
   982  		}
   983  	}
   984  
   985  	objExt := archChar
   986  	if _, ok := buildToolchain.(gccgoToolchain); ok {
   987  		objExt = "o"
   988  	}
   989  
   990  	for _, file := range cfiles {
   991  		out := file[:len(file)-len(".c")] + "." + objExt
   992  		if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
   993  			return err
   994  		}
   995  		objects = append(objects, out)
   996  	}
   997  
   998  	// Assemble .s files.
   999  	for _, file := range sfiles {
  1000  		out := file[:len(file)-len(".s")] + "." + objExt
  1001  		if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
  1002  			return err
  1003  		}
  1004  		objects = append(objects, out)
  1005  	}
  1006  
  1007  	// NOTE(rsc): On Windows, it is critically important that the
  1008  	// gcc-compiled objects (cgoObjects) be listed after the ordinary
  1009  	// objects in the archive.  I do not know why this is.
  1010  	// http://golang.org/issue/2601
  1011  	objects = append(objects, cgoObjects...)
  1012  
  1013  	// Add system object files.
  1014  	for _, syso := range a.p.SysoFiles {
  1015  		objects = append(objects, filepath.Join(a.p.Dir, syso))
  1016  	}
  1017  
  1018  	// Pack into archive in obj directory.
  1019  	// If the Go compiler wrote an archive, we only need to add the
  1020  	// object files for non-Go sources to the archive.
  1021  	// If the Go compiler wrote an archive and the package is entirely
  1022  	// Go sources, there is no pack to execute at all.
  1023  	if len(objects) > 0 {
  1024  		if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
  1025  			return err
  1026  		}
  1027  	}
  1028  
  1029  	// Link if needed.
  1030  	if a.link {
  1031  		// The compiler only cares about direct imports, but the
  1032  		// linker needs the whole dependency tree.
  1033  		all := actionList(a)
  1034  		all = all[:len(all)-1] // drop a
  1035  		if err := buildToolchain.ld(b, a.p, a.target, all, a.objpkg, objects); err != nil {
  1036  			return err
  1037  		}
  1038  	}
  1039  
  1040  	return nil
  1041  }
  1042  
  1043  // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
  1044  func (b *builder) getPkgConfigFlags(p *Package) (cflags, ldflags []string, err error) {
  1045  	if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
  1046  		var out []byte
  1047  		out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
  1048  		if err != nil {
  1049  			b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
  1050  			b.print(err.Error() + "\n")
  1051  			err = errPrintedOutput
  1052  			return
  1053  		}
  1054  		if len(out) > 0 {
  1055  			cflags = strings.Fields(string(out))
  1056  		}
  1057  		out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
  1058  		if err != nil {
  1059  			b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
  1060  			b.print(err.Error() + "\n")
  1061  			err = errPrintedOutput
  1062  			return
  1063  		}
  1064  		if len(out) > 0 {
  1065  			ldflags = strings.Fields(string(out))
  1066  		}
  1067  	}
  1068  	return
  1069  }
  1070  
  1071  // install is the action for installing a single package or executable.
  1072  func (b *builder) install(a *action) (err error) {
  1073  	defer func() {
  1074  		if err != nil && err != errPrintedOutput {
  1075  			err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err)
  1076  		}
  1077  	}()
  1078  	a1 := a.deps[0]
  1079  	perm := os.FileMode(0644)
  1080  	if a1.link {
  1081  		perm = 0755
  1082  	}
  1083  
  1084  	// make target directory
  1085  	dir, _ := filepath.Split(a.target)
  1086  	if dir != "" {
  1087  		if err := b.mkdir(dir); err != nil {
  1088  			return err
  1089  		}
  1090  	}
  1091  
  1092  	// remove object dir to keep the amount of
  1093  	// garbage down in a large build.  On an operating system
  1094  	// with aggressive buffering, cleaning incrementally like
  1095  	// this keeps the intermediate objects from hitting the disk.
  1096  	if !buildWork {
  1097  		defer os.RemoveAll(a1.objdir)
  1098  		defer os.Remove(a1.target)
  1099  	}
  1100  
  1101  	return b.moveOrCopyFile(a, a.target, a1.target, perm)
  1102  }
  1103  
  1104  // includeArgs returns the -I or -L directory list for access
  1105  // to the results of the list of actions.
  1106  func (b *builder) includeArgs(flag string, all []*action) []string {
  1107  	inc := []string{}
  1108  	incMap := map[string]bool{
  1109  		b.work:    true, // handled later
  1110  		gorootPkg: true,
  1111  		"":        true, // ignore empty strings
  1112  	}
  1113  
  1114  	// Look in the temporary space for results of test-specific actions.
  1115  	// This is the $WORK/my/package/_test directory for the
  1116  	// package being built, so there are few of these.
  1117  	for _, a1 := range all {
  1118  		if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
  1119  			incMap[dir] = true
  1120  			inc = append(inc, flag, dir)
  1121  		}
  1122  	}
  1123  
  1124  	// Also look in $WORK for any non-test packages that have
  1125  	// been built but not installed.
  1126  	inc = append(inc, flag, b.work)
  1127  
  1128  	// Finally, look in the installed package directories for each action.
  1129  	for _, a1 := range all {
  1130  		if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
  1131  			incMap[dir] = true
  1132  			if _, ok := buildToolchain.(gccgoToolchain); ok {
  1133  				dir = filepath.Join(dir, "gccgo_"+goos+"_"+goarch)
  1134  			} else {
  1135  				dir = filepath.Join(dir, goos+"_"+goarch)
  1136  				if buildContext.InstallSuffix != "" {
  1137  					dir += "_" + buildContext.InstallSuffix
  1138  				}
  1139  			}
  1140  			inc = append(inc, flag, dir)
  1141  		}
  1142  	}
  1143  
  1144  	return inc
  1145  }
  1146  
  1147  // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
  1148  func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode) error {
  1149  	if buildN {
  1150  		b.showcmd("", "mv %s %s", src, dst)
  1151  		return nil
  1152  	}
  1153  
  1154  	// If we can update the mode and rename to the dst, do it.
  1155  	// Otherwise fall back to standard copy.
  1156  	if err := os.Chmod(src, perm); err == nil {
  1157  		if err := os.Rename(src, dst); err == nil {
  1158  			if buildX {
  1159  				b.showcmd("", "mv %s %s", src, dst)
  1160  			}
  1161  			return nil
  1162  		}
  1163  	}
  1164  
  1165  	return b.copyFile(a, dst, src, perm)
  1166  }
  1167  
  1168  // copyFile is like 'cp src dst'.
  1169  func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode) error {
  1170  	if buildN || buildX {
  1171  		b.showcmd("", "cp %s %s", src, dst)
  1172  		if buildN {
  1173  			return nil
  1174  		}
  1175  	}
  1176  
  1177  	sf, err := os.Open(src)
  1178  	if err != nil {
  1179  		return err
  1180  	}
  1181  	defer sf.Close()
  1182  
  1183  	// Be careful about removing/overwriting dst.
  1184  	// Do not remove/overwrite if dst exists and is a directory
  1185  	// or a non-object file.
  1186  	if fi, err := os.Stat(dst); err == nil {
  1187  		if fi.IsDir() {
  1188  			return fmt.Errorf("build output %q already exists and is a directory", dst)
  1189  		}
  1190  		if !isObject(dst) {
  1191  			return fmt.Errorf("build output %q already exists and is not an object file", dst)
  1192  		}
  1193  	}
  1194  
  1195  	// On Windows, remove lingering ~ file from last attempt.
  1196  	if toolIsWindows {
  1197  		if _, err := os.Stat(dst + "~"); err == nil {
  1198  			os.Remove(dst + "~")
  1199  		}
  1200  	}
  1201  
  1202  	os.Remove(dst)
  1203  	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1204  	if err != nil && toolIsWindows {
  1205  		// Windows does not allow deletion of a binary file
  1206  		// while it is executing.  Try to move it out of the way.
  1207  		// If the move fails, which is likely, we'll try again the
  1208  		// next time we do an install of this binary.
  1209  		if err := os.Rename(dst, dst+"~"); err == nil {
  1210  			os.Remove(dst + "~")
  1211  		}
  1212  		df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1213  	}
  1214  	if err != nil {
  1215  		return err
  1216  	}
  1217  
  1218  	_, err = io.Copy(df, sf)
  1219  	df.Close()
  1220  	if err != nil {
  1221  		os.Remove(dst)
  1222  		return fmt.Errorf("copying %s to %s: %v", src, dst, err)
  1223  	}
  1224  	return nil
  1225  }
  1226  
  1227  // cover runs, in effect,
  1228  //	go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
  1229  func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
  1230  	return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
  1231  		tool("cover"),
  1232  		"-mode", a.p.coverMode,
  1233  		"-var", varName,
  1234  		"-o", dst,
  1235  		src)
  1236  }
  1237  
  1238  var objectMagic = [][]byte{
  1239  	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'},        // Package archive
  1240  	{'\x7F', 'E', 'L', 'F'},                          // ELF
  1241  	{0xFE, 0xED, 0xFA, 0xCE},                         // Mach-O big-endian 32-bit
  1242  	{0xFE, 0xED, 0xFA, 0xCF},                         // Mach-O big-endian 64-bit
  1243  	{0xCE, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 32-bit
  1244  	{0xCF, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 64-bit
  1245  	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x04, 0x00}, // PE (Windows) as generated by 6l/8l
  1246  	{0x00, 0x00, 0x01, 0xEB},                         // Plan 9 i386
  1247  	{0x00, 0x00, 0x8a, 0x97},                         // Plan 9 amd64
  1248  }
  1249  
  1250  func isObject(s string) bool {
  1251  	f, err := os.Open(s)
  1252  	if err != nil {
  1253  		return false
  1254  	}
  1255  	defer f.Close()
  1256  	buf := make([]byte, 64)
  1257  	io.ReadFull(f, buf)
  1258  	for _, magic := range objectMagic {
  1259  		if bytes.HasPrefix(buf, magic) {
  1260  			return true
  1261  		}
  1262  	}
  1263  	return false
  1264  }
  1265  
  1266  // fmtcmd formats a command in the manner of fmt.Sprintf but also:
  1267  //
  1268  //	If dir is non-empty and the script is not in dir right now,
  1269  //	fmtcmd inserts "cd dir\n" before the command.
  1270  //
  1271  //	fmtcmd replaces the value of b.work with $WORK.
  1272  //	fmtcmd replaces the value of goroot with $GOROOT.
  1273  //	fmtcmd replaces the value of b.gobin with $GOBIN.
  1274  //
  1275  //	fmtcmd replaces the name of the current directory with dot (.)
  1276  //	but only when it is at the beginning of a space-separated token.
  1277  //
  1278  func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
  1279  	cmd := fmt.Sprintf(format, args...)
  1280  	if dir != "" && dir != "/" {
  1281  		cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
  1282  		if b.scriptDir != dir {
  1283  			b.scriptDir = dir
  1284  			cmd = "cd " + dir + "\n" + cmd
  1285  		}
  1286  	}
  1287  	if b.work != "" {
  1288  		cmd = strings.Replace(cmd, b.work, "$WORK", -1)
  1289  	}
  1290  	return cmd
  1291  }
  1292  
  1293  // showcmd prints the given command to standard output
  1294  // for the implementation of -n or -x.
  1295  func (b *builder) showcmd(dir string, format string, args ...interface{}) {
  1296  	b.output.Lock()
  1297  	defer b.output.Unlock()
  1298  	b.print(b.fmtcmd(dir, format, args...) + "\n")
  1299  }
  1300  
  1301  // showOutput prints "# desc" followed by the given output.
  1302  // The output is expected to contain references to 'dir', usually
  1303  // the source directory for the package that has failed to build.
  1304  // showOutput rewrites mentions of dir with a relative path to dir
  1305  // when the relative path is shorter.  This is usually more pleasant.
  1306  // For example, if fmt doesn't compile and we are in src/html,
  1307  // the output is
  1308  //
  1309  //	$ go build
  1310  //	# fmt
  1311  //	../fmt/print.go:1090: undefined: asdf
  1312  //	$
  1313  //
  1314  // instead of
  1315  //
  1316  //	$ go build
  1317  //	# fmt
  1318  //	/usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
  1319  //	$
  1320  //
  1321  // showOutput also replaces references to the work directory with $WORK.
  1322  //
  1323  func (b *builder) showOutput(dir, desc, out string) {
  1324  	prefix := "# " + desc
  1325  	suffix := "\n" + out
  1326  	if reldir := shortPath(dir); reldir != dir {
  1327  		suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
  1328  		suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
  1329  	}
  1330  	suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
  1331  
  1332  	b.output.Lock()
  1333  	defer b.output.Unlock()
  1334  	b.print(prefix, suffix)
  1335  }
  1336  
  1337  // shortPath returns an absolute or relative name for path, whatever is shorter.
  1338  func shortPath(path string) string {
  1339  	if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
  1340  		return rel
  1341  	}
  1342  	return path
  1343  }
  1344  
  1345  // relPaths returns a copy of paths with absolute paths
  1346  // made relative to the current directory if they would be shorter.
  1347  func relPaths(paths []string) []string {
  1348  	var out []string
  1349  	pwd, _ := os.Getwd()
  1350  	for _, p := range paths {
  1351  		rel, err := filepath.Rel(pwd, p)
  1352  		if err == nil && len(rel) < len(p) {
  1353  			p = rel
  1354  		}
  1355  		out = append(out, p)
  1356  	}
  1357  	return out
  1358  }
  1359  
  1360  // errPrintedOutput is a special error indicating that a command failed
  1361  // but that it generated output as well, and that output has already
  1362  // been printed, so there's no point showing 'exit status 1' or whatever
  1363  // the wait status was.  The main executor, builder.do, knows not to
  1364  // print this error.
  1365  var errPrintedOutput = errors.New("already printed output - no need to show error")
  1366  
  1367  var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
  1368  var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
  1369  
  1370  // run runs the command given by cmdline in the directory dir.
  1371  // If the command fails, run prints information about the failure
  1372  // and returns a non-nil error.
  1373  func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
  1374  	out, err := b.runOut(dir, desc, env, cmdargs...)
  1375  	if len(out) > 0 {
  1376  		if desc == "" {
  1377  			desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
  1378  		}
  1379  		b.showOutput(dir, desc, b.processOutput(out))
  1380  		if err != nil {
  1381  			err = errPrintedOutput
  1382  		}
  1383  	}
  1384  	return err
  1385  }
  1386  
  1387  // processOutput prepares the output of runOut to be output to the console.
  1388  func (b *builder) processOutput(out []byte) string {
  1389  	if out[len(out)-1] != '\n' {
  1390  		out = append(out, '\n')
  1391  	}
  1392  	messages := string(out)
  1393  	// Fix up output referring to cgo-generated code to be more readable.
  1394  	// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
  1395  	// Replace *[100]_Ctype_foo with *[100]C.foo.
  1396  	// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
  1397  	if !buildX && cgoLine.MatchString(messages) {
  1398  		messages = cgoLine.ReplaceAllString(messages, "")
  1399  		messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
  1400  	}
  1401  	return messages
  1402  }
  1403  
  1404  // runOut runs the command given by cmdline in the directory dir.
  1405  // It returns the command output and any errors that occurred.
  1406  func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
  1407  	cmdline := stringList(cmdargs...)
  1408  	if buildN || buildX {
  1409  		var envcmdline string
  1410  		for i := range env {
  1411  			envcmdline += env[i]
  1412  			envcmdline += " "
  1413  		}
  1414  		envcmdline += joinUnambiguously(cmdline)
  1415  		b.showcmd(dir, "%s", envcmdline)
  1416  		if buildN {
  1417  			return nil, nil
  1418  		}
  1419  	}
  1420  
  1421  	nbusy := 0
  1422  	for {
  1423  		var buf bytes.Buffer
  1424  		cmd := exec.Command(cmdline[0], cmdline[1:]...)
  1425  		cmd.Stdout = &buf
  1426  		cmd.Stderr = &buf
  1427  		cmd.Dir = dir
  1428  		cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir))
  1429  		err := cmd.Run()
  1430  
  1431  		// cmd.Run will fail on Unix if some other process has the binary
  1432  		// we want to run open for writing.  This can happen here because
  1433  		// we build and install the cgo command and then run it.
  1434  		// If another command was kicked off while we were writing the
  1435  		// cgo binary, the child process for that command may be holding
  1436  		// a reference to the fd, keeping us from running exec.
  1437  		//
  1438  		// But, you might reasonably wonder, how can this happen?
  1439  		// The cgo fd, like all our fds, is close-on-exec, so that we need
  1440  		// not worry about other processes inheriting the fd accidentally.
  1441  		// The answer is that running a command is fork and exec.
  1442  		// A child forked while the cgo fd is open inherits that fd.
  1443  		// Until the child has called exec, it holds the fd open and the
  1444  		// kernel will not let us run cgo.  Even if the child were to close
  1445  		// the fd explicitly, it would still be open from the time of the fork
  1446  		// until the time of the explicit close, and the race would remain.
  1447  		//
  1448  		// On Unix systems, this results in ETXTBSY, which formats
  1449  		// as "text file busy".  Rather than hard-code specific error cases,
  1450  		// we just look for that string.  If this happens, sleep a little
  1451  		// and try again.  We let this happen three times, with increasing
  1452  		// sleep lengths: 100+200+400 ms = 0.7 seconds.
  1453  		//
  1454  		// An alternate solution might be to split the cmd.Run into
  1455  		// separate cmd.Start and cmd.Wait, and then use an RWLock
  1456  		// to make sure that copyFile only executes when no cmd.Start
  1457  		// call is in progress.  However, cmd.Start (really syscall.forkExec)
  1458  		// only guarantees that when it returns, the exec is committed to
  1459  		// happen and succeed.  It uses a close-on-exec file descriptor
  1460  		// itself to determine this, so we know that when cmd.Start returns,
  1461  		// at least one close-on-exec file descriptor has been closed.
  1462  		// However, we cannot be sure that all of them have been closed,
  1463  		// so the program might still encounter ETXTBSY even with such
  1464  		// an RWLock.  The race window would be smaller, perhaps, but not
  1465  		// guaranteed to be gone.
  1466  		//
  1467  		// Sleeping when we observe the race seems to be the most reliable
  1468  		// option we have.
  1469  		//
  1470  		// http://golang.org/issue/3001
  1471  		//
  1472  		if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
  1473  			time.Sleep(100 * time.Millisecond << uint(nbusy))
  1474  			nbusy++
  1475  			continue
  1476  		}
  1477  
  1478  		// err can be something like 'exit status 1'.
  1479  		// Add information about what program was running.
  1480  		// Note that if buf.Bytes() is non-empty, the caller usually
  1481  		// shows buf.Bytes() and does not print err at all, so the
  1482  		// prefix here does not make most output any more verbose.
  1483  		if err != nil {
  1484  			err = errors.New(cmdline[0] + ": " + err.Error())
  1485  		}
  1486  		return buf.Bytes(), err
  1487  	}
  1488  }
  1489  
  1490  // joinUnambiguously prints the slice, quoting where necessary to make the
  1491  // output unambiguous.
  1492  // TODO: See issue 5279. The printing of commands needs a complete redo.
  1493  func joinUnambiguously(a []string) string {
  1494  	var buf bytes.Buffer
  1495  	for i, s := range a {
  1496  		if i > 0 {
  1497  			buf.WriteByte(' ')
  1498  		}
  1499  		q := strconv.Quote(s)
  1500  		if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
  1501  			buf.WriteString(q)
  1502  		} else {
  1503  			buf.WriteString(s)
  1504  		}
  1505  	}
  1506  	return buf.String()
  1507  }
  1508  
  1509  // mkdir makes the named directory.
  1510  func (b *builder) mkdir(dir string) error {
  1511  	b.exec.Lock()
  1512  	defer b.exec.Unlock()
  1513  	// We can be a little aggressive about being
  1514  	// sure directories exist.  Skip repeated calls.
  1515  	if b.mkdirCache[dir] {
  1516  		return nil
  1517  	}
  1518  	b.mkdirCache[dir] = true
  1519  
  1520  	if buildN || buildX {
  1521  		b.showcmd("", "mkdir -p %s", dir)
  1522  		if buildN {
  1523  			return nil
  1524  		}
  1525  	}
  1526  
  1527  	if err := os.MkdirAll(dir, 0777); err != nil {
  1528  		return err
  1529  	}
  1530  	return nil
  1531  }
  1532  
  1533  // mkAbs returns an absolute path corresponding to
  1534  // evaluating f in the directory dir.
  1535  // We always pass absolute paths of source files so that
  1536  // the error messages will include the full path to a file
  1537  // in need of attention.
  1538  func mkAbs(dir, f string) string {
  1539  	// Leave absolute paths alone.
  1540  	// Also, during -n mode we use the pseudo-directory $WORK
  1541  	// instead of creating an actual work directory that won't be used.
  1542  	// Leave paths beginning with $WORK alone too.
  1543  	if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
  1544  		return f
  1545  	}
  1546  	return filepath.Join(dir, f)
  1547  }
  1548  
  1549  type toolchain interface {
  1550  	// gc runs the compiler in a specific directory on a set of files
  1551  	// and returns the name of the generated output file.
  1552  	// The compiler runs in the directory dir.
  1553  	gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
  1554  	// cc runs the toolchain's C compiler in a directory on a C file
  1555  	// to produce an output file.
  1556  	cc(b *builder, p *Package, objdir, ofile, cfile string) error
  1557  	// asm runs the assembler in a specific directory on a specific file
  1558  	// to generate the named output file.
  1559  	asm(b *builder, p *Package, obj, ofile, sfile string) error
  1560  	// pkgpath builds an appropriate path for a temporary package file.
  1561  	pkgpath(basedir string, p *Package) string
  1562  	// pack runs the archive packer in a specific directory to create
  1563  	// an archive from a set of object files.
  1564  	// typically it is run in the object directory.
  1565  	pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
  1566  	// ld runs the linker to create a package starting at mainpkg.
  1567  	ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error
  1568  
  1569  	compiler() string
  1570  	linker() string
  1571  }
  1572  
  1573  type noToolchain struct{}
  1574  
  1575  func noCompiler() error {
  1576  	log.Fatalf("unknown compiler %q", buildContext.Compiler)
  1577  	return nil
  1578  }
  1579  
  1580  func (noToolchain) compiler() string {
  1581  	noCompiler()
  1582  	return ""
  1583  }
  1584  
  1585  func (noToolchain) linker() string {
  1586  	noCompiler()
  1587  	return ""
  1588  }
  1589  
  1590  func (noToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
  1591  	return "", nil, noCompiler()
  1592  }
  1593  
  1594  func (noToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
  1595  	return noCompiler()
  1596  }
  1597  
  1598  func (noToolchain) pkgpath(basedir string, p *Package) string {
  1599  	noCompiler()
  1600  	return ""
  1601  }
  1602  
  1603  func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  1604  	return noCompiler()
  1605  }
  1606  
  1607  func (noToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
  1608  	return noCompiler()
  1609  }
  1610  
  1611  func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  1612  	return noCompiler()
  1613  }
  1614  
  1615  // The Go toolchain.
  1616  type gcToolchain struct{}
  1617  
  1618  func (gcToolchain) compiler() string {
  1619  	return tool(archChar + "g")
  1620  }
  1621  
  1622  func (gcToolchain) linker() string {
  1623  	return tool(archChar + "l")
  1624  }
  1625  
  1626  func (gcToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
  1627  	if archive != "" {
  1628  		ofile = archive
  1629  	} else {
  1630  		out := "_go_." + archChar
  1631  		ofile = obj + out
  1632  	}
  1633  
  1634  	gcargs := []string{"-p", p.ImportPath}
  1635  	if p.Standard && p.ImportPath == "runtime" {
  1636  		// runtime compiles with a special 6g flag to emit
  1637  		// additional reflect type data.
  1638  		gcargs = append(gcargs, "-+")
  1639  	}
  1640  
  1641  	// If we're giving the compiler the entire package (no C etc files), tell it that,
  1642  	// so that it can give good error messages about forward declarations.
  1643  	// Exceptions: a few standard packages have forward declarations for
  1644  	// pieces supplied behind-the-scenes by package runtime.
  1645  	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)
  1646  	if p.Standard {
  1647  		switch p.ImportPath {
  1648  		case "bytes", "net", "os", "runtime/pprof", "sync", "time":
  1649  			extFiles++
  1650  		}
  1651  	}
  1652  	if extFiles == 0 {
  1653  		gcargs = append(gcargs, "-complete")
  1654  	}
  1655  	if buildContext.InstallSuffix != "" {
  1656  		gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
  1657  	}
  1658  
  1659  	args := stringList(tool(archChar+"g"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
  1660  	if ofile == archive {
  1661  		args = append(args, "-pack")
  1662  	}
  1663  	for _, f := range gofiles {
  1664  		args = append(args, mkAbs(p.Dir, f))
  1665  	}
  1666  
  1667  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
  1668  	return ofile, output, err
  1669  }
  1670  
  1671  func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
  1672  	// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
  1673  	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
  1674  	sfile = mkAbs(p.Dir, sfile)
  1675  	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)
  1676  }
  1677  
  1678  func (gcToolchain) pkgpath(basedir string, p *Package) string {
  1679  	end := filepath.FromSlash(p.ImportPath + ".a")
  1680  	return filepath.Join(basedir, end)
  1681  }
  1682  
  1683  func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  1684  	var absOfiles []string
  1685  	for _, f := range ofiles {
  1686  		absOfiles = append(absOfiles, mkAbs(objDir, f))
  1687  	}
  1688  	cmd := "c"
  1689  	absAfile := mkAbs(objDir, afile)
  1690  	appending := false
  1691  	if _, err := os.Stat(absAfile); err == nil {
  1692  		appending = true
  1693  		cmd = "r"
  1694  	}
  1695  
  1696  	cmdline := stringList("pack", cmd, absAfile, absOfiles)
  1697  
  1698  	if appending {
  1699  		if buildN || buildX {
  1700  			b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
  1701  		}
  1702  		if buildN {
  1703  			return nil
  1704  		}
  1705  		if err := packInternal(b, absAfile, absOfiles); err != nil {
  1706  			b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
  1707  			return errPrintedOutput
  1708  		}
  1709  		return nil
  1710  	}
  1711  
  1712  	// Need actual pack.
  1713  	cmdline[0] = tool("pack")
  1714  	return b.run(p.Dir, p.ImportPath, nil, cmdline)
  1715  }
  1716  
  1717  func packInternal(b *builder, afile string, ofiles []string) error {
  1718  	dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
  1719  	if err != nil {
  1720  		return err
  1721  	}
  1722  	defer dst.Close() // only for error returns or panics
  1723  	w := bufio.NewWriter(dst)
  1724  
  1725  	for _, ofile := range ofiles {
  1726  		src, err := os.Open(ofile)
  1727  		if err != nil {
  1728  			return err
  1729  		}
  1730  		fi, err := src.Stat()
  1731  		if err != nil {
  1732  			src.Close()
  1733  			return err
  1734  		}
  1735  		// Note: Not using %-16.16s format because we care
  1736  		// about bytes, not runes.
  1737  		name := fi.Name()
  1738  		if len(name) > 16 {
  1739  			name = name[:16]
  1740  		} else {
  1741  			name += strings.Repeat(" ", 16-len(name))
  1742  		}
  1743  		size := fi.Size()
  1744  		fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
  1745  			name, 0, 0, 0, 0644, size)
  1746  		n, err := io.Copy(w, src)
  1747  		src.Close()
  1748  		if err == nil && n < size {
  1749  			err = io.ErrUnexpectedEOF
  1750  		} else if err == nil && n > size {
  1751  			err = fmt.Errorf("file larger than size reported by stat")
  1752  		}
  1753  		if err != nil {
  1754  			return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
  1755  		}
  1756  		if size&1 != 0 {
  1757  			w.WriteByte(0)
  1758  		}
  1759  	}
  1760  
  1761  	if err := w.Flush(); err != nil {
  1762  		return err
  1763  	}
  1764  	return dst.Close()
  1765  }
  1766  
  1767  func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
  1768  	importArgs := b.includeArgs("-L", allactions)
  1769  	cxx := len(p.CXXFiles) > 0
  1770  	for _, a := range allactions {
  1771  		if a.p != nil && len(a.p.CXXFiles) > 0 {
  1772  			cxx = true
  1773  		}
  1774  	}
  1775  	ldflags := buildLdflags
  1776  	// Limit slice capacity so that concurrent appends do not race on the shared array.
  1777  	ldflags = ldflags[:len(ldflags):len(ldflags)]
  1778  	if buildContext.InstallSuffix != "" {
  1779  		ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
  1780  	}
  1781  	if p.omitDWARF {
  1782  		ldflags = append(ldflags, "-w")
  1783  	}
  1784  
  1785  	// If the user has not specified the -extld option, then specify the
  1786  	// appropriate linker. In case of C++ code, use the compiler named
  1787  	// by the CXX environment variable or defaultCXX if CXX is not set.
  1788  	// Else, use the CC environment variable and defaultCC as fallback.
  1789  	extld := false
  1790  	for _, f := range ldflags {
  1791  		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
  1792  			extld = true
  1793  			break
  1794  		}
  1795  	}
  1796  	if !extld {
  1797  		var compiler []string
  1798  		if cxx {
  1799  			compiler = envList("CXX", defaultCXX)
  1800  		} else {
  1801  			compiler = envList("CC", defaultCC)
  1802  		}
  1803  		ldflags = append(ldflags, "-extld="+compiler[0])
  1804  		if len(compiler) > 1 {
  1805  			extldflags := false
  1806  			add := strings.Join(compiler[1:], " ")
  1807  			for i, f := range ldflags {
  1808  				if f == "-extldflags" && i+1 < len(ldflags) {
  1809  					ldflags[i+1] = add + " " + ldflags[i+1]
  1810  					extldflags = true
  1811  					break
  1812  				} else if strings.HasPrefix(f, "-extldflags=") {
  1813  					ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
  1814  					extldflags = true
  1815  					break
  1816  				}
  1817  			}
  1818  			if !extldflags {
  1819  				ldflags = append(ldflags, "-extldflags="+add)
  1820  			}
  1821  		}
  1822  	}
  1823  	return b.run(".", p.ImportPath, nil, tool(archChar+"l"), "-o", out, importArgs, ldflags, mainpkg)
  1824  }
  1825  
  1826  func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  1827  	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
  1828  	cfile = mkAbs(p.Dir, cfile)
  1829  	warn := []string{"-w"}
  1830  	if p.usesSwig() {
  1831  		// When using SWIG, this compiler is only used to
  1832  		// compile the C files generated by SWIG.
  1833  		// We don't want warnings.
  1834  		// See issue 9065 for details.
  1835  		warn = nil
  1836  	}
  1837  	args := stringList(tool(archChar+"c"), "-F", "-V", warn, "-trimpath", b.work, "-I", objdir, "-I", inc, "-o", ofile, buildCcflags, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, cfile)
  1838  	return b.run(p.Dir, p.ImportPath, nil, args)
  1839  }
  1840  
  1841  // The Gccgo toolchain.
  1842  type gccgoToolchain struct{}
  1843  
  1844  var gccgoName, gccgoBin string
  1845  
  1846  func init() {
  1847  	gccgoName = os.Getenv("GCCGO")
  1848  	if gccgoName == "" {
  1849  		gccgoName = "gccgo"
  1850  	}
  1851  	gccgoBin, _ = exec.LookPath(gccgoName)
  1852  }
  1853  
  1854  func (gccgoToolchain) compiler() string {
  1855  	return gccgoBin
  1856  }
  1857  
  1858  func (gccgoToolchain) linker() string {
  1859  	return gccgoBin
  1860  }
  1861  
  1862  func (gccgoToolchain) gc(b *builder, p *Package, archive, obj string, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
  1863  	out := "_go_.o"
  1864  	ofile = obj + out
  1865  	gcargs := []string{"-g"}
  1866  	gcargs = append(gcargs, b.gccArchArgs()...)
  1867  	if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  1868  		gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
  1869  	}
  1870  	if p.localPrefix != "" {
  1871  		gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
  1872  	}
  1873  	args := stringList(gccgoName, importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
  1874  	for _, f := range gofiles {
  1875  		args = append(args, mkAbs(p.Dir, f))
  1876  	}
  1877  
  1878  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
  1879  	return ofile, output, err
  1880  }
  1881  
  1882  func (gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
  1883  	sfile = mkAbs(p.Dir, sfile)
  1884  	defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
  1885  	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  1886  		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
  1887  	}
  1888  	defs = append(defs, b.gccArchArgs()...)
  1889  	return b.run(p.Dir, p.ImportPath, nil, gccgoName, "-I", obj, "-o", ofile, defs, sfile)
  1890  }
  1891  
  1892  func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
  1893  	end := filepath.FromSlash(p.ImportPath + ".a")
  1894  	afile := filepath.Join(basedir, end)
  1895  	// add "lib" to the final element
  1896  	return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
  1897  }
  1898  
  1899  func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  1900  	var absOfiles []string
  1901  	for _, f := range ofiles {
  1902  		absOfiles = append(absOfiles, mkAbs(objDir, f))
  1903  	}
  1904  	return b.run(p.Dir, p.ImportPath, nil, "ar", "cru", mkAbs(objDir, afile), absOfiles)
  1905  }
  1906  
  1907  func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
  1908  	// gccgo needs explicit linking with all package dependencies,
  1909  	// and all LDFLAGS from cgo dependencies.
  1910  	apackagesSeen := make(map[*Package]bool)
  1911  	afiles := []string{}
  1912  	ldflags := b.gccArchArgs()
  1913  	cgoldflags := []string{}
  1914  	usesCgo := false
  1915  	cxx := len(p.CXXFiles) > 0
  1916  	objc := len(p.MFiles) > 0
  1917  
  1918  	// Prefer the output of an install action to the output of a build action,
  1919  	// because the install action will delete the output of the build action.
  1920  	// Iterate over the list backward (reverse dependency order) so that we
  1921  	// always see the install before the build.
  1922  	for i := len(allactions) - 1; i >= 0; i-- {
  1923  		a := allactions[i]
  1924  		if !a.p.Standard {
  1925  			if a.p != nil && !apackagesSeen[a.p] {
  1926  				apackagesSeen[a.p] = true
  1927  				if a.p.fake {
  1928  					// move _test files to the top of the link order
  1929  					afiles = append([]string{a.target}, afiles...)
  1930  				} else {
  1931  					afiles = append(afiles, a.target)
  1932  				}
  1933  			}
  1934  		}
  1935  	}
  1936  
  1937  	for _, a := range allactions {
  1938  		if a.p != nil {
  1939  			cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
  1940  			if len(a.p.CgoFiles) > 0 {
  1941  				usesCgo = true
  1942  			}
  1943  			if a.p.usesSwig() {
  1944  				usesCgo = true
  1945  			}
  1946  			if len(a.p.CXXFiles) > 0 {
  1947  				cxx = true
  1948  			}
  1949  			if len(a.p.MFiles) > 0 {
  1950  				objc = true
  1951  			}
  1952  		}
  1953  	}
  1954  	ldflags = append(ldflags, afiles...)
  1955  	ldflags = append(ldflags, cgoldflags...)
  1956  	ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
  1957  	ldflags = append(ldflags, p.CgoLDFLAGS...)
  1958  	if usesCgo && goos == "linux" {
  1959  		ldflags = append(ldflags, "-Wl,-E")
  1960  	}
  1961  	if cxx {
  1962  		ldflags = append(ldflags, "-lstdc++")
  1963  	}
  1964  	if objc {
  1965  		ldflags = append(ldflags, "-lobjc")
  1966  	}
  1967  	return b.run(".", p.ImportPath, nil, gccgoName, "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
  1968  }
  1969  
  1970  func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  1971  	inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
  1972  	cfile = mkAbs(p.Dir, cfile)
  1973  	defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
  1974  	defs = append(defs, b.gccArchArgs()...)
  1975  	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  1976  		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
  1977  	}
  1978  	return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g",
  1979  		"-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
  1980  }
  1981  
  1982  func gccgoPkgpath(p *Package) string {
  1983  	if p.build.IsCommand() && !p.forceLibrary {
  1984  		return ""
  1985  	}
  1986  	return p.ImportPath
  1987  }
  1988  
  1989  func gccgoCleanPkgpath(p *Package) string {
  1990  	clean := func(r rune) rune {
  1991  		switch {
  1992  		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
  1993  			'0' <= r && r <= '9':
  1994  			return r
  1995  		}
  1996  		return '_'
  1997  	}
  1998  	return strings.Map(clean, gccgoPkgpath(p))
  1999  }
  2000  
  2001  // libgcc returns the filename for libgcc, as determined by invoking gcc with
  2002  // the -print-libgcc-file-name option.
  2003  func (b *builder) libgcc(p *Package) (string, error) {
  2004  	var buf bytes.Buffer
  2005  
  2006  	gccCmd := b.gccCmd(p.Dir)
  2007  
  2008  	prev := b.print
  2009  	if buildN {
  2010  		// In -n mode we temporarily swap out the builder's
  2011  		// print function to capture the command-line. This
  2012  		// let's us assign it to $LIBGCC and produce a valid
  2013  		// buildscript for cgo packages.
  2014  		b.print = func(a ...interface{}) (int, error) {
  2015  			return fmt.Fprint(&buf, a...)
  2016  		}
  2017  	}
  2018  	f, err := b.runOut(p.Dir, p.ImportPath, nil, gccCmd, "-print-libgcc-file-name")
  2019  	if err != nil {
  2020  		return "", fmt.Errorf("gcc -print-libgcc-file-name: %v (%s)", err, f)
  2021  	}
  2022  	if buildN {
  2023  		s := fmt.Sprintf("LIBGCC=$(%s)\n", buf.Next(buf.Len()-1))
  2024  		b.print = prev
  2025  		b.print(s)
  2026  		return "$LIBGCC", nil
  2027  	}
  2028  
  2029  	// The compiler might not be able to find libgcc, and in that case,
  2030  	// it will simply return "libgcc.a", which is of no use to us.
  2031  	if !filepath.IsAbs(string(f)) {
  2032  		return "", nil
  2033  	}
  2034  
  2035  	return strings.Trim(string(f), "\r\n"), nil
  2036  }
  2037  
  2038  // gcc runs the gcc C compiler to create an object from a single C file.
  2039  func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
  2040  	return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
  2041  }
  2042  
  2043  // gxx runs the g++ C++ compiler to create an object from a single C++ file.
  2044  func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
  2045  	return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
  2046  }
  2047  
  2048  // ccompile runs the given C or C++ compiler and creates an object from a single source file.
  2049  func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error {
  2050  	file = mkAbs(p.Dir, file)
  2051  	return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file)
  2052  }
  2053  
  2054  // gccld runs the gcc linker to create an executable from a set of object files.
  2055  func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
  2056  	var cmd []string
  2057  	if len(p.CXXFiles) > 0 {
  2058  		cmd = b.gxxCmd(p.Dir)
  2059  	} else {
  2060  		cmd = b.gccCmd(p.Dir)
  2061  	}
  2062  	return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
  2063  }
  2064  
  2065  // gccCmd returns a gcc command line prefix
  2066  // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
  2067  func (b *builder) gccCmd(objdir string) []string {
  2068  	return b.ccompilerCmd("CC", defaultCC, objdir)
  2069  }
  2070  
  2071  // gxxCmd returns a g++ command line prefix
  2072  // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
  2073  func (b *builder) gxxCmd(objdir string) []string {
  2074  	return b.ccompilerCmd("CXX", defaultCXX, objdir)
  2075  }
  2076  
  2077  // ccompilerCmd returns a command line prefix for the given environment
  2078  // variable and using the default command when the variable is empty.
  2079  func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
  2080  	// NOTE: env.go's mkEnv knows that the first three
  2081  	// strings returned are "gcc", "-I", objdir (and cuts them off).
  2082  
  2083  	compiler := envList(envvar, defcmd)
  2084  	a := []string{compiler[0], "-I", objdir}
  2085  	a = append(a, compiler[1:]...)
  2086  
  2087  	// Definitely want -fPIC but on Windows gcc complains
  2088  	// "-fPIC ignored for target (all code is position independent)"
  2089  	if goos != "windows" {
  2090  		a = append(a, "-fPIC")
  2091  	}
  2092  	a = append(a, b.gccArchArgs()...)
  2093  	// gcc-4.5 and beyond require explicit "-pthread" flag
  2094  	// for multithreading with pthread library.
  2095  	if buildContext.CgoEnabled {
  2096  		switch goos {
  2097  		case "windows":
  2098  			a = append(a, "-mthreads")
  2099  		default:
  2100  			a = append(a, "-pthread")
  2101  		}
  2102  	}
  2103  
  2104  	if strings.Contains(a[0], "clang") {
  2105  		// disable ASCII art in clang errors, if possible
  2106  		a = append(a, "-fno-caret-diagnostics")
  2107  		// clang is too smart about command-line arguments
  2108  		a = append(a, "-Qunused-arguments")
  2109  	}
  2110  
  2111  	// disable word wrapping in error messages
  2112  	a = append(a, "-fmessage-length=0")
  2113  
  2114  	// On OS X, some of the compilers behave as if -fno-common
  2115  	// is always set, and the Mach-O linker in 6l/8l assumes this.
  2116  	// See http://golang.org/issue/3253.
  2117  	if goos == "darwin" {
  2118  		a = append(a, "-fno-common")
  2119  	}
  2120  
  2121  	return a
  2122  }
  2123  
  2124  // gccNoPie returns the flag to use to request non-PIE. On systems
  2125  // with PIE (position independent executables) enabled by default,
  2126  // -no-pie must be passed when doing a partial link with -Wl,-r.
  2127  // But -no-pie is not supported by all compilers, and clang spells it -nopie.
  2128  func (b *builder) gccNoPie() string {
  2129  	if goos != "linux" {
  2130  		// On some BSD platforms, error messages from the
  2131  		// compiler make it to the console despite cmd.Std*
  2132  		// all being nil. As -no-pie is only required on linux
  2133  		// systems so far, we only test there.
  2134  		return ""
  2135  	}
  2136  	src := filepath.Join(b.work, "trivial.c")
  2137  	if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
  2138  		return ""
  2139  	}
  2140  	for _, nopie := range []string{"-no-pie", "-nopie"} {
  2141  		cmdArgs := b.gccCmd(b.work)
  2142  		cmdArgs = append(cmdArgs, nopie, "-c", "trivial.c")
  2143  		if buildN || buildX {
  2144  			b.showcmd(b.work, "%s", joinUnambiguously(cmdArgs))
  2145  			if buildN {
  2146  				return ""
  2147  			}
  2148  		}
  2149  		cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
  2150  		cmd.Dir = b.work
  2151  		cmd.Env = envForDir(cmd.Dir)
  2152  		err := cmd.Run()
  2153  		if err == nil {
  2154  			return nopie
  2155  		}
  2156  	}
  2157  	return ""
  2158  }
  2159  
  2160  // gccArchArgs returns arguments to pass to gcc based on the architecture.
  2161  func (b *builder) gccArchArgs() []string {
  2162  	switch archChar {
  2163  	case "8":
  2164  		return []string{"-m32"}
  2165  	case "6":
  2166  		return []string{"-m64"}
  2167  	case "5":
  2168  		return []string{"-marm"} // not thumb
  2169  	}
  2170  	return nil
  2171  }
  2172  
  2173  // envList returns the value of the given environment variable broken
  2174  // into fields, using the default value when the variable is empty.
  2175  func envList(key, def string) []string {
  2176  	v := os.Getenv(key)
  2177  	if v == "" {
  2178  		v = def
  2179  	}
  2180  	return strings.Fields(v)
  2181  }
  2182  
  2183  // Return the flags to use when invoking the C or C++ compilers, or cgo.
  2184  func (b *builder) cflags(p *Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) {
  2185  	var defaults string
  2186  	if def {
  2187  		defaults = "-g -O2"
  2188  	}
  2189  
  2190  	cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
  2191  	cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
  2192  	cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
  2193  	ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
  2194  	return
  2195  }
  2196  
  2197  var cgoRe = regexp.MustCompile(`[/\\:]`)
  2198  
  2199  var (
  2200  	cgoLibGccFile     string
  2201  	cgoLibGccErr      error
  2202  	cgoLibGccFileOnce sync.Once
  2203  )
  2204  
  2205  func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
  2206  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true)
  2207  	_, cgoexeCFLAGS, _, _ := b.cflags(p, false)
  2208  	cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
  2209  	cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
  2210  	// If we are compiling Objective-C code, then we need to link against libobjc
  2211  	if len(mfiles) > 0 {
  2212  		cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
  2213  	}
  2214  
  2215  	// Allows including _cgo_export.h from .[ch] files in the package.
  2216  	cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
  2217  
  2218  	// cgo
  2219  	// TODO: CGOPKGPATH, CGO_FLAGS?
  2220  	gofiles := []string{obj + "_cgo_gotypes.go"}
  2221  	cfiles := []string{"_cgo_main.c", "_cgo_export.c"}
  2222  	for _, fn := range p.CgoFiles {
  2223  		f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
  2224  		gofiles = append(gofiles, obj+f+"cgo1.go")
  2225  		cfiles = append(cfiles, f+"cgo2.c")
  2226  	}
  2227  	defunC := obj + "_cgo_defun.c"
  2228  
  2229  	cgoflags := []string{}
  2230  	// TODO: make cgo not depend on $GOARCH?
  2231  
  2232  	objExt := archChar
  2233  
  2234  	if p.Standard && p.ImportPath == "runtime/cgo" {
  2235  		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
  2236  	}
  2237  	if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/cgo") {
  2238  		cgoflags = append(cgoflags, "-import_syscall=false")
  2239  	}
  2240  
  2241  	// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
  2242  	var cgoenv []string
  2243  	if len(cgoLDFLAGS) > 0 {
  2244  		flags := make([]string, len(cgoLDFLAGS))
  2245  		for i, f := range cgoLDFLAGS {
  2246  			flags[i] = strconv.Quote(f)
  2247  		}
  2248  		cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
  2249  	}
  2250  
  2251  	if _, ok := buildToolchain.(gccgoToolchain); ok {
  2252  		cgoflags = append(cgoflags, "-gccgo")
  2253  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  2254  			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
  2255  		}
  2256  		objExt = "o"
  2257  	}
  2258  	if err := b.run(p.Dir, p.ImportPath, cgoenv, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, p.CgoFiles); err != nil {
  2259  		return nil, nil, err
  2260  	}
  2261  	outGo = append(outGo, gofiles...)
  2262  
  2263  	// cc _cgo_defun.c
  2264  	defunObj := obj + "_cgo_defun." + objExt
  2265  	if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
  2266  		return nil, nil, err
  2267  	}
  2268  	outObj = append(outObj, defunObj)
  2269  
  2270  	// gcc
  2271  	var linkobj []string
  2272  
  2273  	var bareLDFLAGS []string
  2274  	// filter out -lsomelib, -l somelib, *.{so,dll,dylib}, and (on Darwin) -framework X
  2275  	for i := 0; i < len(cgoLDFLAGS); i++ {
  2276  		f := cgoLDFLAGS[i]
  2277  		switch {
  2278  		// skip "-lc" or "-l somelib"
  2279  		case strings.HasPrefix(f, "-l"):
  2280  			if f == "-l" {
  2281  				i++
  2282  			}
  2283  		// skip "-framework X" on Darwin
  2284  		case goos == "darwin" && f == "-framework":
  2285  			i++
  2286  		// skip "*.{dylib,so,dll}"
  2287  		case strings.HasSuffix(f, ".dylib"),
  2288  			strings.HasSuffix(f, ".so"),
  2289  			strings.HasSuffix(f, ".dll"):
  2290  			continue
  2291  		// Remove any -fsanitize=foo flags.
  2292  		// Otherwise the compiler driver thinks that we are doing final link
  2293  		// and links sanitizer runtime into the object file. But we are not doing
  2294  		// the final link, we will link the resulting object file again. And
  2295  		// so the program ends up with two copies of sanitizer runtime.
  2296  		// See issue 8788 for details.
  2297  		case strings.HasPrefix(f, "-fsanitize="):
  2298  			continue
  2299  		default:
  2300  			bareLDFLAGS = append(bareLDFLAGS, f)
  2301  		}
  2302  	}
  2303  
  2304  	cgoLibGccFileOnce.Do(func() {
  2305  		cgoLibGccFile, cgoLibGccErr = b.libgcc(p)
  2306  	})
  2307  	if cgoLibGccFile == "" && cgoLibGccErr != nil {
  2308  		return nil, nil, err
  2309  	}
  2310  
  2311  	var staticLibs []string
  2312  	if goos == "windows" {
  2313  		// libmingw32 and libmingwex might also use libgcc, so libgcc must come last,
  2314  		// and they also have some inter-dependencies, so must use linker groups.
  2315  		staticLibs = []string{"-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group"}
  2316  	}
  2317  	if cgoLibGccFile != "" {
  2318  		staticLibs = append(staticLibs, cgoLibGccFile)
  2319  	}
  2320  
  2321  	cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
  2322  	for _, cfile := range cfiles {
  2323  		ofile := obj + cfile[:len(cfile)-1] + "o"
  2324  		if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
  2325  			return nil, nil, err
  2326  		}
  2327  		linkobj = append(linkobj, ofile)
  2328  		if !strings.HasSuffix(ofile, "_cgo_main.o") {
  2329  			outObj = append(outObj, ofile)
  2330  		}
  2331  	}
  2332  
  2333  	for _, file := range gccfiles {
  2334  		ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
  2335  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  2336  			return nil, nil, err
  2337  		}
  2338  		linkobj = append(linkobj, ofile)
  2339  		outObj = append(outObj, ofile)
  2340  	}
  2341  
  2342  	cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
  2343  	for _, file := range gxxfiles {
  2344  		// Append .o to the file, just in case the pkg has file.c and file.cpp
  2345  		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
  2346  		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
  2347  			return nil, nil, err
  2348  		}
  2349  		linkobj = append(linkobj, ofile)
  2350  		outObj = append(outObj, ofile)
  2351  	}
  2352  
  2353  	for _, file := range mfiles {
  2354  		// Append .o to the file, just in case the pkg has file.c and file.m
  2355  		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
  2356  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  2357  			return nil, nil, err
  2358  		}
  2359  		linkobj = append(linkobj, ofile)
  2360  		outObj = append(outObj, ofile)
  2361  	}
  2362  
  2363  	linkobj = append(linkobj, p.SysoFiles...)
  2364  	dynobj := obj + "_cgo_.o"
  2365  	pie := goarch == "arm" && (goos == "linux" || goos == "android")
  2366  	if pie { // we need to use -pie for Linux/ARM to get accurate imported sym
  2367  		cgoLDFLAGS = append(cgoLDFLAGS, "-pie")
  2368  	}
  2369  	if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil {
  2370  		return nil, nil, err
  2371  	}
  2372  	if pie { // but we don't need -pie for normal cgo programs
  2373  		cgoLDFLAGS = cgoLDFLAGS[0 : len(cgoLDFLAGS)-1]
  2374  	}
  2375  
  2376  	if _, ok := buildToolchain.(gccgoToolchain); ok {
  2377  		// we don't use dynimport when using gccgo.
  2378  		return outGo, outObj, nil
  2379  	}
  2380  
  2381  	// cgo -dynimport
  2382  	importC := obj + "_cgo_import.c"
  2383  	cgoflags = []string{}
  2384  	if p.Standard && p.ImportPath == "runtime/cgo" {
  2385  		cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
  2386  	}
  2387  	if err := b.run(p.Dir, p.ImportPath, nil, cgoExe, "-objdir", obj, "-dynimport", dynobj, "-dynout", importC, cgoflags); err != nil {
  2388  		return nil, nil, err
  2389  	}
  2390  
  2391  	// cc _cgo_import.ARCH
  2392  	importObj := obj + "_cgo_import." + objExt
  2393  	if err := buildToolchain.cc(b, p, obj, importObj, importC); err != nil {
  2394  		return nil, nil, err
  2395  	}
  2396  
  2397  	ofile := obj + "_all.o"
  2398  	var gccObjs, nonGccObjs []string
  2399  	for _, f := range outObj {
  2400  		if strings.HasSuffix(f, ".o") {
  2401  			gccObjs = append(gccObjs, f)
  2402  		} else {
  2403  			nonGccObjs = append(nonGccObjs, f)
  2404  		}
  2405  	}
  2406  	ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs)
  2407  
  2408  	if flag := b.gccNoPie(); flag != "" {
  2409  		ldflags = append(ldflags, flag)
  2410  	}
  2411  
  2412  	// Some systems, such as Ubuntu, always add --build-id to
  2413  	// every link, but we don't want a build ID since we are
  2414  	// producing an object file.  On some of those system a plain
  2415  	// -r (not -Wl,-r) will turn off --build-id, but clang 3.0
  2416  	// doesn't support a plain -r.  I don't know how to turn off
  2417  	// --build-id when using clang other than passing a trailing
  2418  	// --build-id=none.  So that is what we do, but only on
  2419  	// systems likely to support it, which is to say, systems that
  2420  	// normally use gold or the GNU linker.
  2421  	switch goos {
  2422  	case "android", "dragonfly", "linux", "netbsd":
  2423  		ldflags = append(ldflags, "-Wl,--build-id=none")
  2424  	}
  2425  
  2426  	if err := b.gccld(p, ofile, ldflags, gccObjs); err != nil {
  2427  		return nil, nil, err
  2428  	}
  2429  
  2430  	// NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
  2431  	// must be processed before the gcc-generated objects.
  2432  	// Put it first.  http://golang.org/issue/2601
  2433  	outObj = stringList(importObj, nonGccObjs, ofile)
  2434  
  2435  	return outGo, outObj, nil
  2436  }
  2437  
  2438  // Run SWIG on all SWIG input files.
  2439  // TODO: Don't build a shared library, once SWIG emits the necessary
  2440  // pragmas for external linking.
  2441  func (b *builder) swig(p *Package, obj string, pcCFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
  2442  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
  2443  	cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
  2444  	cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
  2445  
  2446  	for _, file := range gccfiles {
  2447  		ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
  2448  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  2449  			return nil, nil, err
  2450  		}
  2451  		outObj = append(outObj, ofile)
  2452  	}
  2453  
  2454  	for _, file := range gxxfiles {
  2455  		// Append .o to the file, just in case the pkg has file.c and file.cpp
  2456  		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
  2457  		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
  2458  			return nil, nil, err
  2459  		}
  2460  		outObj = append(outObj, ofile)
  2461  	}
  2462  
  2463  	for _, file := range mfiles {
  2464  		// Append .o to the file, just in case the pkg has file.c and file.cpp
  2465  		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
  2466  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  2467  			return nil, nil, err
  2468  		}
  2469  		outObj = append(outObj, ofile)
  2470  	}
  2471  
  2472  	if err := b.swigVersionCheck(); err != nil {
  2473  		return nil, nil, err
  2474  	}
  2475  
  2476  	intgosize, err := b.swigIntSize(obj)
  2477  	if err != nil {
  2478  		return nil, nil, err
  2479  	}
  2480  
  2481  	for _, f := range p.SwigFiles {
  2482  		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
  2483  		if err != nil {
  2484  			return nil, nil, err
  2485  		}
  2486  		if goFile != "" {
  2487  			outGo = append(outGo, goFile)
  2488  		}
  2489  		if objFile != "" {
  2490  			outObj = append(outObj, objFile)
  2491  		}
  2492  		if gccObjFile != "" {
  2493  			outObj = append(outObj, gccObjFile)
  2494  		}
  2495  	}
  2496  	for _, f := range p.SwigCXXFiles {
  2497  		goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
  2498  		if err != nil {
  2499  			return nil, nil, err
  2500  		}
  2501  		if goFile != "" {
  2502  			outGo = append(outGo, goFile)
  2503  		}
  2504  		if objFile != "" {
  2505  			outObj = append(outObj, objFile)
  2506  		}
  2507  		if gccObjFile != "" {
  2508  			outObj = append(outObj, gccObjFile)
  2509  		}
  2510  	}
  2511  	return outGo, outObj, nil
  2512  }
  2513  
  2514  // Make sure SWIG is new enough.
  2515  var (
  2516  	swigCheckOnce sync.Once
  2517  	swigCheck     error
  2518  )
  2519  
  2520  func (b *builder) swigDoVersionCheck() error {
  2521  	out, err := b.runOut("", "", nil, "swig", "-version")
  2522  	if err != nil {
  2523  		return err
  2524  	}
  2525  	re := regexp.MustCompile(`[vV]ersion +([\d])`)
  2526  	matches := re.FindSubmatch(out)
  2527  	if matches == nil {
  2528  		// Can't find version number; hope for the best.
  2529  		return nil
  2530  	}
  2531  	major, err := strconv.Atoi(string(matches[1]))
  2532  	if err != nil {
  2533  		// Can't find version number; hope for the best.
  2534  		return nil
  2535  	}
  2536  	if major < 3 {
  2537  		return errors.New("must have SWIG version >= 3.0")
  2538  	}
  2539  	return nil
  2540  }
  2541  
  2542  func (b *builder) swigVersionCheck() error {
  2543  	swigCheckOnce.Do(func() {
  2544  		swigCheck = b.swigDoVersionCheck()
  2545  	})
  2546  	return swigCheck
  2547  }
  2548  
  2549  // This code fails to build if sizeof(int) <= 32
  2550  const swigIntSizeCode = `
  2551  package main
  2552  const i int = 1 << 32
  2553  `
  2554  
  2555  // Determine the size of int on the target system for the -intgosize option
  2556  // of swig >= 2.0.9
  2557  func (b *builder) swigIntSize(obj string) (intsize string, err error) {
  2558  	if buildN {
  2559  		return "$INTBITS", nil
  2560  	}
  2561  	src := filepath.Join(b.work, "swig_intsize.go")
  2562  	if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0644); err != nil {
  2563  		return
  2564  	}
  2565  	srcs := []string{src}
  2566  
  2567  	p := goFilesPackage(srcs)
  2568  
  2569  	if _, _, e := buildToolchain.gc(b, p, "", obj, nil, srcs); e != nil {
  2570  		return "32", nil
  2571  	}
  2572  	return "64", nil
  2573  }
  2574  
  2575  // Run SWIG on one SWIG input file.
  2576  func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
  2577  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
  2578  	var cflags []string
  2579  	if cxx {
  2580  		cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
  2581  	} else {
  2582  		cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
  2583  	}
  2584  
  2585  	n := 5 // length of ".swig"
  2586  	if cxx {
  2587  		n = 8 // length of ".swigcxx"
  2588  	}
  2589  	base := file[:len(file)-n]
  2590  	goFile := base + ".go"
  2591  	cBase := base + "_gc."
  2592  	gccBase := base + "_wrap."
  2593  	gccExt := "c"
  2594  	if cxx {
  2595  		gccExt = "cxx"
  2596  	}
  2597  
  2598  	_, gccgo := buildToolchain.(gccgoToolchain)
  2599  
  2600  	// swig
  2601  	args := []string{
  2602  		"-go",
  2603  		"-intgosize", intgosize,
  2604  		"-module", base,
  2605  		"-o", obj + gccBase + gccExt,
  2606  		"-outdir", obj,
  2607  	}
  2608  
  2609  	for _, f := range cflags {
  2610  		if len(f) > 3 && f[:2] == "-I" {
  2611  			args = append(args, f)
  2612  		}
  2613  	}
  2614  
  2615  	if gccgo {
  2616  		args = append(args, "-gccgo")
  2617  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  2618  			args = append(args, "-go-pkgpath", pkgpath)
  2619  		}
  2620  	}
  2621  	if cxx {
  2622  		args = append(args, "-c++")
  2623  	}
  2624  
  2625  	if out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file); err != nil {
  2626  		if len(out) > 0 {
  2627  			if bytes.Contains(out, []byte("Unrecognized option -intgosize")) {
  2628  				return "", "", "", errors.New("must have SWIG version >= 3.0")
  2629  			}
  2630  			b.showOutput(p.Dir, p.ImportPath, b.processOutput(out))
  2631  			return "", "", "", errPrintedOutput
  2632  		}
  2633  		return "", "", "", err
  2634  	}
  2635  
  2636  	var cObj string
  2637  	if !gccgo {
  2638  		// cc
  2639  		cObj = obj + cBase + archChar
  2640  		if err := buildToolchain.cc(b, p, obj, cObj, obj+cBase+"c"); err != nil {
  2641  			return "", "", "", err
  2642  		}
  2643  	}
  2644  
  2645  	// gcc
  2646  	gccObj := obj + gccBase + "o"
  2647  	if !cxx {
  2648  		if err := b.gcc(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
  2649  			return "", "", "", err
  2650  		}
  2651  	} else {
  2652  		if err := b.gxx(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
  2653  			return "", "", "", err
  2654  		}
  2655  	}
  2656  
  2657  	return obj + goFile, cObj, gccObj, nil
  2658  }
  2659  
  2660  // An actionQueue is a priority queue of actions.
  2661  type actionQueue []*action
  2662  
  2663  // Implement heap.Interface
  2664  func (q *actionQueue) Len() int           { return len(*q) }
  2665  func (q *actionQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
  2666  func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
  2667  func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) }
  2668  func (q *actionQueue) Pop() interface{} {
  2669  	n := len(*q) - 1
  2670  	x := (*q)[n]
  2671  	*q = (*q)[:n]
  2672  	return x
  2673  }
  2674  
  2675  func (q *actionQueue) push(a *action) {
  2676  	heap.Push(q, a)
  2677  }
  2678  
  2679  func (q *actionQueue) pop() *action {
  2680  	return heap.Pop(q).(*action)
  2681  }
  2682  
  2683  func raceInit() {
  2684  	if !buildRace {
  2685  		return
  2686  	}
  2687  	if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" {
  2688  		fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
  2689  		os.Exit(2)
  2690  	}
  2691  	buildGcflags = append(buildGcflags, "-race")
  2692  	buildLdflags = append(buildLdflags, "-race")
  2693  	buildCcflags = append(buildCcflags, "-D", "RACE")
  2694  	if buildContext.InstallSuffix != "" {
  2695  		buildContext.InstallSuffix += "_"
  2696  	}
  2697  	buildContext.InstallSuffix += "race"
  2698  	buildContext.BuildTags = append(buildContext.BuildTags, "race")
  2699  }
  2700  
  2701  // defaultSuffix returns file extension used for command files in
  2702  // current os environment.
  2703  func defaultSuffix() string {
  2704  	switch runtime.GOOS {
  2705  	case "windows":
  2706  		return ".bat"
  2707  	case "plan9":
  2708  		return ".rc"
  2709  	default:
  2710  		return ".bash"
  2711  	}
  2712  }