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