github.com/jonasi/go@v0.0.0-20150930005915-e78e654c1de0/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  	"debug/elf"
    12  	"errors"
    13  	"flag"
    14  	"fmt"
    15  	"go/build"
    16  	"io"
    17  	"io/ioutil"
    18  	"log"
    19  	"os"
    20  	"os/exec"
    21  	"path"
    22  	"path/filepath"
    23  	"regexp"
    24  	"runtime"
    25  	"strconv"
    26  	"strings"
    27  	"sync"
    28  	"time"
    29  )
    30  
    31  var cmdBuild = &Command{
    32  	UsageLine: "build [-o output] [-i] [build flags] [packages]",
    33  	Short:     "compile packages and dependencies",
    34  	Long: `
    35  Build compiles the packages named by the import paths,
    36  along with their dependencies, but it does not install the results.
    37  
    38  If the arguments to build are a list of .go files, build treats
    39  them as a list of source files specifying a single package.
    40  
    41  When compiling a single main package, build writes
    42  the resulting executable to an output file named after
    43  the first source file ('go build ed.go rx.go' writes 'ed' or 'ed.exe')
    44  or the source code directory ('go build unix/sam' writes 'sam' or 'sam.exe').
    45  The '.exe' suffix is added when writing a Windows executable.
    46  
    47  When compiling multiple packages or a single non-main package,
    48  build compiles the packages but discards the resulting object,
    49  serving only as a check that the packages can be built.
    50  
    51  The -o flag, only allowed when compiling a single package,
    52  forces build to write the resulting executable or object
    53  to the named output file, instead of the default behavior described
    54  in the last two paragraphs.
    55  
    56  The -i flag installs the packages that are dependencies of the target.
    57  
    58  The build flags are shared by the build, clean, get, install, list, run,
    59  and test commands:
    60  
    61  	-a
    62  		force rebuilding of packages that are already up-to-date.
    63  	-n
    64  		print the commands but do not run them.
    65  	-p n
    66  		the number of builds that can be run in parallel.
    67  		The default is the number of CPUs available, except
    68  		on darwin/arm which defaults to 1.
    69  	-race
    70  		enable data race detection.
    71  		Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
    72  	-v
    73  		print the names of packages as they are compiled.
    74  	-work
    75  		print the name of the temporary work directory and
    76  		do not delete it when exiting.
    77  	-x
    78  		print the commands.
    79  
    80  	-asmflags 'flag list'
    81  		arguments to pass on each go tool asm invocation.
    82  	-buildmode mode
    83  		build mode to use. See 'go help buildmode' for more.
    84  	-compiler name
    85  		name of compiler to use, as in runtime.Compiler (gccgo or gc).
    86  	-gccgoflags 'arg list'
    87  		arguments to pass on each gccgo compiler/linker invocation.
    88  	-gcflags 'arg list'
    89  		arguments to pass on each go tool compile invocation.
    90  	-installsuffix suffix
    91  		a suffix to use in the name of the package installation directory,
    92  		in order to keep output separate from default builds.
    93  		If using the -race flag, the install suffix is automatically set to race
    94  		or, if set explicitly, has _race appended to it.  Using a -buildmode
    95  		option that requires non-default compile flags has a similar effect.
    96  	-ldflags 'flag list'
    97  		arguments to pass on each go tool link invocation.
    98  	-linkshared
    99  		link against shared libraries previously created with
   100  		-buildmode=shared
   101  	-pkgdir dir
   102  		install and load all packages from dir instead of the usual locations.
   103  		For example, when building with a non-standard configuration,
   104  		use -pkgdir to keep generated packages in a separate location.
   105  	-tags 'tag list'
   106  		a list of build tags to consider satisfied during the build.
   107  		For more information about build tags, see the description of
   108  		build constraints in the documentation for the go/build package.
   109  	-toolexec 'cmd args'
   110  		a program to use to invoke toolchain programs like vet and asm.
   111  		For example, instead of running asm, the go command will run
   112  		'cmd args /path/to/asm <arguments for asm>'.
   113  
   114  The list flags accept a space-separated list of strings. To embed spaces
   115  in an element in the list, surround it with either single or double quotes.
   116  
   117  For more about specifying packages, see 'go help packages'.
   118  For more about where packages and binaries are installed,
   119  run 'go help gopath'.
   120  For more about calling between Go and C/C++, run 'go help c'.
   121  
   122  Note: Build adheres to certain conventions such as those described
   123  by 'go help gopath'. Not all projects can follow these conventions,
   124  however. Installations that have their own conventions or that use
   125  a separate software build system may choose to use lower-level
   126  invocations such as 'go tool compile' and 'go tool link' to avoid
   127  some of the overheads and design decisions of the build tool.
   128  
   129  See also: go install, go get, go clean.
   130  	`,
   131  }
   132  
   133  func init() {
   134  	// break init cycle
   135  	cmdBuild.Run = runBuild
   136  	cmdInstall.Run = runInstall
   137  
   138  	cmdBuild.Flag.BoolVar(&buildI, "i", false, "")
   139  
   140  	addBuildFlags(cmdBuild)
   141  	addBuildFlags(cmdInstall)
   142  
   143  	if buildContext.GOOS == "darwin" {
   144  		switch buildContext.GOARCH {
   145  		case "arm", "arm64":
   146  			// darwin/arm cannot run multiple tests simultaneously.
   147  			// Parallelism is limited in go_darwin_arm_exec, but
   148  			// also needs to be limited here so go test std does not
   149  			// timeout tests that waiting to run.
   150  			buildP = 1
   151  		}
   152  	}
   153  }
   154  
   155  // Flags set by multiple commands.
   156  var buildA bool               // -a flag
   157  var buildN bool               // -n flag
   158  var buildP = runtime.NumCPU() // -p flag
   159  var buildV bool               // -v flag
   160  var buildX bool               // -x flag
   161  var buildI bool               // -i flag
   162  var buildO = cmdBuild.Flag.String("o", "", "output file")
   163  var buildWork bool           // -work flag
   164  var buildAsmflags []string   // -asmflags flag
   165  var buildGcflags []string    // -gcflags flag
   166  var buildLdflags []string    // -ldflags flag
   167  var buildGccgoflags []string // -gccgoflags flag
   168  var buildRace bool           // -race flag
   169  var buildToolExec []string   // -toolexec flag
   170  var buildBuildmode string    // -buildmode flag
   171  var buildLinkshared bool     // -linkshared flag
   172  var buildPkgdir string       // -pkgdir flag
   173  
   174  var buildContext = build.Default
   175  var buildToolchain toolchain = noToolchain{}
   176  var ldBuildmode string
   177  
   178  // buildCompiler implements flag.Var.
   179  // It implements Set by updating both
   180  // buildToolchain and buildContext.Compiler.
   181  type buildCompiler struct{}
   182  
   183  func (c buildCompiler) Set(value string) error {
   184  	switch value {
   185  	case "gc":
   186  		buildToolchain = gcToolchain{}
   187  	case "gccgo":
   188  		buildToolchain = gccgoToolchain{}
   189  	default:
   190  		return fmt.Errorf("unknown compiler %q", value)
   191  	}
   192  	buildContext.Compiler = value
   193  	return nil
   194  }
   195  
   196  func (c buildCompiler) String() string {
   197  	return buildContext.Compiler
   198  }
   199  
   200  func init() {
   201  	switch build.Default.Compiler {
   202  	case "gc":
   203  		buildToolchain = gcToolchain{}
   204  	case "gccgo":
   205  		buildToolchain = gccgoToolchain{}
   206  	}
   207  }
   208  
   209  // addBuildFlags adds the flags common to the build, clean, get,
   210  // install, list, run, and test commands.
   211  func addBuildFlags(cmd *Command) {
   212  	cmd.Flag.BoolVar(&buildA, "a", false, "")
   213  	cmd.Flag.BoolVar(&buildN, "n", false, "")
   214  	cmd.Flag.IntVar(&buildP, "p", buildP, "")
   215  	cmd.Flag.BoolVar(&buildV, "v", false, "")
   216  	cmd.Flag.BoolVar(&buildX, "x", false, "")
   217  
   218  	cmd.Flag.Var((*stringsFlag)(&buildAsmflags), "asmflags", "")
   219  	cmd.Flag.Var(buildCompiler{}, "compiler", "")
   220  	cmd.Flag.StringVar(&buildBuildmode, "buildmode", "default", "")
   221  	cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
   222  	cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
   223  	cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
   224  	cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
   225  	cmd.Flag.BoolVar(&buildLinkshared, "linkshared", false, "")
   226  	cmd.Flag.StringVar(&buildPkgdir, "pkgdir", "", "")
   227  	cmd.Flag.BoolVar(&buildRace, "race", false, "")
   228  	cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
   229  	cmd.Flag.Var((*stringsFlag)(&buildToolExec), "toolexec", "")
   230  	cmd.Flag.BoolVar(&buildWork, "work", false, "")
   231  }
   232  
   233  func addBuildFlagsNX(cmd *Command) {
   234  	cmd.Flag.BoolVar(&buildN, "n", false, "")
   235  	cmd.Flag.BoolVar(&buildX, "x", false, "")
   236  }
   237  
   238  func isSpaceByte(c byte) bool {
   239  	return c == ' ' || c == '\t' || c == '\n' || c == '\r'
   240  }
   241  
   242  // fileExtSplit expects a filename and returns the name
   243  // and ext (without the dot). If the file has no
   244  // extension, ext will be empty.
   245  func fileExtSplit(file string) (name, ext string) {
   246  	dotExt := filepath.Ext(file)
   247  	name = file[:len(file)-len(dotExt)]
   248  	if dotExt != "" {
   249  		ext = dotExt[1:]
   250  	}
   251  	return
   252  }
   253  
   254  type stringsFlag []string
   255  
   256  func (v *stringsFlag) Set(s string) error {
   257  	var err error
   258  	*v, err = splitQuotedFields(s)
   259  	if *v == nil {
   260  		*v = []string{}
   261  	}
   262  	return err
   263  }
   264  
   265  func splitQuotedFields(s string) ([]string, error) {
   266  	// Split fields allowing '' or "" around elements.
   267  	// Quotes further inside the string do not count.
   268  	var f []string
   269  	for len(s) > 0 {
   270  		for len(s) > 0 && isSpaceByte(s[0]) {
   271  			s = s[1:]
   272  		}
   273  		if len(s) == 0 {
   274  			break
   275  		}
   276  		// Accepted quoted string. No unescaping inside.
   277  		if s[0] == '"' || s[0] == '\'' {
   278  			quote := s[0]
   279  			s = s[1:]
   280  			i := 0
   281  			for i < len(s) && s[i] != quote {
   282  				i++
   283  			}
   284  			if i >= len(s) {
   285  				return nil, fmt.Errorf("unterminated %c string", quote)
   286  			}
   287  			f = append(f, s[:i])
   288  			s = s[i+1:]
   289  			continue
   290  		}
   291  		i := 0
   292  		for i < len(s) && !isSpaceByte(s[i]) {
   293  			i++
   294  		}
   295  		f = append(f, s[:i])
   296  		s = s[i:]
   297  	}
   298  	return f, nil
   299  }
   300  
   301  func (v *stringsFlag) String() string {
   302  	return "<stringsFlag>"
   303  }
   304  
   305  func pkgsMain(pkgs []*Package) (res []*Package) {
   306  	for _, p := range pkgs {
   307  		if p.Name == "main" {
   308  			res = append(res, p)
   309  		}
   310  	}
   311  	return res
   312  }
   313  
   314  func pkgsNotMain(pkgs []*Package) (res []*Package) {
   315  	for _, p := range pkgs {
   316  		if p.Name != "main" {
   317  			res = append(res, p)
   318  		}
   319  	}
   320  	return res
   321  }
   322  
   323  var pkgsFilter = func(pkgs []*Package) []*Package { return pkgs }
   324  
   325  func buildModeInit() {
   326  	_, gccgo := buildToolchain.(gccgoToolchain)
   327  	var codegenArg string
   328  	platform := goos + "/" + goarch
   329  	switch buildBuildmode {
   330  	case "archive":
   331  		pkgsFilter = pkgsNotMain
   332  	case "c-archive":
   333  		pkgsFilter = func(p []*Package) []*Package {
   334  			if len(p) != 1 || p[0].Name != "main" {
   335  				fatalf("-buildmode=c-archive requires exactly one main package")
   336  			}
   337  			return p
   338  		}
   339  		exeSuffix = ".a"
   340  		ldBuildmode = "c-archive"
   341  	case "c-shared":
   342  		pkgsFilter = pkgsMain
   343  		if gccgo {
   344  			codegenArg = "-fPIC"
   345  		} else {
   346  			switch platform {
   347  			case "linux/amd64", "linux/arm", "android/arm":
   348  				codegenArg = "-shared"
   349  			case "darwin/amd64":
   350  			default:
   351  				fatalf("-buildmode=c-shared not supported on %s\n", platform)
   352  			}
   353  		}
   354  		ldBuildmode = "c-shared"
   355  	case "default":
   356  		ldBuildmode = "exe"
   357  	case "exe":
   358  		pkgsFilter = pkgsMain
   359  		ldBuildmode = "exe"
   360  	case "shared":
   361  		pkgsFilter = pkgsNotMain
   362  		if gccgo {
   363  			codegenArg = "-fPIC"
   364  		} else {
   365  			switch platform {
   366  			case "linux/amd64":
   367  			default:
   368  				fatalf("-buildmode=shared not supported on %s\n", platform)
   369  			}
   370  			codegenArg = "-dynlink"
   371  		}
   372  		if *buildO != "" {
   373  			fatalf("-buildmode=shared and -o not supported together")
   374  		}
   375  		ldBuildmode = "shared"
   376  	default:
   377  		fatalf("buildmode=%s not supported", buildBuildmode)
   378  	}
   379  	if buildLinkshared {
   380  		if gccgo {
   381  			codegenArg = "-fPIC"
   382  		} else {
   383  			if platform != "linux/amd64" {
   384  				fmt.Fprintf(os.Stderr, "go %s: -linkshared is only supported on linux/amd64\n", flag.Args()[0])
   385  				os.Exit(2)
   386  			}
   387  			codegenArg = "-dynlink"
   388  			// TODO(mwhudson): remove -w when that gets fixed in linker.
   389  			buildLdflags = append(buildLdflags, "-linkshared", "-w")
   390  		}
   391  	}
   392  	if codegenArg != "" {
   393  		if gccgo {
   394  			buildGccgoflags = append(buildGccgoflags, codegenArg)
   395  		} else {
   396  			buildAsmflags = append(buildAsmflags, codegenArg)
   397  			buildGcflags = append(buildGcflags, codegenArg)
   398  		}
   399  		if buildContext.InstallSuffix != "" {
   400  			buildContext.InstallSuffix += "_"
   401  		}
   402  		buildContext.InstallSuffix += codegenArg[1:]
   403  	}
   404  }
   405  
   406  func runBuild(cmd *Command, args []string) {
   407  	raceInit()
   408  	buildModeInit()
   409  	var b builder
   410  	b.init()
   411  
   412  	pkgs := packagesForBuild(args)
   413  
   414  	if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" {
   415  		_, *buildO = path.Split(pkgs[0].ImportPath)
   416  		*buildO += exeSuffix
   417  	}
   418  
   419  	// sanity check some often mis-used options
   420  	switch buildContext.Compiler {
   421  	case "gccgo":
   422  		if len(buildGcflags) != 0 {
   423  			fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
   424  		}
   425  		if len(buildLdflags) != 0 {
   426  			fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
   427  		}
   428  	case "gc":
   429  		if len(buildGccgoflags) != 0 {
   430  			fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
   431  		}
   432  	}
   433  
   434  	depMode := modeBuild
   435  	if buildI {
   436  		depMode = modeInstall
   437  	}
   438  
   439  	if *buildO != "" {
   440  		if len(pkgs) > 1 {
   441  			fatalf("go build: cannot use -o with multiple packages")
   442  		} else if len(pkgs) == 0 {
   443  			fatalf("no packages to build")
   444  		}
   445  		p := pkgs[0]
   446  		p.target = *buildO
   447  		p.Stale = true // must build - not up to date
   448  		a := b.action(modeInstall, depMode, p)
   449  		b.do(a)
   450  		return
   451  	}
   452  
   453  	var a *action
   454  	if buildBuildmode == "shared" {
   455  		a = b.libaction(libname(args), pkgsFilter(packages(args)), modeBuild, depMode)
   456  	} else {
   457  		a = &action{}
   458  		for _, p := range pkgsFilter(packages(args)) {
   459  			a.deps = append(a.deps, b.action(modeBuild, depMode, p))
   460  		}
   461  	}
   462  	b.do(a)
   463  }
   464  
   465  var cmdInstall = &Command{
   466  	UsageLine: "install [build flags] [packages]",
   467  	Short:     "compile and install packages and dependencies",
   468  	Long: `
   469  Install compiles and installs the packages named by the import paths,
   470  along with their dependencies.
   471  
   472  For more about the build flags, see 'go help build'.
   473  For more about specifying packages, see 'go help packages'.
   474  
   475  See also: go build, go get, go clean.
   476  	`,
   477  }
   478  
   479  // libname returns the filename to use for the shared library when using
   480  // -buildmode=shared.  The rules we use are:
   481  //  1) Drop any trailing "/..."s if present
   482  //  2) Change / to -
   483  //  3) Join arguments with ,
   484  // So std -> libstd.so
   485  //    a b/... -> liba,b.so
   486  //    gopkg.in/tomb.v2 -> libgopkg.in-tomb.v2.so
   487  func libname(args []string) string {
   488  	var libname string
   489  	for _, arg := range args {
   490  		arg = strings.TrimSuffix(arg, "/...")
   491  		arg = strings.Replace(arg, "/", "-", -1)
   492  		if libname == "" {
   493  			libname = arg
   494  		} else {
   495  			libname += "," + arg
   496  		}
   497  	}
   498  	// TODO(mwhudson): Needs to change for platforms that use different naming
   499  	// conventions...
   500  	return "lib" + libname + ".so"
   501  }
   502  
   503  func runInstall(cmd *Command, args []string) {
   504  	raceInit()
   505  	buildModeInit()
   506  	pkgs := pkgsFilter(packagesForBuild(args))
   507  
   508  	for _, p := range pkgs {
   509  		if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
   510  			switch {
   511  			case p.gobinSubdir:
   512  				errorf("go install: cannot install cross-compiled binaries when GOBIN is set")
   513  			case p.cmdline:
   514  				errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
   515  			case p.ConflictDir != "":
   516  				errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
   517  			default:
   518  				errorf("go install: no install location for directory %s outside GOPATH\n"+
   519  					"\tFor more details see: go help gopath", p.Dir)
   520  			}
   521  		}
   522  	}
   523  	exitIfErrors()
   524  
   525  	var b builder
   526  	b.init()
   527  	var a *action
   528  	if buildBuildmode == "shared" {
   529  		a = b.libaction(libname(args), pkgs, modeInstall, modeInstall)
   530  	} else {
   531  		a = &action{}
   532  		var tools []*action
   533  		for _, p := range pkgs {
   534  			// If p is a tool, delay the installation until the end of the build.
   535  			// This avoids installing assemblers/compilers that are being executed
   536  			// by other steps in the build.
   537  			// cmd/cgo is handled specially in b.action, so that we can
   538  			// both build and use it in the same 'go install'.
   539  			action := b.action(modeInstall, modeInstall, p)
   540  			if goTools[p.ImportPath] == toTool && p.ImportPath != "cmd/cgo" {
   541  				a.deps = append(a.deps, action.deps...)
   542  				action.deps = append(action.deps, a)
   543  				tools = append(tools, action)
   544  				continue
   545  			}
   546  			a.deps = append(a.deps, action)
   547  		}
   548  		if len(tools) > 0 {
   549  			a = &action{
   550  				deps: tools,
   551  			}
   552  		}
   553  	}
   554  	b.do(a)
   555  	exitIfErrors()
   556  
   557  	// Success. If this command is 'go install' with no arguments
   558  	// and the current directory (the implicit argument) is a command,
   559  	// remove any leftover command binary from a previous 'go build'.
   560  	// The binary is installed; it's not needed here anymore.
   561  	// And worse it might be a stale copy, which you don't want to find
   562  	// instead of the installed one if $PATH contains dot.
   563  	// One way to view this behavior is that it is as if 'go install' first
   564  	// runs 'go build' and the moves the generated file to the install dir.
   565  	// See issue 9645.
   566  	if len(args) == 0 && len(pkgs) == 1 && pkgs[0].Name == "main" {
   567  		// Compute file 'go build' would have created.
   568  		// If it exists and is an executable file, remove it.
   569  		_, targ := filepath.Split(pkgs[0].ImportPath)
   570  		targ += exeSuffix
   571  		if filepath.Join(pkgs[0].Dir, targ) != pkgs[0].Target { // maybe $GOBIN is the current directory
   572  			fi, err := os.Stat(targ)
   573  			if err == nil {
   574  				m := fi.Mode()
   575  				if m.IsRegular() {
   576  					if m&0111 != 0 || goos == "windows" { // windows never sets executable bit
   577  						os.Remove(targ)
   578  					}
   579  				}
   580  			}
   581  		}
   582  	}
   583  }
   584  
   585  // Global build parameters (used during package load)
   586  var (
   587  	goarch    string
   588  	goos      string
   589  	exeSuffix string
   590  )
   591  
   592  func init() {
   593  	goarch = buildContext.GOARCH
   594  	goos = buildContext.GOOS
   595  	if goos == "windows" {
   596  		exeSuffix = ".exe"
   597  	}
   598  }
   599  
   600  // A builder holds global state about a build.
   601  // It does not hold per-package state, because we
   602  // build packages in parallel, and the builder is shared.
   603  type builder struct {
   604  	work        string               // the temporary work directory (ends in filepath.Separator)
   605  	actionCache map[cacheKey]*action // a cache of already-constructed actions
   606  	mkdirCache  map[string]bool      // a cache of created directories
   607  	print       func(args ...interface{}) (int, error)
   608  
   609  	output    sync.Mutex
   610  	scriptDir string // current directory in printed script
   611  
   612  	exec      sync.Mutex
   613  	readySema chan bool
   614  	ready     actionQueue
   615  }
   616  
   617  // An action represents a single action in the action graph.
   618  type action struct {
   619  	p          *Package      // the package this action works on
   620  	deps       []*action     // actions that must happen before this one
   621  	triggers   []*action     // inverse of deps
   622  	cgo        *action       // action for cgo binary if needed
   623  	args       []string      // additional args for runProgram
   624  	testOutput *bytes.Buffer // test output buffer
   625  
   626  	f          func(*builder, *action) error // the action itself (nil = no-op)
   627  	ignoreFail bool                          // whether to run f even if dependencies fail
   628  
   629  	// Generated files, directories.
   630  	link   bool   // target is executable, not just package
   631  	pkgdir string // the -I or -L argument to use when importing this package
   632  	objdir string // directory for intermediate objects
   633  	objpkg string // the intermediate package .a file created during the action
   634  	target string // goal of the action: the created package or executable
   635  
   636  	// Execution state.
   637  	pending  int  // number of deps yet to complete
   638  	priority int  // relative execution priority
   639  	failed   bool // whether the action failed
   640  }
   641  
   642  // cacheKey is the key for the action cache.
   643  type cacheKey struct {
   644  	mode  buildMode
   645  	p     *Package
   646  	shlib string
   647  }
   648  
   649  // buildMode specifies the build mode:
   650  // are we just building things or also installing the results?
   651  type buildMode int
   652  
   653  const (
   654  	modeBuild buildMode = iota
   655  	modeInstall
   656  )
   657  
   658  var (
   659  	goroot    = filepath.Clean(runtime.GOROOT())
   660  	gobin     = os.Getenv("GOBIN")
   661  	gorootBin = filepath.Join(goroot, "bin")
   662  	gorootPkg = filepath.Join(goroot, "pkg")
   663  	gorootSrc = filepath.Join(goroot, "src")
   664  )
   665  
   666  func (b *builder) init() {
   667  	var err error
   668  	b.print = func(a ...interface{}) (int, error) {
   669  		return fmt.Fprint(os.Stderr, a...)
   670  	}
   671  	b.actionCache = make(map[cacheKey]*action)
   672  	b.mkdirCache = make(map[string]bool)
   673  
   674  	if buildN {
   675  		b.work = "$WORK"
   676  	} else {
   677  		b.work, err = ioutil.TempDir("", "go-build")
   678  		if err != nil {
   679  			fatalf("%s", err)
   680  		}
   681  		if buildX || buildWork {
   682  			fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
   683  		}
   684  		if !buildWork {
   685  			workdir := b.work
   686  			atexit(func() { os.RemoveAll(workdir) })
   687  		}
   688  	}
   689  }
   690  
   691  // goFilesPackage creates a package for building a collection of Go files
   692  // (typically named on the command line).  The target is named p.a for
   693  // package p or named after the first Go file for package main.
   694  func goFilesPackage(gofiles []string) *Package {
   695  	// TODO: Remove this restriction.
   696  	for _, f := range gofiles {
   697  		if !strings.HasSuffix(f, ".go") {
   698  			fatalf("named files must be .go files")
   699  		}
   700  	}
   701  
   702  	var stk importStack
   703  	ctxt := buildContext
   704  	ctxt.UseAllFiles = true
   705  
   706  	// Synthesize fake "directory" that only shows the named files,
   707  	// to make it look like this is a standard package or
   708  	// command directory.  So that local imports resolve
   709  	// consistently, the files must all be in the same directory.
   710  	var dirent []os.FileInfo
   711  	var dir string
   712  	for _, file := range gofiles {
   713  		fi, err := os.Stat(file)
   714  		if err != nil {
   715  			fatalf("%s", err)
   716  		}
   717  		if fi.IsDir() {
   718  			fatalf("%s is a directory, should be a Go file", file)
   719  		}
   720  		dir1, _ := filepath.Split(file)
   721  		if dir1 == "" {
   722  			dir1 = "./"
   723  		}
   724  		if dir == "" {
   725  			dir = dir1
   726  		} else if dir != dir1 {
   727  			fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
   728  		}
   729  		dirent = append(dirent, fi)
   730  	}
   731  	ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
   732  
   733  	var err error
   734  	if dir == "" {
   735  		dir = cwd
   736  	}
   737  	dir, err = filepath.Abs(dir)
   738  	if err != nil {
   739  		fatalf("%s", err)
   740  	}
   741  
   742  	bp, err := ctxt.ImportDir(dir, 0)
   743  	pkg := new(Package)
   744  	pkg.local = true
   745  	pkg.cmdline = true
   746  	pkg.load(&stk, bp, err)
   747  	pkg.localPrefix = dirToImportPath(dir)
   748  	pkg.ImportPath = "command-line-arguments"
   749  	pkg.target = ""
   750  
   751  	if pkg.Name == "main" {
   752  		_, elem := filepath.Split(gofiles[0])
   753  		exe := elem[:len(elem)-len(".go")] + exeSuffix
   754  		if *buildO == "" {
   755  			*buildO = exe
   756  		}
   757  		if gobin != "" {
   758  			pkg.target = filepath.Join(gobin, exe)
   759  		}
   760  	}
   761  
   762  	pkg.Target = pkg.target
   763  	pkg.Stale = true
   764  
   765  	computeStale(pkg)
   766  	return pkg
   767  }
   768  
   769  // readpkglist returns the list of packages that were built into the shared library
   770  // at shlibpath. For the native toolchain this list is stored, newline separated, in
   771  // an ELF note with name "Go\x00\x00" and type 1. For GCCGO it is extracted from the
   772  // .go_export section.
   773  func readpkglist(shlibpath string) (pkgs []*Package) {
   774  	var stk importStack
   775  	if _, gccgo := buildToolchain.(gccgoToolchain); gccgo {
   776  		f, _ := elf.Open(shlibpath)
   777  		sect := f.Section(".go_export")
   778  		data, _ := sect.Data()
   779  		scanner := bufio.NewScanner(bytes.NewBuffer(data))
   780  		for scanner.Scan() {
   781  			t := scanner.Text()
   782  			if strings.HasPrefix(t, "pkgpath ") {
   783  				t = strings.TrimPrefix(t, "pkgpath ")
   784  				t = strings.TrimSuffix(t, ";")
   785  				pkgs = append(pkgs, loadPackage(t, &stk))
   786  			}
   787  		}
   788  	} else {
   789  		pkglistbytes, err := readELFNote(shlibpath, "Go\x00\x00", 1)
   790  		if err != nil {
   791  			fatalf("readELFNote failed: %v", err)
   792  		}
   793  		scanner := bufio.NewScanner(bytes.NewBuffer(pkglistbytes))
   794  		for scanner.Scan() {
   795  			t := scanner.Text()
   796  			pkgs = append(pkgs, loadPackage(t, &stk))
   797  		}
   798  	}
   799  	return
   800  }
   801  
   802  // action returns the action for applying the given operation (mode) to the package.
   803  // depMode is the action to use when building dependencies.
   804  // action never looks for p in a shared library.
   805  func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action {
   806  	return b.action1(mode, depMode, p, false)
   807  }
   808  
   809  // action1 returns the action for applying the given operation (mode) to the package.
   810  // depMode is the action to use when building dependencies.
   811  // action1 will look for p in a shared library if lookshared is true.
   812  func (b *builder) action1(mode buildMode, depMode buildMode, p *Package, lookshared bool) *action {
   813  	shlib := ""
   814  	if lookshared {
   815  		shlib = p.Shlib
   816  	}
   817  	key := cacheKey{mode, p, shlib}
   818  
   819  	a := b.actionCache[key]
   820  	if a != nil {
   821  		return a
   822  	}
   823  	if shlib != "" {
   824  		key2 := cacheKey{modeInstall, nil, shlib}
   825  		a = b.actionCache[key2]
   826  		if a != nil {
   827  			b.actionCache[key] = a
   828  			return a
   829  		}
   830  		pkgs := readpkglist(shlib)
   831  		a = b.libaction(filepath.Base(shlib), pkgs, modeInstall, depMode)
   832  		b.actionCache[key2] = a
   833  		b.actionCache[key] = a
   834  		return a
   835  	}
   836  
   837  	a = &action{p: p, pkgdir: p.build.PkgRoot}
   838  	if p.pkgdir != "" { // overrides p.t
   839  		a.pkgdir = p.pkgdir
   840  	}
   841  	b.actionCache[key] = a
   842  
   843  	for _, p1 := range p.imports {
   844  		ls := buildLinkshared
   845  		// If p1 is part of the same shared library as p, we need the action
   846  		// that builds p here, not the shared libary or we get action loops.
   847  		if p1.Shlib == p.Shlib {
   848  			ls = false
   849  		}
   850  		a.deps = append(a.deps, b.action1(depMode, depMode, p1, ls))
   851  	}
   852  
   853  	// If we are not doing a cross-build, then record the binary we'll
   854  	// generate for cgo as a dependency of the build of any package
   855  	// using cgo, to make sure we do not overwrite the binary while
   856  	// a package is using it.  If this is a cross-build, then the cgo we
   857  	// are writing is not the cgo we need to use.
   858  	if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace {
   859  		if (len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo") && !buildLinkshared && buildBuildmode != "shared" {
   860  			var stk importStack
   861  			p1 := loadPackage("cmd/cgo", &stk)
   862  			if p1.Error != nil {
   863  				fatalf("load cmd/cgo: %v", p1.Error)
   864  			}
   865  			a.cgo = b.action(depMode, depMode, p1)
   866  			a.deps = append(a.deps, a.cgo)
   867  		}
   868  	}
   869  
   870  	if p.Standard {
   871  		switch p.ImportPath {
   872  		case "builtin", "unsafe":
   873  			// Fake packages - nothing to build.
   874  			return a
   875  		}
   876  		// gccgo standard library is "fake" too.
   877  		if _, ok := buildToolchain.(gccgoToolchain); ok {
   878  			// the target name is needed for cgo.
   879  			a.target = p.target
   880  			return a
   881  		}
   882  	}
   883  
   884  	if !p.Stale && p.target != "" {
   885  		// p.Stale==false implies that p.target is up-to-date.
   886  		// Record target name for use by actions depending on this one.
   887  		a.target = p.target
   888  		return a
   889  	}
   890  
   891  	if p.local && p.target == "" {
   892  		// Imported via local path.  No permanent target.
   893  		mode = modeBuild
   894  	}
   895  	work := p.pkgdir
   896  	if work == "" {
   897  		work = b.work
   898  	}
   899  	a.objdir = filepath.Join(work, a.p.ImportPath, "_obj") + string(filepath.Separator)
   900  	a.objpkg = buildToolchain.pkgpath(work, a.p)
   901  	a.link = p.Name == "main"
   902  
   903  	switch mode {
   904  	case modeInstall:
   905  		a.f = (*builder).install
   906  		a.deps = []*action{b.action1(modeBuild, depMode, p, lookshared)}
   907  		a.target = a.p.target
   908  
   909  		// Install header for cgo in c-archive and c-shared modes.
   910  		if p.usesCgo() && (buildBuildmode == "c-archive" || buildBuildmode == "c-shared") {
   911  			ah := &action{
   912  				p:      a.p,
   913  				deps:   []*action{a.deps[0]},
   914  				f:      (*builder).installHeader,
   915  				pkgdir: a.pkgdir,
   916  				objdir: a.objdir,
   917  				target: a.target[:len(a.target)-len(filepath.Ext(a.target))] + ".h",
   918  			}
   919  			a.deps = append(a.deps, ah)
   920  		}
   921  
   922  	case modeBuild:
   923  		a.f = (*builder).build
   924  		a.target = a.objpkg
   925  		if a.link {
   926  			// An executable file. (This is the name of a temporary file.)
   927  			// Because we run the temporary file in 'go run' and 'go test',
   928  			// the name will show up in ps listings. If the caller has specified
   929  			// a name, use that instead of a.out. The binary is generated
   930  			// in an otherwise empty subdirectory named exe to avoid
   931  			// naming conflicts.  The only possible conflict is if we were
   932  			// to create a top-level package named exe.
   933  			name := "a.out"
   934  			if p.exeName != "" {
   935  				name = p.exeName
   936  			} else if goos == "darwin" && buildBuildmode == "c-shared" && p.target != "" {
   937  				// On OS X, the linker output name gets recorded in the
   938  				// shared library's LC_ID_DYLIB load command.
   939  				// The code invoking the linker knows to pass only the final
   940  				// path element. Arrange that the path element matches what
   941  				// we'll install it as; otherwise the library is only loadable as "a.out".
   942  				_, name = filepath.Split(p.target)
   943  			}
   944  			a.target = a.objdir + filepath.Join("exe", name) + exeSuffix
   945  		}
   946  	}
   947  
   948  	return a
   949  }
   950  
   951  func (b *builder) libaction(libname string, pkgs []*Package, mode, depMode buildMode) *action {
   952  	a := &action{}
   953  	if mode == modeBuild {
   954  		a.f = (*builder).linkShared
   955  		a.target = filepath.Join(b.work, libname)
   956  		for _, p := range pkgs {
   957  			if p.target == "" {
   958  				continue
   959  			}
   960  			a.deps = append(a.deps, b.action(depMode, depMode, p))
   961  		}
   962  	} else if mode == modeInstall {
   963  		// Currently build mode shared forces external linking mode, and
   964  		// external linking mode forces an import of runtime/cgo. So if it
   965  		// was not passed on the command line and it is not present in
   966  		// another shared library, add it here.
   967  		seencgo := false
   968  		_, gccgo := buildToolchain.(gccgoToolchain)
   969  		if !gccgo {
   970  			for _, p := range pkgs {
   971  				seencgo = seencgo || (p.Standard && p.ImportPath == "runtime/cgo")
   972  			}
   973  			if !seencgo {
   974  				var stk importStack
   975  				p := loadPackage("runtime/cgo", &stk)
   976  				if p.Error != nil {
   977  					fatalf("load runtime/cgo: %v", p.Error)
   978  				}
   979  				computeStale(p)
   980  				// If runtime/cgo is in another shared library, then that's
   981  				// also the shared library that contains runtime, so
   982  				// something will depend on it and so runtime/cgo's staleness
   983  				// will be checked when processing that library.
   984  				if p.Shlib == "" || p.Shlib == libname {
   985  					pkgs = append([]*Package{}, pkgs...)
   986  					pkgs = append(pkgs, p)
   987  				}
   988  			}
   989  		}
   990  
   991  		// Figure out where the library will go.
   992  		var libdir string
   993  		for _, p := range pkgs {
   994  			plibdir := p.build.PkgTargetRoot
   995  			if gccgo {
   996  				plibdir = filepath.Join(plibdir, "shlibs")
   997  			}
   998  			if libdir == "" {
   999  				libdir = plibdir
  1000  			} else if libdir != plibdir {
  1001  				fatalf("multiple roots %s & %s", libdir, plibdir)
  1002  			}
  1003  		}
  1004  		a.target = filepath.Join(libdir, libname)
  1005  
  1006  		// Now we can check whether we need to rebuild it.
  1007  		stale := false
  1008  		var built time.Time
  1009  		if fi, err := os.Stat(a.target); err == nil {
  1010  			built = fi.ModTime()
  1011  		}
  1012  		for _, p := range pkgs {
  1013  			if p.target == "" {
  1014  				continue
  1015  			}
  1016  			stale = stale || p.Stale
  1017  			lstat, err := os.Stat(p.target)
  1018  			if err != nil || lstat.ModTime().After(built) {
  1019  				stale = true
  1020  			}
  1021  			a.deps = append(a.deps, b.action(depMode, depMode, p))
  1022  		}
  1023  
  1024  		if stale {
  1025  			a.f = (*builder).install
  1026  			buildAction := b.libaction(libname, pkgs, modeBuild, depMode)
  1027  			a.deps = []*action{buildAction}
  1028  			for _, p := range pkgs {
  1029  				if p.target == "" {
  1030  					continue
  1031  				}
  1032  				shlibnameaction := &action{}
  1033  				shlibnameaction.f = (*builder).installShlibname
  1034  				shlibnameaction.target = p.target[:len(p.target)-2] + ".shlibname"
  1035  				a.deps = append(a.deps, shlibnameaction)
  1036  				shlibnameaction.deps = append(shlibnameaction.deps, buildAction)
  1037  			}
  1038  		}
  1039  	} else {
  1040  		fatalf("unregonized mode %v", mode)
  1041  	}
  1042  	return a
  1043  }
  1044  
  1045  // actionList returns the list of actions in the dag rooted at root
  1046  // as visited in a depth-first post-order traversal.
  1047  func actionList(root *action) []*action {
  1048  	seen := map[*action]bool{}
  1049  	all := []*action{}
  1050  	var walk func(*action)
  1051  	walk = func(a *action) {
  1052  		if seen[a] {
  1053  			return
  1054  		}
  1055  		seen[a] = true
  1056  		for _, a1 := range a.deps {
  1057  			walk(a1)
  1058  		}
  1059  		all = append(all, a)
  1060  	}
  1061  	walk(root)
  1062  	return all
  1063  }
  1064  
  1065  // allArchiveActions returns a list of the archive dependencies of root.
  1066  // This is needed because if package p depends on package q that is in libr.so, the
  1067  // action graph looks like p->libr.so->q and so just scanning through p's
  1068  // dependencies does not find the import dir for q.
  1069  func allArchiveActions(root *action) []*action {
  1070  	seen := map[*action]bool{}
  1071  	r := []*action{}
  1072  	var walk func(*action)
  1073  	walk = func(a *action) {
  1074  		if seen[a] {
  1075  			return
  1076  		}
  1077  		seen[a] = true
  1078  		if strings.HasSuffix(a.target, ".so") || a == root {
  1079  			for _, a1 := range a.deps {
  1080  				walk(a1)
  1081  			}
  1082  		} else if strings.HasSuffix(a.target, ".a") {
  1083  			r = append(r, a)
  1084  		}
  1085  	}
  1086  	walk(root)
  1087  	return r
  1088  }
  1089  
  1090  // do runs the action graph rooted at root.
  1091  func (b *builder) do(root *action) {
  1092  	// Build list of all actions, assigning depth-first post-order priority.
  1093  	// The original implementation here was a true queue
  1094  	// (using a channel) but it had the effect of getting
  1095  	// distracted by low-level leaf actions to the detriment
  1096  	// of completing higher-level actions.  The order of
  1097  	// work does not matter much to overall execution time,
  1098  	// but when running "go test std" it is nice to see each test
  1099  	// results as soon as possible.  The priorities assigned
  1100  	// ensure that, all else being equal, the execution prefers
  1101  	// to do what it would have done first in a simple depth-first
  1102  	// dependency order traversal.
  1103  	all := actionList(root)
  1104  	for i, a := range all {
  1105  		a.priority = i
  1106  	}
  1107  
  1108  	b.readySema = make(chan bool, len(all))
  1109  
  1110  	// Initialize per-action execution state.
  1111  	for _, a := range all {
  1112  		for _, a1 := range a.deps {
  1113  			a1.triggers = append(a1.triggers, a)
  1114  		}
  1115  		a.pending = len(a.deps)
  1116  		if a.pending == 0 {
  1117  			b.ready.push(a)
  1118  			b.readySema <- true
  1119  		}
  1120  	}
  1121  
  1122  	// Handle runs a single action and takes care of triggering
  1123  	// any actions that are runnable as a result.
  1124  	handle := func(a *action) {
  1125  		var err error
  1126  		if a.f != nil && (!a.failed || a.ignoreFail) {
  1127  			err = a.f(b, a)
  1128  		}
  1129  
  1130  		// The actions run in parallel but all the updates to the
  1131  		// shared work state are serialized through b.exec.
  1132  		b.exec.Lock()
  1133  		defer b.exec.Unlock()
  1134  
  1135  		if err != nil {
  1136  			if err == errPrintedOutput {
  1137  				setExitStatus(2)
  1138  			} else {
  1139  				errorf("%s", err)
  1140  			}
  1141  			a.failed = true
  1142  		}
  1143  
  1144  		for _, a0 := range a.triggers {
  1145  			if a.failed {
  1146  				a0.failed = true
  1147  			}
  1148  			if a0.pending--; a0.pending == 0 {
  1149  				b.ready.push(a0)
  1150  				b.readySema <- true
  1151  			}
  1152  		}
  1153  
  1154  		if a == root {
  1155  			close(b.readySema)
  1156  		}
  1157  	}
  1158  
  1159  	var wg sync.WaitGroup
  1160  
  1161  	// Kick off goroutines according to parallelism.
  1162  	// If we are using the -n flag (just printing commands)
  1163  	// drop the parallelism to 1, both to make the output
  1164  	// deterministic and because there is no real work anyway.
  1165  	par := buildP
  1166  	if buildN {
  1167  		par = 1
  1168  	}
  1169  	for i := 0; i < par; i++ {
  1170  		wg.Add(1)
  1171  		go func() {
  1172  			defer wg.Done()
  1173  			for {
  1174  				select {
  1175  				case _, ok := <-b.readySema:
  1176  					if !ok {
  1177  						return
  1178  					}
  1179  					// Receiving a value from b.readySema entitles
  1180  					// us to take from the ready queue.
  1181  					b.exec.Lock()
  1182  					a := b.ready.pop()
  1183  					b.exec.Unlock()
  1184  					handle(a)
  1185  				case <-interrupted:
  1186  					setExitStatus(1)
  1187  					return
  1188  				}
  1189  			}
  1190  		}()
  1191  	}
  1192  
  1193  	wg.Wait()
  1194  }
  1195  
  1196  // hasString reports whether s appears in the list of strings.
  1197  func hasString(strings []string, s string) bool {
  1198  	for _, t := range strings {
  1199  		if s == t {
  1200  			return true
  1201  		}
  1202  	}
  1203  	return false
  1204  }
  1205  
  1206  // build is the action for building a single package or command.
  1207  func (b *builder) build(a *action) (err error) {
  1208  	// Return an error if the package has CXX files but it's not using
  1209  	// cgo nor SWIG, since the CXX files can only be processed by cgo
  1210  	// and SWIG.
  1211  	if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
  1212  		return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
  1213  			a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
  1214  	}
  1215  	// Same as above for Objective-C files
  1216  	if len(a.p.MFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
  1217  		return fmt.Errorf("can't build package %s because it contains Objective-C files (%s) but it's not using cgo nor SWIG",
  1218  			a.p.ImportPath, strings.Join(a.p.MFiles, ","))
  1219  	}
  1220  	defer func() {
  1221  		if err != nil && err != errPrintedOutput {
  1222  			err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
  1223  		}
  1224  	}()
  1225  	if buildN {
  1226  		// In -n mode, print a banner between packages.
  1227  		// The banner is five lines so that when changes to
  1228  		// different sections of the bootstrap script have to
  1229  		// be merged, the banners give patch something
  1230  		// to use to find its context.
  1231  		fmt.Printf("\n#\n# %s\n#\n\n", a.p.ImportPath)
  1232  	}
  1233  
  1234  	if buildV {
  1235  		fmt.Fprintf(os.Stderr, "%s\n", a.p.ImportPath)
  1236  	}
  1237  
  1238  	if a.p.Standard && a.p.ImportPath == "runtime" && buildContext.Compiler == "gc" &&
  1239  		(!hasString(a.p.GoFiles, "zgoos_"+buildContext.GOOS+".go") ||
  1240  			!hasString(a.p.GoFiles, "zgoarch_"+buildContext.GOARCH+".go")) {
  1241  		return fmt.Errorf("%s/%s must be bootstrapped using make%v", buildContext.GOOS, buildContext.GOARCH, defaultSuffix())
  1242  	}
  1243  
  1244  	// Make build directory.
  1245  	obj := a.objdir
  1246  	if err := b.mkdir(obj); err != nil {
  1247  		return err
  1248  	}
  1249  
  1250  	// make target directory
  1251  	dir, _ := filepath.Split(a.target)
  1252  	if dir != "" {
  1253  		if err := b.mkdir(dir); err != nil {
  1254  			return err
  1255  		}
  1256  	}
  1257  
  1258  	var gofiles, cgofiles, cfiles, sfiles, cxxfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
  1259  
  1260  	gofiles = append(gofiles, a.p.GoFiles...)
  1261  	cgofiles = append(cgofiles, a.p.CgoFiles...)
  1262  	cfiles = append(cfiles, a.p.CFiles...)
  1263  	sfiles = append(sfiles, a.p.SFiles...)
  1264  	cxxfiles = append(cxxfiles, a.p.CXXFiles...)
  1265  
  1266  	if a.p.usesCgo() || a.p.usesSwig() {
  1267  		if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.p); err != nil {
  1268  			return
  1269  		}
  1270  	}
  1271  
  1272  	// Run SWIG on each .swig and .swigcxx file.
  1273  	// Each run will generate two files, a .go file and a .c or .cxx file.
  1274  	// The .go file will use import "C" and is to be processed by cgo.
  1275  	if a.p.usesSwig() {
  1276  		outGo, outC, outCXX, err := b.swig(a.p, obj, pcCFLAGS)
  1277  		if err != nil {
  1278  			return err
  1279  		}
  1280  		cgofiles = append(cgofiles, outGo...)
  1281  		cfiles = append(cfiles, outC...)
  1282  		cxxfiles = append(cxxfiles, outCXX...)
  1283  	}
  1284  
  1285  	// Run cgo.
  1286  	if a.p.usesCgo() || a.p.usesSwig() {
  1287  		// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
  1288  		// There is one exception: runtime/cgo's job is to bridge the
  1289  		// cgo and non-cgo worlds, so it necessarily has files in both.
  1290  		// In that case gcc only gets the gcc_* files.
  1291  		var gccfiles []string
  1292  		if a.p.Standard && a.p.ImportPath == "runtime/cgo" {
  1293  			filter := func(files, nongcc, gcc []string) ([]string, []string) {
  1294  				for _, f := range files {
  1295  					if strings.HasPrefix(f, "gcc_") {
  1296  						gcc = append(gcc, f)
  1297  					} else {
  1298  						nongcc = append(nongcc, f)
  1299  					}
  1300  				}
  1301  				return nongcc, gcc
  1302  			}
  1303  			cfiles, gccfiles = filter(cfiles, cfiles[:0], gccfiles)
  1304  			sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
  1305  		} else {
  1306  			gccfiles = append(cfiles, sfiles...)
  1307  			cfiles = nil
  1308  			sfiles = nil
  1309  		}
  1310  
  1311  		cgoExe := tool("cgo")
  1312  		if a.cgo != nil && a.cgo.target != "" {
  1313  			cgoExe = a.cgo.target
  1314  		}
  1315  		outGo, outObj, err := b.cgo(a.p, cgoExe, obj, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, cxxfiles, a.p.MFiles)
  1316  		if err != nil {
  1317  			return err
  1318  		}
  1319  		cgoObjects = append(cgoObjects, outObj...)
  1320  		gofiles = append(gofiles, outGo...)
  1321  	}
  1322  
  1323  	if len(gofiles) == 0 {
  1324  		return &build.NoGoError{Dir: a.p.Dir}
  1325  	}
  1326  
  1327  	// If we're doing coverage, preprocess the .go files and put them in the work directory
  1328  	if a.p.coverMode != "" {
  1329  		for i, file := range gofiles {
  1330  			var sourceFile string
  1331  			var coverFile string
  1332  			var key string
  1333  			if strings.HasSuffix(file, ".cgo1.go") {
  1334  				// cgo files have absolute paths
  1335  				base := filepath.Base(file)
  1336  				sourceFile = file
  1337  				coverFile = filepath.Join(obj, base)
  1338  				key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
  1339  			} else {
  1340  				sourceFile = filepath.Join(a.p.Dir, file)
  1341  				coverFile = filepath.Join(obj, file)
  1342  				key = file
  1343  			}
  1344  			cover := a.p.coverVars[key]
  1345  			if cover == nil || isTestFile(file) {
  1346  				// Not covering this file.
  1347  				continue
  1348  			}
  1349  			if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
  1350  				return err
  1351  			}
  1352  			gofiles[i] = coverFile
  1353  		}
  1354  	}
  1355  
  1356  	// Prepare Go import path list.
  1357  	inc := b.includeArgs("-I", allArchiveActions(a))
  1358  
  1359  	// Compile Go.
  1360  	ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, len(sfiles) > 0, inc, gofiles)
  1361  	if len(out) > 0 {
  1362  		b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
  1363  		if err != nil {
  1364  			return errPrintedOutput
  1365  		}
  1366  	}
  1367  	if err != nil {
  1368  		return err
  1369  	}
  1370  	if ofile != a.objpkg {
  1371  		objects = append(objects, ofile)
  1372  	}
  1373  
  1374  	// Copy .h files named for goos or goarch or goos_goarch
  1375  	// to names using GOOS and GOARCH.
  1376  	// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
  1377  	_goos_goarch := "_" + goos + "_" + goarch
  1378  	_goos := "_" + goos
  1379  	_goarch := "_" + goarch
  1380  	for _, file := range a.p.HFiles {
  1381  		name, ext := fileExtSplit(file)
  1382  		switch {
  1383  		case strings.HasSuffix(name, _goos_goarch):
  1384  			targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
  1385  			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644, true); err != nil {
  1386  				return err
  1387  			}
  1388  		case strings.HasSuffix(name, _goarch):
  1389  			targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
  1390  			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644, true); err != nil {
  1391  				return err
  1392  			}
  1393  		case strings.HasSuffix(name, _goos):
  1394  			targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
  1395  			if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644, true); err != nil {
  1396  				return err
  1397  			}
  1398  		}
  1399  	}
  1400  
  1401  	for _, file := range cfiles {
  1402  		out := file[:len(file)-len(".c")] + ".o"
  1403  		if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
  1404  			return err
  1405  		}
  1406  		objects = append(objects, out)
  1407  	}
  1408  
  1409  	// Assemble .s files.
  1410  	for _, file := range sfiles {
  1411  		out := file[:len(file)-len(".s")] + ".o"
  1412  		if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
  1413  			return err
  1414  		}
  1415  		objects = append(objects, out)
  1416  	}
  1417  
  1418  	// NOTE(rsc): On Windows, it is critically important that the
  1419  	// gcc-compiled objects (cgoObjects) be listed after the ordinary
  1420  	// objects in the archive.  I do not know why this is.
  1421  	// https://golang.org/issue/2601
  1422  	objects = append(objects, cgoObjects...)
  1423  
  1424  	// Add system object files.
  1425  	for _, syso := range a.p.SysoFiles {
  1426  		objects = append(objects, filepath.Join(a.p.Dir, syso))
  1427  	}
  1428  
  1429  	// Pack into archive in obj directory.
  1430  	// If the Go compiler wrote an archive, we only need to add the
  1431  	// object files for non-Go sources to the archive.
  1432  	// If the Go compiler wrote an archive and the package is entirely
  1433  	// Go sources, there is no pack to execute at all.
  1434  	if len(objects) > 0 {
  1435  		if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
  1436  			return err
  1437  		}
  1438  	}
  1439  
  1440  	// Link if needed.
  1441  	if a.link {
  1442  		// The compiler only cares about direct imports, but the
  1443  		// linker needs the whole dependency tree.
  1444  		all := actionList(a)
  1445  		all = all[:len(all)-1] // drop a
  1446  		if err := buildToolchain.ld(b, a, a.target, all, a.objpkg, objects); err != nil {
  1447  			return err
  1448  		}
  1449  	}
  1450  
  1451  	return nil
  1452  }
  1453  
  1454  // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
  1455  func (b *builder) getPkgConfigFlags(p *Package) (cflags, ldflags []string, err error) {
  1456  	if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
  1457  		var out []byte
  1458  		out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
  1459  		if err != nil {
  1460  			b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
  1461  			b.print(err.Error() + "\n")
  1462  			err = errPrintedOutput
  1463  			return
  1464  		}
  1465  		if len(out) > 0 {
  1466  			cflags = strings.Fields(string(out))
  1467  		}
  1468  		out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
  1469  		if err != nil {
  1470  			b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
  1471  			b.print(err.Error() + "\n")
  1472  			err = errPrintedOutput
  1473  			return
  1474  		}
  1475  		if len(out) > 0 {
  1476  			ldflags = strings.Fields(string(out))
  1477  		}
  1478  	}
  1479  	return
  1480  }
  1481  
  1482  func (b *builder) installShlibname(a *action) error {
  1483  	a1 := a.deps[0]
  1484  	err := ioutil.WriteFile(a.target, []byte(filepath.Base(a1.target)+"\n"), 0644)
  1485  	if err != nil {
  1486  		return err
  1487  	}
  1488  	if buildX {
  1489  		b.showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.target), a.target)
  1490  	}
  1491  	return nil
  1492  }
  1493  
  1494  func (b *builder) linkShared(a *action) (err error) {
  1495  	allactions := actionList(a)
  1496  	allactions = allactions[:len(allactions)-1]
  1497  	return buildToolchain.ldShared(b, a.deps, a.target, allactions)
  1498  }
  1499  
  1500  // install is the action for installing a single package or executable.
  1501  func (b *builder) install(a *action) (err error) {
  1502  	defer func() {
  1503  		if err != nil && err != errPrintedOutput {
  1504  			err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err)
  1505  		}
  1506  	}()
  1507  	a1 := a.deps[0]
  1508  	perm := os.FileMode(0644)
  1509  	if a1.link {
  1510  		switch buildBuildmode {
  1511  		case "c-archive", "c-shared":
  1512  		default:
  1513  			perm = 0755
  1514  		}
  1515  	}
  1516  
  1517  	// make target directory
  1518  	dir, _ := filepath.Split(a.target)
  1519  	if dir != "" {
  1520  		if err := b.mkdir(dir); err != nil {
  1521  			return err
  1522  		}
  1523  	}
  1524  
  1525  	// remove object dir to keep the amount of
  1526  	// garbage down in a large build.  On an operating system
  1527  	// with aggressive buffering, cleaning incrementally like
  1528  	// this keeps the intermediate objects from hitting the disk.
  1529  	if !buildWork {
  1530  		defer os.RemoveAll(a1.objdir)
  1531  		defer os.Remove(a1.target)
  1532  	}
  1533  
  1534  	return b.moveOrCopyFile(a, a.target, a1.target, perm, false)
  1535  }
  1536  
  1537  // includeArgs returns the -I or -L directory list for access
  1538  // to the results of the list of actions.
  1539  func (b *builder) includeArgs(flag string, all []*action) []string {
  1540  	inc := []string{}
  1541  	incMap := map[string]bool{
  1542  		b.work:    true, // handled later
  1543  		gorootPkg: true,
  1544  		"":        true, // ignore empty strings
  1545  	}
  1546  
  1547  	// Look in the temporary space for results of test-specific actions.
  1548  	// This is the $WORK/my/package/_test directory for the
  1549  	// package being built, so there are few of these.
  1550  	for _, a1 := range all {
  1551  		if a1.p == nil {
  1552  			continue
  1553  		}
  1554  		if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
  1555  			incMap[dir] = true
  1556  			inc = append(inc, flag, dir)
  1557  		}
  1558  	}
  1559  
  1560  	// Also look in $WORK for any non-test packages that have
  1561  	// been built but not installed.
  1562  	inc = append(inc, flag, b.work)
  1563  
  1564  	// Finally, look in the installed package directories for each action.
  1565  	for _, a1 := range all {
  1566  		if a1.p == nil {
  1567  			continue
  1568  		}
  1569  		if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
  1570  			incMap[dir] = true
  1571  			inc = append(inc, flag, a1.p.build.PkgTargetRoot)
  1572  		}
  1573  	}
  1574  
  1575  	return inc
  1576  }
  1577  
  1578  // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
  1579  func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
  1580  	if buildN {
  1581  		b.showcmd("", "mv %s %s", src, dst)
  1582  		return nil
  1583  	}
  1584  
  1585  	// If we can update the mode and rename to the dst, do it.
  1586  	// Otherwise fall back to standard copy.
  1587  	if err := os.Chmod(src, perm); err == nil {
  1588  		if err := os.Rename(src, dst); err == nil {
  1589  			if buildX {
  1590  				b.showcmd("", "mv %s %s", src, dst)
  1591  			}
  1592  			return nil
  1593  		}
  1594  	}
  1595  
  1596  	return b.copyFile(a, dst, src, perm, force)
  1597  }
  1598  
  1599  // copyFile is like 'cp src dst'.
  1600  func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
  1601  	if buildN || buildX {
  1602  		b.showcmd("", "cp %s %s", src, dst)
  1603  		if buildN {
  1604  			return nil
  1605  		}
  1606  	}
  1607  
  1608  	sf, err := os.Open(src)
  1609  	if err != nil {
  1610  		return err
  1611  	}
  1612  	defer sf.Close()
  1613  
  1614  	// Be careful about removing/overwriting dst.
  1615  	// Do not remove/overwrite if dst exists and is a directory
  1616  	// or a non-object file.
  1617  	if fi, err := os.Stat(dst); err == nil {
  1618  		if fi.IsDir() {
  1619  			return fmt.Errorf("build output %q already exists and is a directory", dst)
  1620  		}
  1621  		if !force && !isObject(dst) {
  1622  			return fmt.Errorf("build output %q already exists and is not an object file", dst)
  1623  		}
  1624  	}
  1625  
  1626  	// On Windows, remove lingering ~ file from last attempt.
  1627  	if toolIsWindows {
  1628  		if _, err := os.Stat(dst + "~"); err == nil {
  1629  			os.Remove(dst + "~")
  1630  		}
  1631  	}
  1632  
  1633  	os.Remove(dst)
  1634  	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1635  	if err != nil && toolIsWindows {
  1636  		// Windows does not allow deletion of a binary file
  1637  		// while it is executing.  Try to move it out of the way.
  1638  		// If the move fails, which is likely, we'll try again the
  1639  		// next time we do an install of this binary.
  1640  		if err := os.Rename(dst, dst+"~"); err == nil {
  1641  			os.Remove(dst + "~")
  1642  		}
  1643  		df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1644  	}
  1645  	if err != nil {
  1646  		return err
  1647  	}
  1648  
  1649  	_, err = io.Copy(df, sf)
  1650  	df.Close()
  1651  	if err != nil {
  1652  		os.Remove(dst)
  1653  		return fmt.Errorf("copying %s to %s: %v", src, dst, err)
  1654  	}
  1655  	return nil
  1656  }
  1657  
  1658  // Install the cgo export header file, if there is one.
  1659  func (b *builder) installHeader(a *action) error {
  1660  	src := a.objdir + "_cgo_install.h"
  1661  	if _, err := os.Stat(src); os.IsNotExist(err) {
  1662  		// If the file does not exist, there are no exported
  1663  		// functions, and we do not install anything.
  1664  		return nil
  1665  	}
  1666  
  1667  	dir, _ := filepath.Split(a.target)
  1668  	if dir != "" {
  1669  		if err := b.mkdir(dir); err != nil {
  1670  			return err
  1671  		}
  1672  	}
  1673  
  1674  	return b.moveOrCopyFile(a, a.target, src, 0644, true)
  1675  }
  1676  
  1677  // cover runs, in effect,
  1678  //	go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
  1679  func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
  1680  	return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
  1681  		buildToolExec,
  1682  		tool("cover"),
  1683  		"-mode", a.p.coverMode,
  1684  		"-var", varName,
  1685  		"-o", dst,
  1686  		src)
  1687  }
  1688  
  1689  var objectMagic = [][]byte{
  1690  	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
  1691  	{'\x7F', 'E', 'L', 'F'},                   // ELF
  1692  	{0xFE, 0xED, 0xFA, 0xCE},                  // Mach-O big-endian 32-bit
  1693  	{0xFE, 0xED, 0xFA, 0xCF},                  // Mach-O big-endian 64-bit
  1694  	{0xCE, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 32-bit
  1695  	{0xCF, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 64-bit
  1696  	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00},      // PE (Windows) as generated by 6l/8l and gcc
  1697  	{0x00, 0x00, 0x01, 0xEB},                  // Plan 9 i386
  1698  	{0x00, 0x00, 0x8a, 0x97},                  // Plan 9 amd64
  1699  }
  1700  
  1701  func isObject(s string) bool {
  1702  	f, err := os.Open(s)
  1703  	if err != nil {
  1704  		return false
  1705  	}
  1706  	defer f.Close()
  1707  	buf := make([]byte, 64)
  1708  	io.ReadFull(f, buf)
  1709  	for _, magic := range objectMagic {
  1710  		if bytes.HasPrefix(buf, magic) {
  1711  			return true
  1712  		}
  1713  	}
  1714  	return false
  1715  }
  1716  
  1717  // fmtcmd formats a command in the manner of fmt.Sprintf but also:
  1718  //
  1719  //	If dir is non-empty and the script is not in dir right now,
  1720  //	fmtcmd inserts "cd dir\n" before the command.
  1721  //
  1722  //	fmtcmd replaces the value of b.work with $WORK.
  1723  //	fmtcmd replaces the value of goroot with $GOROOT.
  1724  //	fmtcmd replaces the value of b.gobin with $GOBIN.
  1725  //
  1726  //	fmtcmd replaces the name of the current directory with dot (.)
  1727  //	but only when it is at the beginning of a space-separated token.
  1728  //
  1729  func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
  1730  	cmd := fmt.Sprintf(format, args...)
  1731  	if dir != "" && dir != "/" {
  1732  		cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
  1733  		if b.scriptDir != dir {
  1734  			b.scriptDir = dir
  1735  			cmd = "cd " + dir + "\n" + cmd
  1736  		}
  1737  	}
  1738  	if b.work != "" {
  1739  		cmd = strings.Replace(cmd, b.work, "$WORK", -1)
  1740  	}
  1741  	return cmd
  1742  }
  1743  
  1744  // showcmd prints the given command to standard output
  1745  // for the implementation of -n or -x.
  1746  func (b *builder) showcmd(dir string, format string, args ...interface{}) {
  1747  	b.output.Lock()
  1748  	defer b.output.Unlock()
  1749  	b.print(b.fmtcmd(dir, format, args...) + "\n")
  1750  }
  1751  
  1752  // showOutput prints "# desc" followed by the given output.
  1753  // The output is expected to contain references to 'dir', usually
  1754  // the source directory for the package that has failed to build.
  1755  // showOutput rewrites mentions of dir with a relative path to dir
  1756  // when the relative path is shorter.  This is usually more pleasant.
  1757  // For example, if fmt doesn't compile and we are in src/html,
  1758  // the output is
  1759  //
  1760  //	$ go build
  1761  //	# fmt
  1762  //	../fmt/print.go:1090: undefined: asdf
  1763  //	$
  1764  //
  1765  // instead of
  1766  //
  1767  //	$ go build
  1768  //	# fmt
  1769  //	/usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
  1770  //	$
  1771  //
  1772  // showOutput also replaces references to the work directory with $WORK.
  1773  //
  1774  func (b *builder) showOutput(dir, desc, out string) {
  1775  	prefix := "# " + desc
  1776  	suffix := "\n" + out
  1777  	if reldir := shortPath(dir); reldir != dir {
  1778  		suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
  1779  		suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
  1780  	}
  1781  	suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
  1782  
  1783  	b.output.Lock()
  1784  	defer b.output.Unlock()
  1785  	b.print(prefix, suffix)
  1786  }
  1787  
  1788  // shortPath returns an absolute or relative name for path, whatever is shorter.
  1789  func shortPath(path string) string {
  1790  	if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
  1791  		return rel
  1792  	}
  1793  	return path
  1794  }
  1795  
  1796  // relPaths returns a copy of paths with absolute paths
  1797  // made relative to the current directory if they would be shorter.
  1798  func relPaths(paths []string) []string {
  1799  	var out []string
  1800  	pwd, _ := os.Getwd()
  1801  	for _, p := range paths {
  1802  		rel, err := filepath.Rel(pwd, p)
  1803  		if err == nil && len(rel) < len(p) {
  1804  			p = rel
  1805  		}
  1806  		out = append(out, p)
  1807  	}
  1808  	return out
  1809  }
  1810  
  1811  // errPrintedOutput is a special error indicating that a command failed
  1812  // but that it generated output as well, and that output has already
  1813  // been printed, so there's no point showing 'exit status 1' or whatever
  1814  // the wait status was.  The main executor, builder.do, knows not to
  1815  // print this error.
  1816  var errPrintedOutput = errors.New("already printed output - no need to show error")
  1817  
  1818  var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
  1819  var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
  1820  
  1821  // run runs the command given by cmdline in the directory dir.
  1822  // If the command fails, run prints information about the failure
  1823  // and returns a non-nil error.
  1824  func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
  1825  	out, err := b.runOut(dir, desc, env, cmdargs...)
  1826  	if len(out) > 0 {
  1827  		if desc == "" {
  1828  			desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
  1829  		}
  1830  		b.showOutput(dir, desc, b.processOutput(out))
  1831  		if err != nil {
  1832  			err = errPrintedOutput
  1833  		}
  1834  	}
  1835  	return err
  1836  }
  1837  
  1838  // processOutput prepares the output of runOut to be output to the console.
  1839  func (b *builder) processOutput(out []byte) string {
  1840  	if out[len(out)-1] != '\n' {
  1841  		out = append(out, '\n')
  1842  	}
  1843  	messages := string(out)
  1844  	// Fix up output referring to cgo-generated code to be more readable.
  1845  	// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
  1846  	// Replace *[100]_Ctype_foo with *[100]C.foo.
  1847  	// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
  1848  	if !buildX && cgoLine.MatchString(messages) {
  1849  		messages = cgoLine.ReplaceAllString(messages, "")
  1850  		messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
  1851  	}
  1852  	return messages
  1853  }
  1854  
  1855  // runOut runs the command given by cmdline in the directory dir.
  1856  // It returns the command output and any errors that occurred.
  1857  func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
  1858  	cmdline := stringList(cmdargs...)
  1859  	if buildN || buildX {
  1860  		var envcmdline string
  1861  		for i := range env {
  1862  			envcmdline += env[i]
  1863  			envcmdline += " "
  1864  		}
  1865  		envcmdline += joinUnambiguously(cmdline)
  1866  		b.showcmd(dir, "%s", envcmdline)
  1867  		if buildN {
  1868  			return nil, nil
  1869  		}
  1870  	}
  1871  
  1872  	nbusy := 0
  1873  	for {
  1874  		var buf bytes.Buffer
  1875  		cmd := exec.Command(cmdline[0], cmdline[1:]...)
  1876  		cmd.Stdout = &buf
  1877  		cmd.Stderr = &buf
  1878  		cmd.Dir = dir
  1879  		cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir, os.Environ()))
  1880  		err := cmd.Run()
  1881  
  1882  		// cmd.Run will fail on Unix if some other process has the binary
  1883  		// we want to run open for writing.  This can happen here because
  1884  		// we build and install the cgo command and then run it.
  1885  		// If another command was kicked off while we were writing the
  1886  		// cgo binary, the child process for that command may be holding
  1887  		// a reference to the fd, keeping us from running exec.
  1888  		//
  1889  		// But, you might reasonably wonder, how can this happen?
  1890  		// The cgo fd, like all our fds, is close-on-exec, so that we need
  1891  		// not worry about other processes inheriting the fd accidentally.
  1892  		// The answer is that running a command is fork and exec.
  1893  		// A child forked while the cgo fd is open inherits that fd.
  1894  		// Until the child has called exec, it holds the fd open and the
  1895  		// kernel will not let us run cgo.  Even if the child were to close
  1896  		// the fd explicitly, it would still be open from the time of the fork
  1897  		// until the time of the explicit close, and the race would remain.
  1898  		//
  1899  		// On Unix systems, this results in ETXTBSY, which formats
  1900  		// as "text file busy".  Rather than hard-code specific error cases,
  1901  		// we just look for that string.  If this happens, sleep a little
  1902  		// and try again.  We let this happen three times, with increasing
  1903  		// sleep lengths: 100+200+400 ms = 0.7 seconds.
  1904  		//
  1905  		// An alternate solution might be to split the cmd.Run into
  1906  		// separate cmd.Start and cmd.Wait, and then use an RWLock
  1907  		// to make sure that copyFile only executes when no cmd.Start
  1908  		// call is in progress.  However, cmd.Start (really syscall.forkExec)
  1909  		// only guarantees that when it returns, the exec is committed to
  1910  		// happen and succeed.  It uses a close-on-exec file descriptor
  1911  		// itself to determine this, so we know that when cmd.Start returns,
  1912  		// at least one close-on-exec file descriptor has been closed.
  1913  		// However, we cannot be sure that all of them have been closed,
  1914  		// so the program might still encounter ETXTBSY even with such
  1915  		// an RWLock.  The race window would be smaller, perhaps, but not
  1916  		// guaranteed to be gone.
  1917  		//
  1918  		// Sleeping when we observe the race seems to be the most reliable
  1919  		// option we have.
  1920  		//
  1921  		// https://golang.org/issue/3001
  1922  		//
  1923  		if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
  1924  			time.Sleep(100 * time.Millisecond << uint(nbusy))
  1925  			nbusy++
  1926  			continue
  1927  		}
  1928  
  1929  		// err can be something like 'exit status 1'.
  1930  		// Add information about what program was running.
  1931  		// Note that if buf.Bytes() is non-empty, the caller usually
  1932  		// shows buf.Bytes() and does not print err at all, so the
  1933  		// prefix here does not make most output any more verbose.
  1934  		if err != nil {
  1935  			err = errors.New(cmdline[0] + ": " + err.Error())
  1936  		}
  1937  		return buf.Bytes(), err
  1938  	}
  1939  }
  1940  
  1941  // joinUnambiguously prints the slice, quoting where necessary to make the
  1942  // output unambiguous.
  1943  // TODO: See issue 5279. The printing of commands needs a complete redo.
  1944  func joinUnambiguously(a []string) string {
  1945  	var buf bytes.Buffer
  1946  	for i, s := range a {
  1947  		if i > 0 {
  1948  			buf.WriteByte(' ')
  1949  		}
  1950  		q := strconv.Quote(s)
  1951  		if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
  1952  			buf.WriteString(q)
  1953  		} else {
  1954  			buf.WriteString(s)
  1955  		}
  1956  	}
  1957  	return buf.String()
  1958  }
  1959  
  1960  // mkdir makes the named directory.
  1961  func (b *builder) mkdir(dir string) error {
  1962  	b.exec.Lock()
  1963  	defer b.exec.Unlock()
  1964  	// We can be a little aggressive about being
  1965  	// sure directories exist.  Skip repeated calls.
  1966  	if b.mkdirCache[dir] {
  1967  		return nil
  1968  	}
  1969  	b.mkdirCache[dir] = true
  1970  
  1971  	if buildN || buildX {
  1972  		b.showcmd("", "mkdir -p %s", dir)
  1973  		if buildN {
  1974  			return nil
  1975  		}
  1976  	}
  1977  
  1978  	if err := os.MkdirAll(dir, 0777); err != nil {
  1979  		return err
  1980  	}
  1981  	return nil
  1982  }
  1983  
  1984  // mkAbs returns an absolute path corresponding to
  1985  // evaluating f in the directory dir.
  1986  // We always pass absolute paths of source files so that
  1987  // the error messages will include the full path to a file
  1988  // in need of attention.
  1989  func mkAbs(dir, f string) string {
  1990  	// Leave absolute paths alone.
  1991  	// Also, during -n mode we use the pseudo-directory $WORK
  1992  	// instead of creating an actual work directory that won't be used.
  1993  	// Leave paths beginning with $WORK alone too.
  1994  	if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
  1995  		return f
  1996  	}
  1997  	return filepath.Join(dir, f)
  1998  }
  1999  
  2000  type toolchain interface {
  2001  	// gc runs the compiler in a specific directory on a set of files
  2002  	// and returns the name of the generated output file.
  2003  	// The compiler runs in the directory dir.
  2004  	gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
  2005  	// cc runs the toolchain's C compiler in a directory on a C file
  2006  	// to produce an output file.
  2007  	cc(b *builder, p *Package, objdir, ofile, cfile string) error
  2008  	// asm runs the assembler in a specific directory on a specific file
  2009  	// to generate the named output file.
  2010  	asm(b *builder, p *Package, obj, ofile, sfile string) error
  2011  	// pkgpath builds an appropriate path for a temporary package file.
  2012  	pkgpath(basedir string, p *Package) string
  2013  	// pack runs the archive packer in a specific directory to create
  2014  	// an archive from a set of object files.
  2015  	// typically it is run in the object directory.
  2016  	pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
  2017  	// ld runs the linker to create an executable starting at mainpkg.
  2018  	ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error
  2019  	// ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
  2020  	ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error
  2021  
  2022  	compiler() string
  2023  	linker() string
  2024  }
  2025  
  2026  type noToolchain struct{}
  2027  
  2028  func noCompiler() error {
  2029  	log.Fatalf("unknown compiler %q", buildContext.Compiler)
  2030  	return nil
  2031  }
  2032  
  2033  func (noToolchain) compiler() string {
  2034  	noCompiler()
  2035  	return ""
  2036  }
  2037  
  2038  func (noToolchain) linker() string {
  2039  	noCompiler()
  2040  	return ""
  2041  }
  2042  
  2043  func (noToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
  2044  	return "", nil, noCompiler()
  2045  }
  2046  
  2047  func (noToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
  2048  	return noCompiler()
  2049  }
  2050  
  2051  func (noToolchain) pkgpath(basedir string, p *Package) string {
  2052  	noCompiler()
  2053  	return ""
  2054  }
  2055  
  2056  func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  2057  	return noCompiler()
  2058  }
  2059  
  2060  func (noToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
  2061  	return noCompiler()
  2062  }
  2063  
  2064  func (noToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
  2065  	return noCompiler()
  2066  }
  2067  
  2068  func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  2069  	return noCompiler()
  2070  }
  2071  
  2072  // The Go toolchain.
  2073  type gcToolchain struct{}
  2074  
  2075  func (gcToolchain) compiler() string {
  2076  	return tool("compile")
  2077  }
  2078  
  2079  func (gcToolchain) linker() string {
  2080  	return tool("link")
  2081  }
  2082  
  2083  func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
  2084  	if archive != "" {
  2085  		ofile = archive
  2086  	} else {
  2087  		out := "_go_.o"
  2088  		ofile = obj + out
  2089  	}
  2090  
  2091  	gcargs := []string{"-p", p.ImportPath}
  2092  	if p.Name == "main" {
  2093  		gcargs[1] = "main"
  2094  	}
  2095  	if p.Standard && p.ImportPath == "runtime" {
  2096  		// runtime compiles with a special gc flag to emit
  2097  		// additional reflect type data.
  2098  		gcargs = append(gcargs, "-+")
  2099  	}
  2100  
  2101  	// If we're giving the compiler the entire package (no C etc files), tell it that,
  2102  	// so that it can give good error messages about forward declarations.
  2103  	// Exceptions: a few standard packages have forward declarations for
  2104  	// pieces supplied behind-the-scenes by package runtime.
  2105  	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)
  2106  	if p.Standard {
  2107  		switch p.ImportPath {
  2108  		case "bytes", "net", "os", "runtime/pprof", "sync", "time":
  2109  			extFiles++
  2110  		}
  2111  	}
  2112  	if extFiles == 0 {
  2113  		gcargs = append(gcargs, "-complete")
  2114  	}
  2115  	if buildContext.InstallSuffix != "" {
  2116  		gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
  2117  	}
  2118  	if p.buildID != "" {
  2119  		gcargs = append(gcargs, "-buildid", p.buildID)
  2120  	}
  2121  
  2122  	for _, path := range p.Imports {
  2123  		if i := strings.LastIndex(path, "/vendor/"); i >= 0 {
  2124  			gcargs = append(gcargs, "-importmap", path[i+len("/vendor/"):]+"="+path)
  2125  		} else if strings.HasPrefix(path, "vendor/") {
  2126  			gcargs = append(gcargs, "-importmap", path[len("vendor/"):]+"="+path)
  2127  		}
  2128  	}
  2129  
  2130  	args := []interface{}{buildToolExec, tool("compile"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs}
  2131  	if ofile == archive {
  2132  		args = append(args, "-pack")
  2133  	}
  2134  	if asmhdr {
  2135  		args = append(args, "-asmhdr", obj+"go_asm.h")
  2136  	}
  2137  	for _, f := range gofiles {
  2138  		args = append(args, mkAbs(p.Dir, f))
  2139  	}
  2140  
  2141  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args...)
  2142  	return ofile, output, err
  2143  }
  2144  
  2145  func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
  2146  	// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
  2147  	inc := filepath.Join(goroot, "pkg", "include")
  2148  	sfile = mkAbs(p.Dir, sfile)
  2149  	args := []interface{}{buildToolExec, tool("asm"), "-o", ofile, "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch, buildAsmflags, sfile}
  2150  	if err := b.run(p.Dir, p.ImportPath, nil, args...); err != nil {
  2151  		return err
  2152  	}
  2153  	return nil
  2154  }
  2155  
  2156  // toolVerify checks that the command line args writes the same output file
  2157  // if run using newTool instead.
  2158  // Unused now but kept around for future use.
  2159  func toolVerify(b *builder, p *Package, newTool string, ofile string, args []interface{}) error {
  2160  	newArgs := make([]interface{}, len(args))
  2161  	copy(newArgs, args)
  2162  	newArgs[1] = tool(newTool)
  2163  	newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
  2164  	if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
  2165  		return err
  2166  	}
  2167  	data1, err := ioutil.ReadFile(ofile)
  2168  	if err != nil {
  2169  		return err
  2170  	}
  2171  	data2, err := ioutil.ReadFile(ofile + ".new")
  2172  	if err != nil {
  2173  		return err
  2174  	}
  2175  	if !bytes.Equal(data1, data2) {
  2176  		return fmt.Errorf("%s and %s produced different output files:\n%s\n%s", filepath.Base(args[1].(string)), newTool, strings.Join(stringList(args...), " "), strings.Join(stringList(newArgs...), " "))
  2177  	}
  2178  	os.Remove(ofile + ".new")
  2179  	return nil
  2180  }
  2181  
  2182  func (gcToolchain) pkgpath(basedir string, p *Package) string {
  2183  	end := filepath.FromSlash(p.ImportPath + ".a")
  2184  	return filepath.Join(basedir, end)
  2185  }
  2186  
  2187  func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  2188  	var absOfiles []string
  2189  	for _, f := range ofiles {
  2190  		absOfiles = append(absOfiles, mkAbs(objDir, f))
  2191  	}
  2192  	cmd := "c"
  2193  	absAfile := mkAbs(objDir, afile)
  2194  	appending := false
  2195  	if _, err := os.Stat(absAfile); err == nil {
  2196  		appending = true
  2197  		cmd = "r"
  2198  	}
  2199  
  2200  	cmdline := stringList("pack", cmd, absAfile, absOfiles)
  2201  
  2202  	if appending {
  2203  		if buildN || buildX {
  2204  			b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
  2205  		}
  2206  		if buildN {
  2207  			return nil
  2208  		}
  2209  		if err := packInternal(b, absAfile, absOfiles); err != nil {
  2210  			b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
  2211  			return errPrintedOutput
  2212  		}
  2213  		return nil
  2214  	}
  2215  
  2216  	// Need actual pack.
  2217  	cmdline[0] = tool("pack")
  2218  	return b.run(p.Dir, p.ImportPath, nil, buildToolExec, cmdline)
  2219  }
  2220  
  2221  func packInternal(b *builder, afile string, ofiles []string) error {
  2222  	dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
  2223  	if err != nil {
  2224  		return err
  2225  	}
  2226  	defer dst.Close() // only for error returns or panics
  2227  	w := bufio.NewWriter(dst)
  2228  
  2229  	for _, ofile := range ofiles {
  2230  		src, err := os.Open(ofile)
  2231  		if err != nil {
  2232  			return err
  2233  		}
  2234  		fi, err := src.Stat()
  2235  		if err != nil {
  2236  			src.Close()
  2237  			return err
  2238  		}
  2239  		// Note: Not using %-16.16s format because we care
  2240  		// about bytes, not runes.
  2241  		name := fi.Name()
  2242  		if len(name) > 16 {
  2243  			name = name[:16]
  2244  		} else {
  2245  			name += strings.Repeat(" ", 16-len(name))
  2246  		}
  2247  		size := fi.Size()
  2248  		fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
  2249  			name, 0, 0, 0, 0644, size)
  2250  		n, err := io.Copy(w, src)
  2251  		src.Close()
  2252  		if err == nil && n < size {
  2253  			err = io.ErrUnexpectedEOF
  2254  		} else if err == nil && n > size {
  2255  			err = fmt.Errorf("file larger than size reported by stat")
  2256  		}
  2257  		if err != nil {
  2258  			return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
  2259  		}
  2260  		if size&1 != 0 {
  2261  			w.WriteByte(0)
  2262  		}
  2263  	}
  2264  
  2265  	if err := w.Flush(); err != nil {
  2266  		return err
  2267  	}
  2268  	return dst.Close()
  2269  }
  2270  
  2271  // setextld sets the appropriate linker flags for the specified compiler.
  2272  func setextld(ldflags []string, compiler []string) []string {
  2273  	for _, f := range ldflags {
  2274  		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
  2275  			// don't override -extld if supplied
  2276  			return ldflags
  2277  		}
  2278  	}
  2279  	ldflags = append(ldflags, "-extld="+compiler[0])
  2280  	if len(compiler) > 1 {
  2281  		extldflags := false
  2282  		add := strings.Join(compiler[1:], " ")
  2283  		for i, f := range ldflags {
  2284  			if f == "-extldflags" && i+1 < len(ldflags) {
  2285  				ldflags[i+1] = add + " " + ldflags[i+1]
  2286  				extldflags = true
  2287  				break
  2288  			} else if strings.HasPrefix(f, "-extldflags=") {
  2289  				ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
  2290  				extldflags = true
  2291  				break
  2292  			}
  2293  		}
  2294  		if !extldflags {
  2295  			ldflags = append(ldflags, "-extldflags="+add)
  2296  		}
  2297  	}
  2298  	return ldflags
  2299  }
  2300  
  2301  func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
  2302  	importArgs := b.includeArgs("-L", allactions)
  2303  	cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
  2304  	for _, a := range allactions {
  2305  		if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
  2306  			cxx = true
  2307  		}
  2308  	}
  2309  	var ldflags []string
  2310  	if buildContext.InstallSuffix != "" {
  2311  		ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
  2312  	}
  2313  	if root.p.omitDWARF {
  2314  		ldflags = append(ldflags, "-w")
  2315  	}
  2316  
  2317  	// If the user has not specified the -extld option, then specify the
  2318  	// appropriate linker. In case of C++ code, use the compiler named
  2319  	// by the CXX environment variable or defaultCXX if CXX is not set.
  2320  	// Else, use the CC environment variable and defaultCC as fallback.
  2321  	var compiler []string
  2322  	if cxx {
  2323  		compiler = envList("CXX", defaultCXX)
  2324  	} else {
  2325  		compiler = envList("CC", defaultCC)
  2326  	}
  2327  	ldflags = setextld(ldflags, compiler)
  2328  	ldflags = append(ldflags, "-buildmode="+ldBuildmode)
  2329  	if root.p.buildID != "" {
  2330  		ldflags = append(ldflags, "-buildid="+root.p.buildID)
  2331  	}
  2332  	ldflags = append(ldflags, buildLdflags...)
  2333  
  2334  	// On OS X when using external linking to build a shared library,
  2335  	// the argument passed here to -o ends up recorded in the final
  2336  	// shared library in the LC_ID_DYLIB load command.
  2337  	// To avoid putting the temporary output directory name there
  2338  	// (and making the resulting shared library useless),
  2339  	// run the link in the output directory so that -o can name
  2340  	// just the final path element.
  2341  	dir := "."
  2342  	if goos == "darwin" && buildBuildmode == "c-shared" {
  2343  		dir, out = filepath.Split(out)
  2344  	}
  2345  
  2346  	return b.run(dir, root.p.ImportPath, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags, mainpkg)
  2347  }
  2348  
  2349  func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
  2350  	importArgs := b.includeArgs("-L", allactions)
  2351  	ldflags := []string{"-installsuffix", buildContext.InstallSuffix}
  2352  	ldflags = append(ldflags, "-buildmode=shared")
  2353  	ldflags = append(ldflags, buildLdflags...)
  2354  	cxx := false
  2355  	for _, a := range allactions {
  2356  		if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
  2357  			cxx = true
  2358  		}
  2359  	}
  2360  	// If the user has not specified the -extld option, then specify the
  2361  	// appropriate linker. In case of C++ code, use the compiler named
  2362  	// by the CXX environment variable or defaultCXX if CXX is not set.
  2363  	// Else, use the CC environment variable and defaultCC as fallback.
  2364  	var compiler []string
  2365  	if cxx {
  2366  		compiler = envList("CXX", defaultCXX)
  2367  	} else {
  2368  		compiler = envList("CC", defaultCC)
  2369  	}
  2370  	ldflags = setextld(ldflags, compiler)
  2371  	for _, d := range toplevelactions {
  2372  		if !strings.HasSuffix(d.target, ".a") { // omit unsafe etc and actions for other shared libraries
  2373  			continue
  2374  		}
  2375  		ldflags = append(ldflags, d.p.ImportPath+"="+d.target)
  2376  	}
  2377  	return b.run(".", out, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags)
  2378  }
  2379  
  2380  func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  2381  	return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
  2382  }
  2383  
  2384  // The Gccgo toolchain.
  2385  type gccgoToolchain struct{}
  2386  
  2387  var gccgoName, gccgoBin string
  2388  
  2389  func init() {
  2390  	gccgoName = os.Getenv("GCCGO")
  2391  	if gccgoName == "" {
  2392  		gccgoName = "gccgo"
  2393  	}
  2394  	gccgoBin, _ = exec.LookPath(gccgoName)
  2395  }
  2396  
  2397  func (gccgoToolchain) compiler() string {
  2398  	return gccgoBin
  2399  }
  2400  
  2401  func (gccgoToolchain) linker() string {
  2402  	return gccgoBin
  2403  }
  2404  
  2405  func (tools gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
  2406  	out := "_go_.o"
  2407  	ofile = obj + out
  2408  	gcargs := []string{"-g"}
  2409  	gcargs = append(gcargs, b.gccArchArgs()...)
  2410  	if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  2411  		gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
  2412  	}
  2413  	if p.localPrefix != "" {
  2414  		gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
  2415  	}
  2416  	args := stringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
  2417  	for _, f := range gofiles {
  2418  		args = append(args, mkAbs(p.Dir, f))
  2419  	}
  2420  
  2421  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
  2422  	return ofile, output, err
  2423  }
  2424  
  2425  func (tools gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
  2426  	sfile = mkAbs(p.Dir, sfile)
  2427  	defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
  2428  	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  2429  		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
  2430  	}
  2431  	defs = tools.maybePIC(defs)
  2432  	defs = append(defs, b.gccArchArgs()...)
  2433  	return b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-I", obj, "-o", ofile, defs, sfile)
  2434  }
  2435  
  2436  func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
  2437  	end := filepath.FromSlash(p.ImportPath + ".a")
  2438  	afile := filepath.Join(basedir, end)
  2439  	// add "lib" to the final element
  2440  	return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
  2441  }
  2442  
  2443  func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  2444  	var absOfiles []string
  2445  	for _, f := range ofiles {
  2446  		absOfiles = append(absOfiles, mkAbs(objDir, f))
  2447  	}
  2448  	return b.run(p.Dir, p.ImportPath, nil, "ar", "cru", mkAbs(objDir, afile), absOfiles)
  2449  }
  2450  
  2451  func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
  2452  	// gccgo needs explicit linking with all package dependencies,
  2453  	// and all LDFLAGS from cgo dependencies.
  2454  	apackagesSeen := make(map[*Package]bool)
  2455  	afiles := []string{}
  2456  	shlibs := []string{}
  2457  	xfiles := []string{}
  2458  	ldflags := b.gccArchArgs()
  2459  	cgoldflags := []string{}
  2460  	usesCgo := false
  2461  	cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
  2462  	objc := len(root.p.MFiles) > 0
  2463  
  2464  	actionsSeen := make(map[*action]bool)
  2465  	// Make a pre-order depth-first traversal of the action graph, taking note of
  2466  	// whether a shared library action has been seen on the way to an action (the
  2467  	// construction of the graph means that if any path to a node passes through
  2468  	// a shared library action, they all do).
  2469  	var walk func(a *action, seenShlib bool)
  2470  	walk = func(a *action, seenShlib bool) {
  2471  		if actionsSeen[a] {
  2472  			return
  2473  		}
  2474  		actionsSeen[a] = true
  2475  		if a.p != nil && !seenShlib {
  2476  			if a.p.Standard {
  2477  				return
  2478  			}
  2479  			// We record the target of the first time we see a .a file
  2480  			// for a package to make sure that we prefer the 'install'
  2481  			// rather than the 'build' location (which may not exist any
  2482  			// more). We still need to traverse the dependencies of the
  2483  			// build action though so saying
  2484  			// if apackagesSeen[a.p] { return }
  2485  			// doesn't work.
  2486  			if !apackagesSeen[a.p] {
  2487  				apackagesSeen[a.p] = true
  2488  				if a.p.fake && a.p.external {
  2489  					// external _tests, if present must come before
  2490  					// internal _tests. Store these on a separate list
  2491  					// and place them at the head after this loop.
  2492  					xfiles = append(xfiles, a.target)
  2493  				} else if a.p.fake {
  2494  					// move _test files to the top of the link order
  2495  					afiles = append([]string{a.target}, afiles...)
  2496  				} else {
  2497  					afiles = append(afiles, a.target)
  2498  				}
  2499  			}
  2500  		}
  2501  		if strings.HasSuffix(a.target, ".so") {
  2502  			shlibs = append(shlibs, a.target)
  2503  			seenShlib = true
  2504  		}
  2505  		for _, a1 := range a.deps {
  2506  			walk(a1, seenShlib)
  2507  		}
  2508  	}
  2509  	for _, a1 := range root.deps {
  2510  		walk(a1, false)
  2511  	}
  2512  	afiles = append(xfiles, afiles...)
  2513  
  2514  	for _, a := range allactions {
  2515  		// Gather CgoLDFLAGS, but not from standard packages.
  2516  		// The go tool can dig up runtime/cgo from GOROOT and
  2517  		// think that it should use its CgoLDFLAGS, but gccgo
  2518  		// doesn't use runtime/cgo.
  2519  		if a.p == nil {
  2520  			continue
  2521  		}
  2522  		if !a.p.Standard {
  2523  			cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
  2524  		}
  2525  		if len(a.p.CgoFiles) > 0 {
  2526  			usesCgo = true
  2527  		}
  2528  		if a.p.usesSwig() {
  2529  			usesCgo = true
  2530  		}
  2531  		if len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0 {
  2532  			cxx = true
  2533  		}
  2534  		if len(a.p.MFiles) > 0 {
  2535  			objc = true
  2536  		}
  2537  	}
  2538  
  2539  	switch ldBuildmode {
  2540  	case "c-archive", "c-shared":
  2541  		ldflags = append(ldflags, "-Wl,--whole-archive")
  2542  	}
  2543  
  2544  	ldflags = append(ldflags, afiles...)
  2545  
  2546  	switch ldBuildmode {
  2547  	case "c-archive", "c-shared":
  2548  		ldflags = append(ldflags, "-Wl,--no-whole-archive")
  2549  	}
  2550  
  2551  	ldflags = append(ldflags, cgoldflags...)
  2552  	ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
  2553  	ldflags = append(ldflags, root.p.CgoLDFLAGS...)
  2554  
  2555  	ldflags = stringList("-Wl,-(", ldflags, "-Wl,-)")
  2556  
  2557  	for _, shlib := range shlibs {
  2558  		ldflags = append(
  2559  			ldflags,
  2560  			"-L"+filepath.Dir(shlib),
  2561  			"-Wl,-rpath="+filepath.Dir(shlib),
  2562  			"-l"+strings.TrimSuffix(
  2563  				strings.TrimPrefix(filepath.Base(shlib), "lib"),
  2564  				".so"))
  2565  	}
  2566  
  2567  	var realOut string
  2568  	switch ldBuildmode {
  2569  	case "exe":
  2570  		if usesCgo && goos == "linux" {
  2571  			ldflags = append(ldflags, "-Wl,-E")
  2572  		}
  2573  
  2574  	case "c-archive":
  2575  		// Link the Go files into a single .o, and also link
  2576  		// in -lgolibbegin.
  2577  		//
  2578  		// We need to use --whole-archive with -lgolibbegin
  2579  		// because it doesn't define any symbols that will
  2580  		// cause the contents to be pulled in; it's just
  2581  		// initialization code.
  2582  		//
  2583  		// The user remains responsible for linking against
  2584  		// -lgo -lpthread -lm in the final link.  We can't use
  2585  		// -r to pick them up because we can't combine
  2586  		// split-stack and non-split-stack code in a single -r
  2587  		// link, and libgo picks up non-split-stack code from
  2588  		// libffi.
  2589  		ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
  2590  
  2591  		// We are creating an object file, so we don't want a build ID.
  2592  		ldflags = b.disableBuildID(ldflags)
  2593  
  2594  		realOut = out
  2595  		out = out + ".o"
  2596  
  2597  	case "c-shared":
  2598  		ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc")
  2599  
  2600  	default:
  2601  		fatalf("-buildmode=%s not supported for gccgo", ldBuildmode)
  2602  	}
  2603  
  2604  	switch ldBuildmode {
  2605  	case "exe", "c-shared":
  2606  		if cxx {
  2607  			ldflags = append(ldflags, "-lstdc++")
  2608  		}
  2609  		if objc {
  2610  			ldflags = append(ldflags, "-lobjc")
  2611  		}
  2612  	}
  2613  
  2614  	if err := b.run(".", root.p.ImportPath, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil {
  2615  		return err
  2616  	}
  2617  
  2618  	switch ldBuildmode {
  2619  	case "c-archive":
  2620  		if err := b.run(".", root.p.ImportPath, nil, "ar", "rc", realOut, out); err != nil {
  2621  			return err
  2622  		}
  2623  	}
  2624  	return nil
  2625  }
  2626  
  2627  func (tools gccgoToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
  2628  	args := []string{"-o", out, "-shared", "-nostdlib", "-zdefs", "-Wl,--whole-archive"}
  2629  	for _, a := range toplevelactions {
  2630  		args = append(args, a.target)
  2631  	}
  2632  	args = append(args, "-Wl,--no-whole-archive", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc")
  2633  	shlibs := []string{}
  2634  	for _, a := range allactions {
  2635  		if strings.HasSuffix(a.target, ".so") {
  2636  			shlibs = append(shlibs, a.target)
  2637  		}
  2638  	}
  2639  	for _, shlib := range shlibs {
  2640  		args = append(
  2641  			args,
  2642  			"-L"+filepath.Dir(shlib),
  2643  			"-Wl,-rpath="+filepath.Dir(shlib),
  2644  			"-l"+strings.TrimSuffix(
  2645  				strings.TrimPrefix(filepath.Base(shlib), "lib"),
  2646  				".so"))
  2647  	}
  2648  	return b.run(".", out, nil, tools.linker(), args, buildGccgoflags)
  2649  }
  2650  
  2651  func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  2652  	inc := filepath.Join(goroot, "pkg", "include")
  2653  	cfile = mkAbs(p.Dir, cfile)
  2654  	defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
  2655  	defs = append(defs, b.gccArchArgs()...)
  2656  	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  2657  		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
  2658  	}
  2659  	switch goarch {
  2660  	case "386", "amd64":
  2661  		defs = append(defs, "-fsplit-stack")
  2662  	}
  2663  	defs = tools.maybePIC(defs)
  2664  	return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g",
  2665  		"-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
  2666  }
  2667  
  2668  // maybePIC adds -fPIC to the list of arguments if needed.
  2669  func (tools gccgoToolchain) maybePIC(args []string) []string {
  2670  	switch buildBuildmode {
  2671  	case "c-shared", "shared":
  2672  		args = append(args, "-fPIC")
  2673  	}
  2674  	return args
  2675  }
  2676  
  2677  func gccgoPkgpath(p *Package) string {
  2678  	if p.build.IsCommand() && !p.forceLibrary {
  2679  		return ""
  2680  	}
  2681  	return p.ImportPath
  2682  }
  2683  
  2684  func gccgoCleanPkgpath(p *Package) string {
  2685  	clean := func(r rune) rune {
  2686  		switch {
  2687  		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
  2688  			'0' <= r && r <= '9':
  2689  			return r
  2690  		}
  2691  		return '_'
  2692  	}
  2693  	return strings.Map(clean, gccgoPkgpath(p))
  2694  }
  2695  
  2696  // libgcc returns the filename for libgcc, as determined by invoking gcc with
  2697  // the -print-libgcc-file-name option.
  2698  func (b *builder) libgcc(p *Package) (string, error) {
  2699  	var buf bytes.Buffer
  2700  
  2701  	gccCmd := b.gccCmd(p.Dir)
  2702  
  2703  	prev := b.print
  2704  	if buildN {
  2705  		// In -n mode we temporarily swap out the builder's
  2706  		// print function to capture the command-line. This
  2707  		// let's us assign it to $LIBGCC and produce a valid
  2708  		// buildscript for cgo packages.
  2709  		b.print = func(a ...interface{}) (int, error) {
  2710  			return fmt.Fprint(&buf, a...)
  2711  		}
  2712  	}
  2713  	f, err := b.runOut(p.Dir, p.ImportPath, nil, gccCmd, "-print-libgcc-file-name")
  2714  	if err != nil {
  2715  		return "", fmt.Errorf("gcc -print-libgcc-file-name: %v (%s)", err, f)
  2716  	}
  2717  	if buildN {
  2718  		s := fmt.Sprintf("LIBGCC=$(%s)\n", buf.Next(buf.Len()-1))
  2719  		b.print = prev
  2720  		b.print(s)
  2721  		return "$LIBGCC", nil
  2722  	}
  2723  
  2724  	// The compiler might not be able to find libgcc, and in that case,
  2725  	// it will simply return "libgcc.a", which is of no use to us.
  2726  	if !filepath.IsAbs(string(f)) {
  2727  		return "", nil
  2728  	}
  2729  
  2730  	return strings.Trim(string(f), "\r\n"), nil
  2731  }
  2732  
  2733  // gcc runs the gcc C compiler to create an object from a single C file.
  2734  func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
  2735  	return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
  2736  }
  2737  
  2738  // gxx runs the g++ C++ compiler to create an object from a single C++ file.
  2739  func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
  2740  	return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
  2741  }
  2742  
  2743  // ccompile runs the given C or C++ compiler and creates an object from a single source file.
  2744  func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error {
  2745  	file = mkAbs(p.Dir, file)
  2746  	return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file)
  2747  }
  2748  
  2749  // gccld runs the gcc linker to create an executable from a set of object files.
  2750  func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
  2751  	var cmd []string
  2752  	if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
  2753  		cmd = b.gxxCmd(p.Dir)
  2754  	} else {
  2755  		cmd = b.gccCmd(p.Dir)
  2756  	}
  2757  	return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
  2758  }
  2759  
  2760  // gccCmd returns a gcc command line prefix
  2761  // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
  2762  func (b *builder) gccCmd(objdir string) []string {
  2763  	return b.ccompilerCmd("CC", defaultCC, objdir)
  2764  }
  2765  
  2766  // gxxCmd returns a g++ command line prefix
  2767  // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
  2768  func (b *builder) gxxCmd(objdir string) []string {
  2769  	return b.ccompilerCmd("CXX", defaultCXX, objdir)
  2770  }
  2771  
  2772  // ccompilerCmd returns a command line prefix for the given environment
  2773  // variable and using the default command when the variable is empty.
  2774  func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
  2775  	// NOTE: env.go's mkEnv knows that the first three
  2776  	// strings returned are "gcc", "-I", objdir (and cuts them off).
  2777  
  2778  	compiler := envList(envvar, defcmd)
  2779  	a := []string{compiler[0], "-I", objdir}
  2780  	a = append(a, compiler[1:]...)
  2781  
  2782  	// Definitely want -fPIC but on Windows gcc complains
  2783  	// "-fPIC ignored for target (all code is position independent)"
  2784  	if goos != "windows" {
  2785  		a = append(a, "-fPIC")
  2786  	}
  2787  	a = append(a, b.gccArchArgs()...)
  2788  	// gcc-4.5 and beyond require explicit "-pthread" flag
  2789  	// for multithreading with pthread library.
  2790  	if buildContext.CgoEnabled {
  2791  		switch goos {
  2792  		case "windows":
  2793  			a = append(a, "-mthreads")
  2794  		default:
  2795  			a = append(a, "-pthread")
  2796  		}
  2797  	}
  2798  
  2799  	if strings.Contains(a[0], "clang") {
  2800  		// disable ASCII art in clang errors, if possible
  2801  		a = append(a, "-fno-caret-diagnostics")
  2802  		// clang is too smart about command-line arguments
  2803  		a = append(a, "-Qunused-arguments")
  2804  	}
  2805  
  2806  	// disable word wrapping in error messages
  2807  	a = append(a, "-fmessage-length=0")
  2808  
  2809  	// On OS X, some of the compilers behave as if -fno-common
  2810  	// is always set, and the Mach-O linker in 6l/8l assumes this.
  2811  	// See https://golang.org/issue/3253.
  2812  	if goos == "darwin" {
  2813  		a = append(a, "-fno-common")
  2814  	}
  2815  
  2816  	return a
  2817  }
  2818  
  2819  // gccArchArgs returns arguments to pass to gcc based on the architecture.
  2820  func (b *builder) gccArchArgs() []string {
  2821  	switch goarch {
  2822  	case "386":
  2823  		return []string{"-m32"}
  2824  	case "amd64", "amd64p32":
  2825  		return []string{"-m64"}
  2826  	case "arm":
  2827  		return []string{"-marm"} // not thumb
  2828  	}
  2829  	return nil
  2830  }
  2831  
  2832  // envList returns the value of the given environment variable broken
  2833  // into fields, using the default value when the variable is empty.
  2834  func envList(key, def string) []string {
  2835  	v := os.Getenv(key)
  2836  	if v == "" {
  2837  		v = def
  2838  	}
  2839  	return strings.Fields(v)
  2840  }
  2841  
  2842  // Return the flags to use when invoking the C or C++ compilers, or cgo.
  2843  func (b *builder) cflags(p *Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) {
  2844  	var defaults string
  2845  	if def {
  2846  		defaults = "-g -O2"
  2847  	}
  2848  
  2849  	cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
  2850  	cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
  2851  	cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
  2852  	ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
  2853  	return
  2854  }
  2855  
  2856  var cgoRe = regexp.MustCompile(`[/\\:]`)
  2857  
  2858  var (
  2859  	cgoLibGccFile     string
  2860  	cgoLibGccErr      error
  2861  	cgoLibGccFileOnce sync.Once
  2862  )
  2863  
  2864  func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
  2865  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true)
  2866  	_, cgoexeCFLAGS, _, _ := b.cflags(p, false)
  2867  	cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
  2868  	cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
  2869  	// If we are compiling Objective-C code, then we need to link against libobjc
  2870  	if len(mfiles) > 0 {
  2871  		cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
  2872  	}
  2873  
  2874  	// Allows including _cgo_export.h from .[ch] files in the package.
  2875  	cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
  2876  
  2877  	// cgo
  2878  	// TODO: CGOPKGPATH, CGO_FLAGS?
  2879  	gofiles := []string{obj + "_cgo_gotypes.go"}
  2880  	cfiles := []string{"_cgo_main.c", "_cgo_export.c"}
  2881  	for _, fn := range cgofiles {
  2882  		f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
  2883  		gofiles = append(gofiles, obj+f+"cgo1.go")
  2884  		cfiles = append(cfiles, f+"cgo2.c")
  2885  	}
  2886  	defunC := obj + "_cgo_defun.c"
  2887  
  2888  	cgoflags := []string{}
  2889  	// TODO: make cgo not depend on $GOARCH?
  2890  
  2891  	if p.Standard && p.ImportPath == "runtime/cgo" {
  2892  		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
  2893  	}
  2894  	if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/cgo") {
  2895  		cgoflags = append(cgoflags, "-import_syscall=false")
  2896  	}
  2897  
  2898  	// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
  2899  	var cgoenv []string
  2900  	if len(cgoLDFLAGS) > 0 {
  2901  		flags := make([]string, len(cgoLDFLAGS))
  2902  		for i, f := range cgoLDFLAGS {
  2903  			flags[i] = strconv.Quote(f)
  2904  		}
  2905  		cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
  2906  	}
  2907  
  2908  	if _, ok := buildToolchain.(gccgoToolchain); ok {
  2909  		switch goarch {
  2910  		case "386", "amd64":
  2911  			cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
  2912  		}
  2913  		cgoflags = append(cgoflags, "-gccgo")
  2914  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  2915  			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
  2916  		}
  2917  	}
  2918  
  2919  	switch buildBuildmode {
  2920  	case "c-archive", "c-shared":
  2921  		// Tell cgo that if there are any exported functions
  2922  		// it should generate a header file that C code can
  2923  		// #include.
  2924  		cgoflags = append(cgoflags, "-exportheader="+obj+"_cgo_install.h")
  2925  	}
  2926  
  2927  	if err := b.run(p.Dir, p.ImportPath, cgoenv, buildToolExec, cgoExe, "-objdir", obj, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, cgofiles); err != nil {
  2928  		return nil, nil, err
  2929  	}
  2930  	outGo = append(outGo, gofiles...)
  2931  
  2932  	// cc _cgo_defun.c
  2933  	_, gccgo := buildToolchain.(gccgoToolchain)
  2934  	if gccgo {
  2935  		defunObj := obj + "_cgo_defun.o"
  2936  		if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
  2937  			return nil, nil, err
  2938  		}
  2939  		outObj = append(outObj, defunObj)
  2940  	}
  2941  
  2942  	// gcc
  2943  	var linkobj []string
  2944  
  2945  	var bareLDFLAGS []string
  2946  	// When linking relocatable objects, various flags need to be
  2947  	// filtered out as they are inapplicable and can cause some linkers
  2948  	// to fail.
  2949  	for i := 0; i < len(cgoLDFLAGS); i++ {
  2950  		f := cgoLDFLAGS[i]
  2951  		switch {
  2952  		// skip "-lc" or "-l somelib"
  2953  		case strings.HasPrefix(f, "-l"):
  2954  			if f == "-l" {
  2955  				i++
  2956  			}
  2957  		// skip "-framework X" on Darwin
  2958  		case goos == "darwin" && f == "-framework":
  2959  			i++
  2960  		// skip "*.{dylib,so,dll}"
  2961  		case strings.HasSuffix(f, ".dylib"),
  2962  			strings.HasSuffix(f, ".so"),
  2963  			strings.HasSuffix(f, ".dll"):
  2964  		// Remove any -fsanitize=foo flags.
  2965  		// Otherwise the compiler driver thinks that we are doing final link
  2966  		// and links sanitizer runtime into the object file. But we are not doing
  2967  		// the final link, we will link the resulting object file again. And
  2968  		// so the program ends up with two copies of sanitizer runtime.
  2969  		// See issue 8788 for details.
  2970  		case strings.HasPrefix(f, "-fsanitize="):
  2971  			continue
  2972  		// runpath flags not applicable unless building a shared
  2973  		// object or executable; see issue 12115 for details.  This
  2974  		// is necessary as Go currently does not offer a way to
  2975  		// specify the set of LDFLAGS that only apply to shared
  2976  		// objects.
  2977  		case strings.HasPrefix(f, "-Wl,-rpath"):
  2978  			if f == "-Wl,-rpath" || f == "-Wl,-rpath-link" {
  2979  				// Skip following argument to -rpath* too.
  2980  				i++
  2981  			}
  2982  		default:
  2983  			bareLDFLAGS = append(bareLDFLAGS, f)
  2984  		}
  2985  	}
  2986  
  2987  	cgoLibGccFileOnce.Do(func() {
  2988  		cgoLibGccFile, cgoLibGccErr = b.libgcc(p)
  2989  	})
  2990  	if cgoLibGccFile == "" && cgoLibGccErr != nil {
  2991  		return nil, nil, err
  2992  	}
  2993  
  2994  	var staticLibs []string
  2995  	if goos == "windows" {
  2996  		// libmingw32 and libmingwex might also use libgcc, so libgcc must come last,
  2997  		// and they also have some inter-dependencies, so must use linker groups.
  2998  		staticLibs = []string{"-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group"}
  2999  	}
  3000  	if cgoLibGccFile != "" {
  3001  		staticLibs = append(staticLibs, cgoLibGccFile)
  3002  	}
  3003  
  3004  	cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
  3005  	for _, cfile := range cfiles {
  3006  		ofile := obj + cfile[:len(cfile)-1] + "o"
  3007  		if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
  3008  			return nil, nil, err
  3009  		}
  3010  		linkobj = append(linkobj, ofile)
  3011  		if !strings.HasSuffix(ofile, "_cgo_main.o") {
  3012  			outObj = append(outObj, ofile)
  3013  		}
  3014  	}
  3015  
  3016  	for _, file := range gccfiles {
  3017  		ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
  3018  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  3019  			return nil, nil, err
  3020  		}
  3021  		linkobj = append(linkobj, ofile)
  3022  		outObj = append(outObj, ofile)
  3023  	}
  3024  
  3025  	cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
  3026  	for _, file := range gxxfiles {
  3027  		// Append .o to the file, just in case the pkg has file.c and file.cpp
  3028  		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
  3029  		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
  3030  			return nil, nil, err
  3031  		}
  3032  		linkobj = append(linkobj, ofile)
  3033  		outObj = append(outObj, ofile)
  3034  	}
  3035  
  3036  	for _, file := range mfiles {
  3037  		// Append .o to the file, just in case the pkg has file.c and file.m
  3038  		ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
  3039  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  3040  			return nil, nil, err
  3041  		}
  3042  		linkobj = append(linkobj, ofile)
  3043  		outObj = append(outObj, ofile)
  3044  	}
  3045  
  3046  	linkobj = append(linkobj, p.SysoFiles...)
  3047  	dynobj := obj + "_cgo_.o"
  3048  	pie := goarch == "arm" && (goos == "linux" || goos == "android")
  3049  	if pie { // we need to use -pie for Linux/ARM to get accurate imported sym
  3050  		cgoLDFLAGS = append(cgoLDFLAGS, "-pie")
  3051  	}
  3052  	if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil {
  3053  		return nil, nil, err
  3054  	}
  3055  	if pie { // but we don't need -pie for normal cgo programs
  3056  		cgoLDFLAGS = cgoLDFLAGS[0 : len(cgoLDFLAGS)-1]
  3057  	}
  3058  
  3059  	if _, ok := buildToolchain.(gccgoToolchain); ok {
  3060  		// we don't use dynimport when using gccgo.
  3061  		return outGo, outObj, nil
  3062  	}
  3063  
  3064  	// cgo -dynimport
  3065  	importGo := obj + "_cgo_import.go"
  3066  	cgoflags = []string{}
  3067  	if p.Standard && p.ImportPath == "runtime/cgo" {
  3068  		cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
  3069  	}
  3070  	if err := b.run(p.Dir, p.ImportPath, nil, buildToolExec, cgoExe, "-objdir", obj, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags); err != nil {
  3071  		return nil, nil, err
  3072  	}
  3073  	outGo = append(outGo, importGo)
  3074  
  3075  	ofile := obj + "_all.o"
  3076  	var gccObjs, nonGccObjs []string
  3077  	for _, f := range outObj {
  3078  		if strings.HasSuffix(f, ".o") {
  3079  			gccObjs = append(gccObjs, f)
  3080  		} else {
  3081  			nonGccObjs = append(nonGccObjs, f)
  3082  		}
  3083  	}
  3084  	ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs)
  3085  
  3086  	// We are creating an object file, so we don't want a build ID.
  3087  	ldflags = b.disableBuildID(ldflags)
  3088  
  3089  	if err := b.gccld(p, ofile, ldflags, gccObjs); err != nil {
  3090  		return nil, nil, err
  3091  	}
  3092  
  3093  	// NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
  3094  	// must be processed before the gcc-generated objects.
  3095  	// Put it first.  https://golang.org/issue/2601
  3096  	outObj = stringList(nonGccObjs, ofile)
  3097  
  3098  	return outGo, outObj, nil
  3099  }
  3100  
  3101  // Run SWIG on all SWIG input files.
  3102  // TODO: Don't build a shared library, once SWIG emits the necessary
  3103  // pragmas for external linking.
  3104  func (b *builder) swig(p *Package, obj string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
  3105  	if err := b.swigVersionCheck(); err != nil {
  3106  		return nil, nil, nil, err
  3107  	}
  3108  
  3109  	intgosize, err := b.swigIntSize(obj)
  3110  	if err != nil {
  3111  		return nil, nil, nil, err
  3112  	}
  3113  
  3114  	for _, f := range p.SwigFiles {
  3115  		goFile, cFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
  3116  		if err != nil {
  3117  			return nil, nil, nil, err
  3118  		}
  3119  		if goFile != "" {
  3120  			outGo = append(outGo, goFile)
  3121  		}
  3122  		if cFile != "" {
  3123  			outC = append(outC, cFile)
  3124  		}
  3125  	}
  3126  	for _, f := range p.SwigCXXFiles {
  3127  		goFile, cxxFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
  3128  		if err != nil {
  3129  			return nil, nil, nil, err
  3130  		}
  3131  		if goFile != "" {
  3132  			outGo = append(outGo, goFile)
  3133  		}
  3134  		if cxxFile != "" {
  3135  			outCXX = append(outCXX, cxxFile)
  3136  		}
  3137  	}
  3138  	return outGo, outC, outCXX, nil
  3139  }
  3140  
  3141  // Make sure SWIG is new enough.
  3142  var (
  3143  	swigCheckOnce sync.Once
  3144  	swigCheck     error
  3145  )
  3146  
  3147  func (b *builder) swigDoVersionCheck() error {
  3148  	out, err := b.runOut("", "", nil, "swig", "-version")
  3149  	if err != nil {
  3150  		return err
  3151  	}
  3152  	re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
  3153  	matches := re.FindSubmatch(out)
  3154  	if matches == nil {
  3155  		// Can't find version number; hope for the best.
  3156  		return nil
  3157  	}
  3158  
  3159  	major, err := strconv.Atoi(string(matches[1]))
  3160  	if err != nil {
  3161  		// Can't find version number; hope for the best.
  3162  		return nil
  3163  	}
  3164  	const errmsg = "must have SWIG version >= 3.0.6"
  3165  	if major < 3 {
  3166  		return errors.New(errmsg)
  3167  	}
  3168  	if major > 3 {
  3169  		// 4.0 or later
  3170  		return nil
  3171  	}
  3172  
  3173  	// We have SWIG version 3.x.
  3174  	if len(matches[2]) > 0 {
  3175  		minor, err := strconv.Atoi(string(matches[2][1:]))
  3176  		if err != nil {
  3177  			return nil
  3178  		}
  3179  		if minor > 0 {
  3180  			// 3.1 or later
  3181  			return nil
  3182  		}
  3183  	}
  3184  
  3185  	// We have SWIG version 3.0.x.
  3186  	if len(matches[3]) > 0 {
  3187  		patch, err := strconv.Atoi(string(matches[3][1:]))
  3188  		if err != nil {
  3189  			return nil
  3190  		}
  3191  		if patch < 6 {
  3192  			// Before 3.0.6.
  3193  			return errors.New(errmsg)
  3194  		}
  3195  	}
  3196  
  3197  	return nil
  3198  }
  3199  
  3200  func (b *builder) swigVersionCheck() error {
  3201  	swigCheckOnce.Do(func() {
  3202  		swigCheck = b.swigDoVersionCheck()
  3203  	})
  3204  	return swigCheck
  3205  }
  3206  
  3207  // This code fails to build if sizeof(int) <= 32
  3208  const swigIntSizeCode = `
  3209  package main
  3210  const i int = 1 << 32
  3211  `
  3212  
  3213  // Determine the size of int on the target system for the -intgosize option
  3214  // of swig >= 2.0.9
  3215  func (b *builder) swigIntSize(obj string) (intsize string, err error) {
  3216  	if buildN {
  3217  		return "$INTBITS", nil
  3218  	}
  3219  	src := filepath.Join(b.work, "swig_intsize.go")
  3220  	if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0644); err != nil {
  3221  		return
  3222  	}
  3223  	srcs := []string{src}
  3224  
  3225  	p := goFilesPackage(srcs)
  3226  
  3227  	if _, _, e := buildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil {
  3228  		return "32", nil
  3229  	}
  3230  	return "64", nil
  3231  }
  3232  
  3233  // Run SWIG on one SWIG input file.
  3234  func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
  3235  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
  3236  	var cflags []string
  3237  	if cxx {
  3238  		cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
  3239  	} else {
  3240  		cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
  3241  	}
  3242  
  3243  	n := 5 // length of ".swig"
  3244  	if cxx {
  3245  		n = 8 // length of ".swigcxx"
  3246  	}
  3247  	base := file[:len(file)-n]
  3248  	goFile := base + ".go"
  3249  	gccBase := base + "_wrap."
  3250  	gccExt := "c"
  3251  	if cxx {
  3252  		gccExt = "cxx"
  3253  	}
  3254  
  3255  	_, gccgo := buildToolchain.(gccgoToolchain)
  3256  
  3257  	// swig
  3258  	args := []string{
  3259  		"-go",
  3260  		"-cgo",
  3261  		"-intgosize", intgosize,
  3262  		"-module", base,
  3263  		"-o", obj + gccBase + gccExt,
  3264  		"-outdir", obj,
  3265  	}
  3266  
  3267  	for _, f := range cflags {
  3268  		if len(f) > 3 && f[:2] == "-I" {
  3269  			args = append(args, f)
  3270  		}
  3271  	}
  3272  
  3273  	if gccgo {
  3274  		args = append(args, "-gccgo")
  3275  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  3276  			args = append(args, "-go-pkgpath", pkgpath)
  3277  		}
  3278  	}
  3279  	if cxx {
  3280  		args = append(args, "-c++")
  3281  	}
  3282  
  3283  	out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file)
  3284  	if err != nil {
  3285  		if len(out) > 0 {
  3286  			if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
  3287  				return "", "", errors.New("must have SWIG version >= 3.0.6")
  3288  			}
  3289  			b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig error
  3290  			return "", "", errPrintedOutput
  3291  		}
  3292  		return "", "", err
  3293  	}
  3294  	if len(out) > 0 {
  3295  		b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig warning
  3296  	}
  3297  
  3298  	return obj + goFile, obj + gccBase + gccExt, nil
  3299  }
  3300  
  3301  // disableBuildID adjusts a linker command line to avoid creating a
  3302  // build ID when creating an object file rather than an executable or
  3303  // shared library.  Some systems, such as Ubuntu, always add
  3304  // --build-id to every link, but we don't want a build ID when we are
  3305  // producing an object file.  On some of those system a plain -r (not
  3306  // -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a
  3307  // plain -r.  I don't know how to turn off --build-id when using clang
  3308  // other than passing a trailing --build-id=none.  So that is what we
  3309  // do, but only on systems likely to support it, which is to say,
  3310  // systems that normally use gold or the GNU linker.
  3311  func (b *builder) disableBuildID(ldflags []string) []string {
  3312  	switch goos {
  3313  	case "android", "dragonfly", "linux", "netbsd":
  3314  		ldflags = append(ldflags, "-Wl,--build-id=none")
  3315  	}
  3316  	return ldflags
  3317  }
  3318  
  3319  // An actionQueue is a priority queue of actions.
  3320  type actionQueue []*action
  3321  
  3322  // Implement heap.Interface
  3323  func (q *actionQueue) Len() int           { return len(*q) }
  3324  func (q *actionQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
  3325  func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
  3326  func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) }
  3327  func (q *actionQueue) Pop() interface{} {
  3328  	n := len(*q) - 1
  3329  	x := (*q)[n]
  3330  	*q = (*q)[:n]
  3331  	return x
  3332  }
  3333  
  3334  func (q *actionQueue) push(a *action) {
  3335  	heap.Push(q, a)
  3336  }
  3337  
  3338  func (q *actionQueue) pop() *action {
  3339  	return heap.Pop(q).(*action)
  3340  }
  3341  
  3342  func raceInit() {
  3343  	if !buildRace {
  3344  		return
  3345  	}
  3346  	if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" {
  3347  		fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
  3348  		os.Exit(2)
  3349  	}
  3350  	buildGcflags = append(buildGcflags, "-race")
  3351  	buildLdflags = append(buildLdflags, "-race")
  3352  	if buildContext.InstallSuffix != "" {
  3353  		buildContext.InstallSuffix += "_"
  3354  	}
  3355  	buildContext.InstallSuffix += "race"
  3356  	buildContext.BuildTags = append(buildContext.BuildTags, "race")
  3357  }
  3358  
  3359  // defaultSuffix returns file extension used for command files in
  3360  // current os environment.
  3361  func defaultSuffix() string {
  3362  	switch runtime.GOOS {
  3363  	case "windows":
  3364  		return ".bat"
  3365  	case "plan9":
  3366  		return ".rc"
  3367  	default:
  3368  		return ".bash"
  3369  	}
  3370  }