github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/src/cmd/go/build.go (about)

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