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