github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/go/build.go (about)

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