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