github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/cmd/go/build.go (about)

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