github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/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",
   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  	if p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) {
  2180  		// runtime compiles with a special gc flag to emit
  2181  		// additional reflect type data.
  2182  		gcargs = append(gcargs, "-+")
  2183  	}
  2184  
  2185  	// If we're giving the compiler the entire package (no C etc files), tell it that,
  2186  	// so that it can give good error messages about forward declarations.
  2187  	// Exceptions: a few standard packages have forward declarations for
  2188  	// pieces supplied behind-the-scenes by package runtime.
  2189  	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)
  2190  	if p.Standard {
  2191  		switch p.ImportPath {
  2192  		case "bytes", "internal/poll", "net", "os", "runtime/pprof", "sync", "syscall", "time":
  2193  			extFiles++
  2194  		}
  2195  	}
  2196  	if extFiles == 0 {
  2197  		gcargs = append(gcargs, "-complete")
  2198  	}
  2199  	if cfg.BuildContext.InstallSuffix != "" {
  2200  		gcargs = append(gcargs, "-installsuffix", cfg.BuildContext.InstallSuffix)
  2201  	}
  2202  	if p.Internal.BuildID != "" {
  2203  		gcargs = append(gcargs, "-buildid", p.Internal.BuildID)
  2204  	}
  2205  
  2206  	for _, path := range p.Imports {
  2207  		if i := strings.LastIndex(path, "/vendor/"); i >= 0 {
  2208  			gcargs = append(gcargs, "-importmap", path[i+len("/vendor/"):]+"="+path)
  2209  		} else if strings.HasPrefix(path, "vendor/") {
  2210  			gcargs = append(gcargs, "-importmap", path[len("vendor/"):]+"="+path)
  2211  		}
  2212  	}
  2213  
  2214  	args := []interface{}{cfg.BuildToolexec, base.Tool("compile"), "-o", ofile, "-trimpath", b.WorkDir, buildGcflags, gcargs, "-D", p.Internal.LocalPrefix, importArgs}
  2215  	if ofile == archive {
  2216  		args = append(args, "-pack")
  2217  	}
  2218  	if asmhdr {
  2219  		args = append(args, "-asmhdr", obj+"go_asm.h")
  2220  	}
  2221  	for _, f := range gofiles {
  2222  		args = append(args, mkAbs(p.Dir, f))
  2223  	}
  2224  
  2225  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args...)
  2226  	return ofile, output, err
  2227  }
  2228  
  2229  func (gcToolchain) asm(b *Builder, p *load.Package, obj string, sfiles []string) ([]string, error) {
  2230  	// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
  2231  	inc := filepath.Join(cfg.GOROOT, "pkg", "include")
  2232  	args := []interface{}{cfg.BuildToolexec, base.Tool("asm"), "-trimpath", b.WorkDir, "-I", obj, "-I", inc, "-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch, buildAsmflags}
  2233  	if p.ImportPath == "runtime" && cfg.Goarch == "386" {
  2234  		for _, arg := range buildAsmflags {
  2235  			if arg == "-dynlink" {
  2236  				args = append(args, "-D=GOBUILDMODE_shared=1")
  2237  			}
  2238  		}
  2239  	}
  2240  	var ofiles []string
  2241  	for _, sfile := range sfiles {
  2242  		ofile := obj + sfile[:len(sfile)-len(".s")] + ".o"
  2243  		ofiles = append(ofiles, ofile)
  2244  		a := append(args, "-o", ofile, mkAbs(p.Dir, sfile))
  2245  		if err := b.run(p.Dir, p.ImportPath, nil, a...); err != nil {
  2246  			return nil, err
  2247  		}
  2248  	}
  2249  	return ofiles, nil
  2250  }
  2251  
  2252  // toolVerify checks that the command line args writes the same output file
  2253  // if run using newTool instead.
  2254  // Unused now but kept around for future use.
  2255  func toolVerify(b *Builder, p *load.Package, newTool string, ofile string, args []interface{}) error {
  2256  	newArgs := make([]interface{}, len(args))
  2257  	copy(newArgs, args)
  2258  	newArgs[1] = base.Tool(newTool)
  2259  	newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
  2260  	if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
  2261  		return err
  2262  	}
  2263  	data1, err := ioutil.ReadFile(ofile)
  2264  	if err != nil {
  2265  		return err
  2266  	}
  2267  	data2, err := ioutil.ReadFile(ofile + ".new")
  2268  	if err != nil {
  2269  		return err
  2270  	}
  2271  	if !bytes.Equal(data1, data2) {
  2272  		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...), " "))
  2273  	}
  2274  	os.Remove(ofile + ".new")
  2275  	return nil
  2276  }
  2277  
  2278  func (gcToolchain) Pkgpath(basedir string, p *load.Package) string {
  2279  	end := filepath.FromSlash(p.ImportPath + ".a")
  2280  	return filepath.Join(basedir, end)
  2281  }
  2282  
  2283  func (gcToolchain) pack(b *Builder, p *load.Package, objDir, afile string, ofiles []string) error {
  2284  	var absOfiles []string
  2285  	for _, f := range ofiles {
  2286  		absOfiles = append(absOfiles, mkAbs(objDir, f))
  2287  	}
  2288  	absAfile := mkAbs(objDir, afile)
  2289  
  2290  	// The archive file should have been created by the compiler.
  2291  	// Since it used to not work that way, verify.
  2292  	if !cfg.BuildN {
  2293  		if _, err := os.Stat(absAfile); err != nil {
  2294  			base.Fatalf("os.Stat of archive file failed: %v", err)
  2295  		}
  2296  	}
  2297  
  2298  	if cfg.BuildN || cfg.BuildX {
  2299  		cmdline := str.StringList("pack", "r", absAfile, absOfiles)
  2300  		b.Showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
  2301  	}
  2302  	if cfg.BuildN {
  2303  		return nil
  2304  	}
  2305  	if err := packInternal(b, absAfile, absOfiles); err != nil {
  2306  		b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
  2307  		return errPrintedOutput
  2308  	}
  2309  	return nil
  2310  }
  2311  
  2312  func packInternal(b *Builder, afile string, ofiles []string) error {
  2313  	dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
  2314  	if err != nil {
  2315  		return err
  2316  	}
  2317  	defer dst.Close() // only for error returns or panics
  2318  	w := bufio.NewWriter(dst)
  2319  
  2320  	for _, ofile := range ofiles {
  2321  		src, err := os.Open(ofile)
  2322  		if err != nil {
  2323  			return err
  2324  		}
  2325  		fi, err := src.Stat()
  2326  		if err != nil {
  2327  			src.Close()
  2328  			return err
  2329  		}
  2330  		// Note: Not using %-16.16s format because we care
  2331  		// about bytes, not runes.
  2332  		name := fi.Name()
  2333  		if len(name) > 16 {
  2334  			name = name[:16]
  2335  		} else {
  2336  			name += strings.Repeat(" ", 16-len(name))
  2337  		}
  2338  		size := fi.Size()
  2339  		fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
  2340  			name, 0, 0, 0, 0644, size)
  2341  		n, err := io.Copy(w, src)
  2342  		src.Close()
  2343  		if err == nil && n < size {
  2344  			err = io.ErrUnexpectedEOF
  2345  		} else if err == nil && n > size {
  2346  			err = fmt.Errorf("file larger than size reported by stat")
  2347  		}
  2348  		if err != nil {
  2349  			return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
  2350  		}
  2351  		if size&1 != 0 {
  2352  			w.WriteByte(0)
  2353  		}
  2354  	}
  2355  
  2356  	if err := w.Flush(); err != nil {
  2357  		return err
  2358  	}
  2359  	return dst.Close()
  2360  }
  2361  
  2362  // setextld sets the appropriate linker flags for the specified compiler.
  2363  func setextld(ldflags []string, compiler []string) []string {
  2364  	for _, f := range ldflags {
  2365  		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
  2366  			// don't override -extld if supplied
  2367  			return ldflags
  2368  		}
  2369  	}
  2370  	ldflags = append(ldflags, "-extld="+compiler[0])
  2371  	if len(compiler) > 1 {
  2372  		extldflags := false
  2373  		add := strings.Join(compiler[1:], " ")
  2374  		for i, f := range ldflags {
  2375  			if f == "-extldflags" && i+1 < len(ldflags) {
  2376  				ldflags[i+1] = add + " " + ldflags[i+1]
  2377  				extldflags = true
  2378  				break
  2379  			} else if strings.HasPrefix(f, "-extldflags=") {
  2380  				ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
  2381  				extldflags = true
  2382  				break
  2383  			}
  2384  		}
  2385  		if !extldflags {
  2386  			ldflags = append(ldflags, "-extldflags="+add)
  2387  		}
  2388  	}
  2389  	return ldflags
  2390  }
  2391  
  2392  func (gcToolchain) ld(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string) error {
  2393  	importArgs := b.includeArgs("-L", allactions)
  2394  	cxx := len(root.Package.CXXFiles) > 0 || len(root.Package.SwigCXXFiles) > 0
  2395  	for _, a := range allactions {
  2396  		if a.Package != nil && (len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0) {
  2397  			cxx = true
  2398  		}
  2399  	}
  2400  	var ldflags []string
  2401  	if cfg.BuildContext.InstallSuffix != "" {
  2402  		ldflags = append(ldflags, "-installsuffix", cfg.BuildContext.InstallSuffix)
  2403  	}
  2404  	if root.Package.Internal.OmitDWARF {
  2405  		ldflags = append(ldflags, "-w")
  2406  	}
  2407  	if cfg.BuildBuildmode == "plugin" {
  2408  		pluginpath := root.Package.ImportPath
  2409  		if pluginpath == "command-line-arguments" {
  2410  			pluginpath = "plugin/unnamed-" + root.Package.Internal.BuildID
  2411  		}
  2412  		ldflags = append(ldflags, "-pluginpath", pluginpath)
  2413  	}
  2414  
  2415  	// If the user has not specified the -extld option, then specify the
  2416  	// appropriate linker. In case of C++ code, use the compiler named
  2417  	// by the CXX environment variable or defaultCXX if CXX is not set.
  2418  	// Else, use the CC environment variable and defaultCC as fallback.
  2419  	var compiler []string
  2420  	if cxx {
  2421  		compiler = envList("CXX", cfg.DefaultCXX)
  2422  	} else {
  2423  		compiler = envList("CC", cfg.DefaultCC)
  2424  	}
  2425  	ldflags = setextld(ldflags, compiler)
  2426  	ldflags = append(ldflags, "-buildmode="+ldBuildmode)
  2427  	if root.Package.Internal.BuildID != "" {
  2428  		ldflags = append(ldflags, "-buildid="+root.Package.Internal.BuildID)
  2429  	}
  2430  	ldflags = append(ldflags, cfg.BuildLdflags...)
  2431  
  2432  	// On OS X when using external linking to build a shared library,
  2433  	// the argument passed here to -o ends up recorded in the final
  2434  	// shared library in the LC_ID_DYLIB load command.
  2435  	// To avoid putting the temporary output directory name there
  2436  	// (and making the resulting shared library useless),
  2437  	// run the link in the output directory so that -o can name
  2438  	// just the final path element.
  2439  	dir := "."
  2440  	if cfg.Goos == "darwin" && cfg.BuildBuildmode == "c-shared" {
  2441  		dir, out = filepath.Split(out)
  2442  	}
  2443  
  2444  	return b.run(dir, root.Package.ImportPath, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, importArgs, ldflags, mainpkg)
  2445  }
  2446  
  2447  func (gcToolchain) ldShared(b *Builder, toplevelactions []*Action, out string, allactions []*Action) error {
  2448  	importArgs := b.includeArgs("-L", allactions)
  2449  	ldflags := []string{"-installsuffix", cfg.BuildContext.InstallSuffix}
  2450  	ldflags = append(ldflags, "-buildmode=shared")
  2451  	ldflags = append(ldflags, cfg.BuildLdflags...)
  2452  	cxx := false
  2453  	for _, a := range allactions {
  2454  		if a.Package != nil && (len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0) {
  2455  			cxx = true
  2456  		}
  2457  	}
  2458  	// If the user has not specified the -extld option, then specify the
  2459  	// appropriate linker. In case of C++ code, use the compiler named
  2460  	// by the CXX environment variable or defaultCXX if CXX is not set.
  2461  	// Else, use the CC environment variable and defaultCC as fallback.
  2462  	var compiler []string
  2463  	if cxx {
  2464  		compiler = envList("CXX", cfg.DefaultCXX)
  2465  	} else {
  2466  		compiler = envList("CC", cfg.DefaultCC)
  2467  	}
  2468  	ldflags = setextld(ldflags, compiler)
  2469  	for _, d := range toplevelactions {
  2470  		if !strings.HasSuffix(d.Target, ".a") { // omit unsafe etc and actions for other shared libraries
  2471  			continue
  2472  		}
  2473  		ldflags = append(ldflags, d.Package.ImportPath+"="+d.Target)
  2474  	}
  2475  	return b.run(".", out, nil, cfg.BuildToolexec, base.Tool("link"), "-o", out, importArgs, ldflags)
  2476  }
  2477  
  2478  func (gcToolchain) cc(b *Builder, p *load.Package, objdir, ofile, cfile string) error {
  2479  	return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
  2480  }
  2481  
  2482  // The Gccgo toolchain.
  2483  type gccgoToolchain struct{}
  2484  
  2485  var GccgoName, GccgoBin string
  2486  
  2487  func init() {
  2488  	GccgoName = os.Getenv("GCCGO")
  2489  	if GccgoName == "" {
  2490  		GccgoName = "gccgo"
  2491  	}
  2492  	GccgoBin, _ = exec.LookPath(GccgoName)
  2493  }
  2494  
  2495  func (gccgoToolchain) compiler() string {
  2496  	return GccgoBin
  2497  }
  2498  
  2499  func (gccgoToolchain) linker() string {
  2500  	return GccgoBin
  2501  }
  2502  
  2503  func (tools gccgoToolchain) gc(b *Builder, p *load.Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
  2504  	out := "_go_.o"
  2505  	ofile = obj + out
  2506  	gcargs := []string{"-g"}
  2507  	gcargs = append(gcargs, b.gccArchArgs()...)
  2508  	if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  2509  		gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
  2510  	}
  2511  	if p.Internal.LocalPrefix != "" {
  2512  		gcargs = append(gcargs, "-fgo-relative-import-path="+p.Internal.LocalPrefix)
  2513  	}
  2514  	args := str.StringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
  2515  	for _, f := range gofiles {
  2516  		args = append(args, mkAbs(p.Dir, f))
  2517  	}
  2518  
  2519  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
  2520  	return ofile, output, err
  2521  }
  2522  
  2523  func (tools gccgoToolchain) asm(b *Builder, p *load.Package, obj string, sfiles []string) ([]string, error) {
  2524  	var ofiles []string
  2525  	for _, sfile := range sfiles {
  2526  		ofile := obj + sfile[:len(sfile)-len(".s")] + ".o"
  2527  		ofiles = append(ofiles, ofile)
  2528  		sfile = mkAbs(p.Dir, sfile)
  2529  		defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
  2530  		if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  2531  			defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath)
  2532  		}
  2533  		defs = tools.maybePIC(defs)
  2534  		defs = append(defs, b.gccArchArgs()...)
  2535  		err := b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-xassembler-with-cpp", "-I", obj, "-c", "-o", ofile, defs, sfile)
  2536  		if err != nil {
  2537  			return nil, err
  2538  		}
  2539  	}
  2540  	return ofiles, nil
  2541  }
  2542  
  2543  func (gccgoToolchain) Pkgpath(basedir string, p *load.Package) string {
  2544  	end := filepath.FromSlash(p.ImportPath + ".a")
  2545  	afile := filepath.Join(basedir, end)
  2546  	// add "lib" to the final element
  2547  	return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
  2548  }
  2549  
  2550  func (gccgoToolchain) pack(b *Builder, p *load.Package, objDir, afile string, ofiles []string) error {
  2551  	var absOfiles []string
  2552  	for _, f := range ofiles {
  2553  		absOfiles = append(absOfiles, mkAbs(objDir, f))
  2554  	}
  2555  	return b.run(p.Dir, p.ImportPath, nil, "ar", "rc", mkAbs(objDir, afile), absOfiles)
  2556  }
  2557  
  2558  func (tools gccgoToolchain) link(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string, buildmode, desc string) error {
  2559  	// gccgo needs explicit linking with all package dependencies,
  2560  	// and all LDFLAGS from cgo dependencies.
  2561  	apackagePathsSeen := make(map[string]bool)
  2562  	afiles := []string{}
  2563  	shlibs := []string{}
  2564  	ldflags := b.gccArchArgs()
  2565  	cgoldflags := []string{}
  2566  	usesCgo := false
  2567  	cxx := false
  2568  	objc := false
  2569  	fortran := false
  2570  	if root.Package != nil {
  2571  		cxx = len(root.Package.CXXFiles) > 0 || len(root.Package.SwigCXXFiles) > 0
  2572  		objc = len(root.Package.MFiles) > 0
  2573  		fortran = len(root.Package.FFiles) > 0
  2574  	}
  2575  
  2576  	readCgoFlags := func(flagsFile string) error {
  2577  		flags, err := ioutil.ReadFile(flagsFile)
  2578  		if err != nil {
  2579  			return err
  2580  		}
  2581  		const ldflagsPrefix = "_CGO_LDFLAGS="
  2582  		for _, line := range strings.Split(string(flags), "\n") {
  2583  			if strings.HasPrefix(line, ldflagsPrefix) {
  2584  				newFlags := strings.Fields(line[len(ldflagsPrefix):])
  2585  				for _, flag := range newFlags {
  2586  					// Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
  2587  					// but they don't mean anything to the linker so filter
  2588  					// them out.
  2589  					if flag != "-g" && !strings.HasPrefix(flag, "-O") {
  2590  						cgoldflags = append(cgoldflags, flag)
  2591  					}
  2592  				}
  2593  			}
  2594  		}
  2595  		return nil
  2596  	}
  2597  
  2598  	readAndRemoveCgoFlags := func(archive string) (string, error) {
  2599  		newa, err := ioutil.TempFile(b.WorkDir, filepath.Base(archive))
  2600  		if err != nil {
  2601  			return "", err
  2602  		}
  2603  		olda, err := os.Open(archive)
  2604  		if err != nil {
  2605  			return "", err
  2606  		}
  2607  		_, err = io.Copy(newa, olda)
  2608  		if err != nil {
  2609  			return "", err
  2610  		}
  2611  		err = olda.Close()
  2612  		if err != nil {
  2613  			return "", err
  2614  		}
  2615  		err = newa.Close()
  2616  		if err != nil {
  2617  			return "", err
  2618  		}
  2619  
  2620  		newarchive := newa.Name()
  2621  		err = b.run(b.WorkDir, desc, nil, "ar", "x", newarchive, "_cgo_flags")
  2622  		if err != nil {
  2623  			return "", err
  2624  		}
  2625  		err = b.run(".", desc, nil, "ar", "d", newarchive, "_cgo_flags")
  2626  		if err != nil {
  2627  			return "", err
  2628  		}
  2629  		err = readCgoFlags(filepath.Join(b.WorkDir, "_cgo_flags"))
  2630  		if err != nil {
  2631  			return "", err
  2632  		}
  2633  		return newarchive, nil
  2634  	}
  2635  
  2636  	actionsSeen := make(map[*Action]bool)
  2637  	// Make a pre-order depth-first traversal of the action graph, taking note of
  2638  	// whether a shared library action has been seen on the way to an action (the
  2639  	// construction of the graph means that if any path to a node passes through
  2640  	// a shared library action, they all do).
  2641  	var walk func(a *Action, seenShlib bool)
  2642  	var err error
  2643  	walk = func(a *Action, seenShlib bool) {
  2644  		if actionsSeen[a] {
  2645  			return
  2646  		}
  2647  		actionsSeen[a] = true
  2648  		if a.Package != nil && !seenShlib {
  2649  			if a.Package.Standard {
  2650  				return
  2651  			}
  2652  			// We record the target of the first time we see a .a file
  2653  			// for a package to make sure that we prefer the 'install'
  2654  			// rather than the 'build' location (which may not exist any
  2655  			// more). We still need to traverse the dependencies of the
  2656  			// build action though so saying
  2657  			// if apackagePathsSeen[a.Package.ImportPath] { return }
  2658  			// doesn't work.
  2659  			if !apackagePathsSeen[a.Package.ImportPath] {
  2660  				apackagePathsSeen[a.Package.ImportPath] = true
  2661  				target := a.Target
  2662  				if len(a.Package.CgoFiles) > 0 || a.Package.UsesSwig() {
  2663  					target, err = readAndRemoveCgoFlags(target)
  2664  					if err != nil {
  2665  						return
  2666  					}
  2667  				}
  2668  				afiles = append(afiles, target)
  2669  			}
  2670  		}
  2671  		if strings.HasSuffix(a.Target, ".so") {
  2672  			shlibs = append(shlibs, a.Target)
  2673  			seenShlib = true
  2674  		}
  2675  		for _, a1 := range a.Deps {
  2676  			walk(a1, seenShlib)
  2677  			if err != nil {
  2678  				return
  2679  			}
  2680  		}
  2681  	}
  2682  	for _, a1 := range root.Deps {
  2683  		walk(a1, false)
  2684  		if err != nil {
  2685  			return err
  2686  		}
  2687  	}
  2688  
  2689  	for _, a := range allactions {
  2690  		// Gather CgoLDFLAGS, but not from standard packages.
  2691  		// The go tool can dig up runtime/cgo from GOROOT and
  2692  		// think that it should use its CgoLDFLAGS, but gccgo
  2693  		// doesn't use runtime/cgo.
  2694  		if a.Package == nil {
  2695  			continue
  2696  		}
  2697  		if !a.Package.Standard {
  2698  			cgoldflags = append(cgoldflags, a.Package.CgoLDFLAGS...)
  2699  		}
  2700  		if len(a.Package.CgoFiles) > 0 {
  2701  			usesCgo = true
  2702  		}
  2703  		if a.Package.UsesSwig() {
  2704  			usesCgo = true
  2705  		}
  2706  		if len(a.Package.CXXFiles) > 0 || len(a.Package.SwigCXXFiles) > 0 {
  2707  			cxx = true
  2708  		}
  2709  		if len(a.Package.MFiles) > 0 {
  2710  			objc = true
  2711  		}
  2712  		if len(a.Package.FFiles) > 0 {
  2713  			fortran = true
  2714  		}
  2715  	}
  2716  
  2717  	for i, o := range ofiles {
  2718  		if filepath.Base(o) == "_cgo_flags" {
  2719  			readCgoFlags(o)
  2720  			ofiles = append(ofiles[:i], ofiles[i+1:]...)
  2721  			break
  2722  		}
  2723  	}
  2724  
  2725  	ldflags = append(ldflags, "-Wl,--whole-archive")
  2726  	ldflags = append(ldflags, afiles...)
  2727  	ldflags = append(ldflags, "-Wl,--no-whole-archive")
  2728  
  2729  	ldflags = append(ldflags, cgoldflags...)
  2730  	ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
  2731  	if root.Package != nil {
  2732  		ldflags = append(ldflags, root.Package.CgoLDFLAGS...)
  2733  	}
  2734  
  2735  	ldflags = str.StringList("-Wl,-(", ldflags, "-Wl,-)")
  2736  
  2737  	for _, shlib := range shlibs {
  2738  		ldflags = append(
  2739  			ldflags,
  2740  			"-L"+filepath.Dir(shlib),
  2741  			"-Wl,-rpath="+filepath.Dir(shlib),
  2742  			"-l"+strings.TrimSuffix(
  2743  				strings.TrimPrefix(filepath.Base(shlib), "lib"),
  2744  				".so"))
  2745  	}
  2746  
  2747  	var realOut string
  2748  	switch buildmode {
  2749  	case "exe":
  2750  		if usesCgo && cfg.Goos == "linux" {
  2751  			ldflags = append(ldflags, "-Wl,-E")
  2752  		}
  2753  
  2754  	case "c-archive":
  2755  		// Link the Go files into a single .o, and also link
  2756  		// in -lgolibbegin.
  2757  		//
  2758  		// We need to use --whole-archive with -lgolibbegin
  2759  		// because it doesn't define any symbols that will
  2760  		// cause the contents to be pulled in; it's just
  2761  		// initialization code.
  2762  		//
  2763  		// The user remains responsible for linking against
  2764  		// -lgo -lpthread -lm in the final link. We can't use
  2765  		// -r to pick them up because we can't combine
  2766  		// split-stack and non-split-stack code in a single -r
  2767  		// link, and libgo picks up non-split-stack code from
  2768  		// libffi.
  2769  		ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
  2770  
  2771  		if b.gccSupportsNoPie() {
  2772  			ldflags = append(ldflags, "-no-pie")
  2773  		}
  2774  
  2775  		// We are creating an object file, so we don't want a build ID.
  2776  		ldflags = b.disableBuildID(ldflags)
  2777  
  2778  		realOut = out
  2779  		out = out + ".o"
  2780  
  2781  	case "c-shared":
  2782  		ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc", "-lc", "-lgcc")
  2783  	case "shared":
  2784  		ldflags = append(ldflags, "-zdefs", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc")
  2785  
  2786  	default:
  2787  		base.Fatalf("-buildmode=%s not supported for gccgo", buildmode)
  2788  	}
  2789  
  2790  	switch buildmode {
  2791  	case "exe", "c-shared":
  2792  		if cxx {
  2793  			ldflags = append(ldflags, "-lstdc++")
  2794  		}
  2795  		if objc {
  2796  			ldflags = append(ldflags, "-lobjc")
  2797  		}
  2798  		if fortran {
  2799  			fc := os.Getenv("FC")
  2800  			if fc == "" {
  2801  				fc = "gfortran"
  2802  			}
  2803  			// support gfortran out of the box and let others pass the correct link options
  2804  			// via CGO_LDFLAGS
  2805  			if strings.Contains(fc, "gfortran") {
  2806  				ldflags = append(ldflags, "-lgfortran")
  2807  			}
  2808  		}
  2809  	}
  2810  
  2811  	if err := b.run(".", desc, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil {
  2812  		return err
  2813  	}
  2814  
  2815  	switch buildmode {
  2816  	case "c-archive":
  2817  		if err := b.run(".", desc, nil, "ar", "rc", realOut, out); err != nil {
  2818  			return err
  2819  		}
  2820  	}
  2821  	return nil
  2822  }
  2823  
  2824  func (tools gccgoToolchain) ld(b *Builder, root *Action, out string, allactions []*Action, mainpkg string, ofiles []string) error {
  2825  	return tools.link(b, root, out, allactions, mainpkg, ofiles, ldBuildmode, root.Package.ImportPath)
  2826  }
  2827  
  2828  func (tools gccgoToolchain) ldShared(b *Builder, toplevelactions []*Action, out string, allactions []*Action) error {
  2829  	fakeRoot := &Action{}
  2830  	fakeRoot.Deps = toplevelactions
  2831  	return tools.link(b, fakeRoot, out, allactions, "", nil, "shared", out)
  2832  }
  2833  
  2834  func (tools gccgoToolchain) cc(b *Builder, p *load.Package, objdir, ofile, cfile string) error {
  2835  	inc := filepath.Join(cfg.GOROOT, "pkg", "include")
  2836  	cfile = mkAbs(p.Dir, cfile)
  2837  	defs := []string{"-D", "GOOS_" + cfg.Goos, "-D", "GOARCH_" + cfg.Goarch}
  2838  	defs = append(defs, b.gccArchArgs()...)
  2839  	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  2840  		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
  2841  	}
  2842  	switch cfg.Goarch {
  2843  	case "386", "amd64":
  2844  		defs = append(defs, "-fsplit-stack")
  2845  	}
  2846  	defs = tools.maybePIC(defs)
  2847  	return b.run(p.Dir, p.ImportPath, nil, envList("CC", cfg.DefaultCC), "-Wall", "-g",
  2848  		"-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
  2849  }
  2850  
  2851  // maybePIC adds -fPIC to the list of arguments if needed.
  2852  func (tools gccgoToolchain) maybePIC(args []string) []string {
  2853  	switch cfg.BuildBuildmode {
  2854  	case "c-shared", "shared", "plugin":
  2855  		args = append(args, "-fPIC")
  2856  	}
  2857  	return args
  2858  }
  2859  
  2860  func gccgoPkgpath(p *load.Package) string {
  2861  	if p.Internal.Build.IsCommand() && !p.Internal.ForceLibrary {
  2862  		return ""
  2863  	}
  2864  	return p.ImportPath
  2865  }
  2866  
  2867  func gccgoCleanPkgpath(p *load.Package) string {
  2868  	clean := func(r rune) rune {
  2869  		switch {
  2870  		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
  2871  			'0' <= r && r <= '9':
  2872  			return r
  2873  		}
  2874  		return '_'
  2875  	}
  2876  	return strings.Map(clean, gccgoPkgpath(p))
  2877  }
  2878  
  2879  // gcc runs the gcc C compiler to create an object from a single C file.
  2880  func (b *Builder) gcc(p *load.Package, out string, flags []string, cfile string) error {
  2881  	return b.ccompile(p, out, flags, cfile, b.GccCmd(p.Dir))
  2882  }
  2883  
  2884  // gxx runs the g++ C++ compiler to create an object from a single C++ file.
  2885  func (b *Builder) gxx(p *load.Package, out string, flags []string, cxxfile string) error {
  2886  	return b.ccompile(p, out, flags, cxxfile, b.GxxCmd(p.Dir))
  2887  }
  2888  
  2889  // gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.
  2890  func (b *Builder) gfortran(p *load.Package, out string, flags []string, ffile string) error {
  2891  	return b.ccompile(p, out, flags, ffile, b.gfortranCmd(p.Dir))
  2892  }
  2893  
  2894  // ccompile runs the given C or C++ compiler and creates an object from a single source file.
  2895  func (b *Builder) ccompile(p *load.Package, outfile string, flags []string, file string, compiler []string) error {
  2896  	file = mkAbs(p.Dir, file)
  2897  	desc := p.ImportPath
  2898  	output, err := b.runOut(p.Dir, desc, nil, compiler, flags, "-o", outfile, "-c", file)
  2899  	if len(output) > 0 {
  2900  		b.showOutput(p.Dir, desc, b.processOutput(output))
  2901  		if err != nil {
  2902  			err = errPrintedOutput
  2903  		} else if os.Getenv("GO_BUILDER_NAME") != "" {
  2904  			return errors.New("C compiler warning promoted to error on Go builders")
  2905  		}
  2906  	}
  2907  	return err
  2908  }
  2909  
  2910  // gccld runs the gcc linker to create an executable from a set of object files.
  2911  func (b *Builder) gccld(p *load.Package, out string, flags []string, obj []string) error {
  2912  	var cmd []string
  2913  	if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
  2914  		cmd = b.GxxCmd(p.Dir)
  2915  	} else {
  2916  		cmd = b.GccCmd(p.Dir)
  2917  	}
  2918  	return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
  2919  }
  2920  
  2921  // gccCmd returns a gcc command line prefix
  2922  // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
  2923  func (b *Builder) GccCmd(objdir string) []string {
  2924  	return b.ccompilerCmd("CC", cfg.DefaultCC, objdir)
  2925  }
  2926  
  2927  // gxxCmd returns a g++ command line prefix
  2928  // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
  2929  func (b *Builder) GxxCmd(objdir string) []string {
  2930  	return b.ccompilerCmd("CXX", cfg.DefaultCXX, objdir)
  2931  }
  2932  
  2933  // gfortranCmd returns a gfortran command line prefix.
  2934  func (b *Builder) gfortranCmd(objdir string) []string {
  2935  	return b.ccompilerCmd("FC", "gfortran", objdir)
  2936  }
  2937  
  2938  // ccompilerCmd returns a command line prefix for the given environment
  2939  // variable and using the default command when the variable is empty.
  2940  func (b *Builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
  2941  	// NOTE: env.go's mkEnv knows that the first three
  2942  	// strings returned are "gcc", "-I", objdir (and cuts them off).
  2943  
  2944  	compiler := envList(envvar, defcmd)
  2945  	a := []string{compiler[0], "-I", objdir}
  2946  	a = append(a, compiler[1:]...)
  2947  
  2948  	// Definitely want -fPIC but on Windows gcc complains
  2949  	// "-fPIC ignored for target (all code is position independent)"
  2950  	if cfg.Goos != "windows" {
  2951  		a = append(a, "-fPIC")
  2952  	}
  2953  	a = append(a, b.gccArchArgs()...)
  2954  	// gcc-4.5 and beyond require explicit "-pthread" flag
  2955  	// for multithreading with pthread library.
  2956  	if cfg.BuildContext.CgoEnabled {
  2957  		switch cfg.Goos {
  2958  		case "windows":
  2959  			a = append(a, "-mthreads")
  2960  		default:
  2961  			a = append(a, "-pthread")
  2962  		}
  2963  	}
  2964  
  2965  	if strings.Contains(a[0], "clang") {
  2966  		// disable ASCII art in clang errors, if possible
  2967  		a = append(a, "-fno-caret-diagnostics")
  2968  		// clang is too smart about command-line arguments
  2969  		a = append(a, "-Qunused-arguments")
  2970  	}
  2971  
  2972  	// disable word wrapping in error messages
  2973  	a = append(a, "-fmessage-length=0")
  2974  
  2975  	// Tell gcc not to include the work directory in object files.
  2976  	if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
  2977  		a = append(a, "-fdebug-prefix-map="+b.WorkDir+"=/tmp/go-build")
  2978  	}
  2979  
  2980  	// Tell gcc not to include flags in object files, which defeats the
  2981  	// point of -fdebug-prefix-map above.
  2982  	if b.gccSupportsFlag("-gno-record-gcc-switches") {
  2983  		a = append(a, "-gno-record-gcc-switches")
  2984  	}
  2985  
  2986  	// On OS X, some of the compilers behave as if -fno-common
  2987  	// is always set, and the Mach-O linker in 6l/8l assumes this.
  2988  	// See https://golang.org/issue/3253.
  2989  	if cfg.Goos == "darwin" {
  2990  		a = append(a, "-fno-common")
  2991  	}
  2992  
  2993  	return a
  2994  }
  2995  
  2996  // On systems with PIE (position independent executables) enabled by default,
  2997  // -no-pie must be passed when doing a partial link with -Wl,-r. But -no-pie is
  2998  // not supported by all compilers.
  2999  func (b *Builder) gccSupportsNoPie() bool {
  3000  	return b.gccSupportsFlag("-no-pie")
  3001  }
  3002  
  3003  // gccSupportsFlag checks to see if the compiler supports a flag.
  3004  func (b *Builder) gccSupportsFlag(flag string) bool {
  3005  	b.exec.Lock()
  3006  	defer b.exec.Unlock()
  3007  	if b, ok := b.flagCache[flag]; ok {
  3008  		return b
  3009  	}
  3010  	if b.flagCache == nil {
  3011  		src := filepath.Join(b.WorkDir, "trivial.c")
  3012  		if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
  3013  			return false
  3014  		}
  3015  		b.flagCache = make(map[string]bool)
  3016  	}
  3017  	cmdArgs := append(envList("CC", cfg.DefaultCC), flag, "-c", "trivial.c")
  3018  	if cfg.BuildN || cfg.BuildX {
  3019  		b.Showcmd(b.WorkDir, "%s", joinUnambiguously(cmdArgs))
  3020  		if cfg.BuildN {
  3021  			return false
  3022  		}
  3023  	}
  3024  	cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
  3025  	cmd.Dir = b.WorkDir
  3026  	cmd.Env = base.MergeEnvLists([]string{"LC_ALL=C"}, base.EnvForDir(cmd.Dir, os.Environ()))
  3027  	out, err := cmd.CombinedOutput()
  3028  	supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
  3029  	b.flagCache[flag] = supported
  3030  	return supported
  3031  }
  3032  
  3033  // gccArchArgs returns arguments to pass to gcc based on the architecture.
  3034  func (b *Builder) gccArchArgs() []string {
  3035  	switch cfg.Goarch {
  3036  	case "386":
  3037  		return []string{"-m32"}
  3038  	case "amd64", "amd64p32":
  3039  		return []string{"-m64"}
  3040  	case "arm":
  3041  		return []string{"-marm"} // not thumb
  3042  	case "s390x":
  3043  		return []string{"-m64", "-march=z196"}
  3044  	case "mips64", "mips64le":
  3045  		return []string{"-mabi=64"}
  3046  	case "mips", "mipsle":
  3047  		return []string{"-mabi=32", "-march=mips32"}
  3048  	}
  3049  	return nil
  3050  }
  3051  
  3052  // envList returns the value of the given environment variable broken
  3053  // into fields, using the default value when the variable is empty.
  3054  func envList(key, def string) []string {
  3055  	v := os.Getenv(key)
  3056  	if v == "" {
  3057  		v = def
  3058  	}
  3059  	return strings.Fields(v)
  3060  }
  3061  
  3062  // CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
  3063  func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, ldflags []string) {
  3064  	defaults := "-g -O2"
  3065  
  3066  	cppflags = str.StringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
  3067  	cflags = str.StringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
  3068  	cxxflags = str.StringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
  3069  	fflags = str.StringList(envList("CGO_FFLAGS", defaults), p.CgoFFLAGS)
  3070  	ldflags = str.StringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
  3071  	return
  3072  }
  3073  
  3074  var cgoRe = regexp.MustCompile(`[/\\:]`)
  3075  
  3076  func (b *Builder) cgo(a *Action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofiles, objdirCgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) {
  3077  	p := a.Package
  3078  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS := b.CFlags(p)
  3079  	cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
  3080  	cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
  3081  	// If we are compiling Objective-C code, then we need to link against libobjc
  3082  	if len(mfiles) > 0 {
  3083  		cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
  3084  	}
  3085  
  3086  	// Likewise for Fortran, except there are many Fortran compilers.
  3087  	// Support gfortran out of the box and let others pass the correct link options
  3088  	// via CGO_LDFLAGS
  3089  	if len(ffiles) > 0 {
  3090  		fc := os.Getenv("FC")
  3091  		if fc == "" {
  3092  			fc = "gfortran"
  3093  		}
  3094  		if strings.Contains(fc, "gfortran") {
  3095  			cgoLDFLAGS = append(cgoLDFLAGS, "-lgfortran")
  3096  		}
  3097  	}
  3098  
  3099  	if cfg.BuildMSan {
  3100  		cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
  3101  		cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
  3102  	}
  3103  
  3104  	// Allows including _cgo_export.h from .[ch] files in the package.
  3105  	cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
  3106  
  3107  	// If we have cgo files in the object directory, then copy any
  3108  	// other cgo files into the object directory, and pass a
  3109  	// -srcdir option to cgo.
  3110  	var srcdirarg []string
  3111  	if len(objdirCgofiles) > 0 {
  3112  		for _, fn := range cgofiles {
  3113  			if err := b.copyFile(a, obj+filepath.Base(fn), filepath.Join(p.Dir, fn), 0666, false); err != nil {
  3114  				return nil, nil, err
  3115  			}
  3116  		}
  3117  		cgofiles = append(cgofiles, objdirCgofiles...)
  3118  		srcdirarg = []string{"-srcdir", obj}
  3119  	}
  3120  
  3121  	// cgo
  3122  	// TODO: CGO_FLAGS?
  3123  	gofiles := []string{obj + "_cgo_gotypes.go"}
  3124  	cfiles := []string{"_cgo_export.c"}
  3125  	for _, fn := range cgofiles {
  3126  		f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
  3127  		gofiles = append(gofiles, obj+f+"cgo1.go")
  3128  		cfiles = append(cfiles, f+"cgo2.c")
  3129  	}
  3130  
  3131  	// TODO: make cgo not depend on $GOARCH?
  3132  
  3133  	cgoflags := []string{}
  3134  	if p.Standard && p.ImportPath == "runtime/cgo" {
  3135  		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
  3136  	}
  3137  	if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") {
  3138  		cgoflags = append(cgoflags, "-import_syscall=false")
  3139  	}
  3140  
  3141  	// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
  3142  	var cgoenv []string
  3143  	if len(cgoLDFLAGS) > 0 {
  3144  		flags := make([]string, len(cgoLDFLAGS))
  3145  		for i, f := range cgoLDFLAGS {
  3146  			flags[i] = strconv.Quote(f)
  3147  		}
  3148  		cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
  3149  	}
  3150  
  3151  	if cfg.BuildToolchainName == "gccgo" {
  3152  		switch cfg.Goarch {
  3153  		case "386", "amd64":
  3154  			cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
  3155  		}
  3156  		cgoflags = append(cgoflags, "-gccgo")
  3157  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  3158  			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
  3159  		}
  3160  	}
  3161  
  3162  	switch cfg.BuildBuildmode {
  3163  	case "c-archive", "c-shared":
  3164  		// Tell cgo that if there are any exported functions
  3165  		// it should generate a header file that C code can
  3166  		// #include.
  3167  		cgoflags = append(cgoflags, "-exportheader="+obj+"_cgo_install.h")
  3168  	}
  3169  
  3170  	if err := b.run(p.Dir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, srcdirarg, "-objdir", obj, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil {
  3171  		return nil, nil, err
  3172  	}
  3173  	outGo = append(outGo, gofiles...)
  3174  
  3175  	// gcc
  3176  	cflags := str.StringList(cgoCPPFLAGS, cgoCFLAGS)
  3177  	for _, cfile := range cfiles {
  3178  		ofile := obj + cfile[:len(cfile)-1] + "o"
  3179  		if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
  3180  			return nil, nil, err
  3181  		}
  3182  		outObj = append(outObj, ofile)
  3183  	}
  3184  
  3185  	for _, file := range gccfiles {
  3186  		base := filepath.Base(file)
  3187  		ofile := obj + cgoRe.ReplaceAllString(base[:len(base)-1], "_") + "o"
  3188  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  3189  			return nil, nil, err
  3190  		}
  3191  		outObj = append(outObj, ofile)
  3192  	}
  3193  
  3194  	cxxflags := str.StringList(cgoCPPFLAGS, cgoCXXFLAGS)
  3195  	for _, file := range gxxfiles {
  3196  		// Append .o to the file, just in case the pkg has file.c and file.cpp
  3197  		ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
  3198  		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
  3199  			return nil, nil, err
  3200  		}
  3201  		outObj = append(outObj, ofile)
  3202  	}
  3203  
  3204  	for _, file := range mfiles {
  3205  		// Append .o to the file, just in case the pkg has file.c and file.m
  3206  		ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
  3207  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  3208  			return nil, nil, err
  3209  		}
  3210  		outObj = append(outObj, ofile)
  3211  	}
  3212  
  3213  	fflags := str.StringList(cgoCPPFLAGS, cgoFFLAGS)
  3214  	for _, file := range ffiles {
  3215  		// Append .o to the file, just in case the pkg has file.c and file.f
  3216  		ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
  3217  		if err := b.gfortran(p, ofile, fflags, file); err != nil {
  3218  			return nil, nil, err
  3219  		}
  3220  		outObj = append(outObj, ofile)
  3221  	}
  3222  
  3223  	switch cfg.BuildToolchainName {
  3224  	case "gc":
  3225  		importGo := obj + "_cgo_import.go"
  3226  		if err := b.dynimport(p, obj, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil {
  3227  			return nil, nil, err
  3228  		}
  3229  		outGo = append(outGo, importGo)
  3230  
  3231  		ofile := obj + "_all.o"
  3232  		if err := b.collect(p, obj, ofile, cgoLDFLAGS, outObj); err != nil {
  3233  			return nil, nil, err
  3234  		}
  3235  		outObj = []string{ofile}
  3236  
  3237  	case "gccgo":
  3238  		defunC := obj + "_cgo_defun.c"
  3239  		defunObj := obj + "_cgo_defun.o"
  3240  		if err := BuildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
  3241  			return nil, nil, err
  3242  		}
  3243  		outObj = append(outObj, defunObj)
  3244  
  3245  	default:
  3246  		noCompiler()
  3247  	}
  3248  
  3249  	return outGo, outObj, nil
  3250  }
  3251  
  3252  // dynimport creates a Go source file named importGo containing
  3253  // //go:cgo_import_dynamic directives for each symbol or library
  3254  // dynamically imported by the object files outObj.
  3255  func (b *Builder) dynimport(p *load.Package, obj, importGo, cgoExe string, cflags, cgoLDFLAGS, outObj []string) error {
  3256  	cfile := obj + "_cgo_main.c"
  3257  	ofile := obj + "_cgo_main.o"
  3258  	if err := b.gcc(p, ofile, cflags, cfile); err != nil {
  3259  		return err
  3260  	}
  3261  
  3262  	linkobj := str.StringList(ofile, outObj, p.SysoFiles)
  3263  	dynobj := obj + "_cgo_.o"
  3264  
  3265  	// we need to use -pie for Linux/ARM to get accurate imported sym
  3266  	ldflags := cgoLDFLAGS
  3267  	if (cfg.Goarch == "arm" && cfg.Goos == "linux") || cfg.Goos == "android" {
  3268  		ldflags = append(ldflags, "-pie")
  3269  	}
  3270  	if err := b.gccld(p, dynobj, ldflags, linkobj); err != nil {
  3271  		return err
  3272  	}
  3273  
  3274  	// cgo -dynimport
  3275  	var cgoflags []string
  3276  	if p.Standard && p.ImportPath == "runtime/cgo" {
  3277  		cgoflags = []string{"-dynlinker"} // record path to dynamic linker
  3278  	}
  3279  	return b.run(p.Dir, p.ImportPath, nil, cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
  3280  }
  3281  
  3282  // collect partially links the object files outObj into a single
  3283  // relocatable object file named ofile.
  3284  func (b *Builder) collect(p *load.Package, obj, ofile string, cgoLDFLAGS, outObj []string) error {
  3285  	// When linking relocatable objects, various flags need to be
  3286  	// filtered out as they are inapplicable and can cause some linkers
  3287  	// to fail.
  3288  	var ldflags []string
  3289  	for i := 0; i < len(cgoLDFLAGS); i++ {
  3290  		f := cgoLDFLAGS[i]
  3291  		switch {
  3292  		// skip "-lc" or "-l somelib"
  3293  		case strings.HasPrefix(f, "-l"):
  3294  			if f == "-l" {
  3295  				i++
  3296  			}
  3297  		// skip "-framework X" on Darwin
  3298  		case cfg.Goos == "darwin" && f == "-framework":
  3299  			i++
  3300  		// skip "*.{dylib,so,dll,o,a}"
  3301  		case strings.HasSuffix(f, ".dylib"),
  3302  			strings.HasSuffix(f, ".so"),
  3303  			strings.HasSuffix(f, ".dll"),
  3304  			strings.HasSuffix(f, ".o"),
  3305  			strings.HasSuffix(f, ".a"):
  3306  		// Remove any -fsanitize=foo flags.
  3307  		// Otherwise the compiler driver thinks that we are doing final link
  3308  		// and links sanitizer runtime into the object file. But we are not doing
  3309  		// the final link, we will link the resulting object file again. And
  3310  		// so the program ends up with two copies of sanitizer runtime.
  3311  		// See issue 8788 for details.
  3312  		case strings.HasPrefix(f, "-fsanitize="):
  3313  			continue
  3314  		// runpath flags not applicable unless building a shared
  3315  		// object or executable; see issue 12115 for details. This
  3316  		// is necessary as Go currently does not offer a way to
  3317  		// specify the set of LDFLAGS that only apply to shared
  3318  		// objects.
  3319  		case strings.HasPrefix(f, "-Wl,-rpath"):
  3320  			if f == "-Wl,-rpath" || f == "-Wl,-rpath-link" {
  3321  				// Skip following argument to -rpath* too.
  3322  				i++
  3323  			}
  3324  		default:
  3325  			ldflags = append(ldflags, f)
  3326  		}
  3327  	}
  3328  
  3329  	ldflags = append(ldflags, "-Wl,-r", "-nostdlib")
  3330  
  3331  	if b.gccSupportsNoPie() {
  3332  		ldflags = append(ldflags, "-no-pie")
  3333  	}
  3334  
  3335  	// We are creating an object file, so we don't want a build ID.
  3336  	ldflags = b.disableBuildID(ldflags)
  3337  
  3338  	return b.gccld(p, ofile, ldflags, outObj)
  3339  }
  3340  
  3341  // Run SWIG on all SWIG input files.
  3342  // TODO: Don't build a shared library, once SWIG emits the necessary
  3343  // pragmas for external linking.
  3344  func (b *Builder) swig(p *load.Package, obj string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
  3345  	if err := b.swigVersionCheck(); err != nil {
  3346  		return nil, nil, nil, err
  3347  	}
  3348  
  3349  	intgosize, err := b.swigIntSize(obj)
  3350  	if err != nil {
  3351  		return nil, nil, nil, err
  3352  	}
  3353  
  3354  	for _, f := range p.SwigFiles {
  3355  		goFile, cFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
  3356  		if err != nil {
  3357  			return nil, nil, nil, err
  3358  		}
  3359  		if goFile != "" {
  3360  			outGo = append(outGo, goFile)
  3361  		}
  3362  		if cFile != "" {
  3363  			outC = append(outC, cFile)
  3364  		}
  3365  	}
  3366  	for _, f := range p.SwigCXXFiles {
  3367  		goFile, cxxFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
  3368  		if err != nil {
  3369  			return nil, nil, nil, err
  3370  		}
  3371  		if goFile != "" {
  3372  			outGo = append(outGo, goFile)
  3373  		}
  3374  		if cxxFile != "" {
  3375  			outCXX = append(outCXX, cxxFile)
  3376  		}
  3377  	}
  3378  	return outGo, outC, outCXX, nil
  3379  }
  3380  
  3381  // Make sure SWIG is new enough.
  3382  var (
  3383  	swigCheckOnce sync.Once
  3384  	swigCheck     error
  3385  )
  3386  
  3387  func (b *Builder) swigDoVersionCheck() error {
  3388  	out, err := b.runOut("", "", nil, "swig", "-version")
  3389  	if err != nil {
  3390  		return err
  3391  	}
  3392  	re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
  3393  	matches := re.FindSubmatch(out)
  3394  	if matches == nil {
  3395  		// Can't find version number; hope for the best.
  3396  		return nil
  3397  	}
  3398  
  3399  	major, err := strconv.Atoi(string(matches[1]))
  3400  	if err != nil {
  3401  		// Can't find version number; hope for the best.
  3402  		return nil
  3403  	}
  3404  	const errmsg = "must have SWIG version >= 3.0.6"
  3405  	if major < 3 {
  3406  		return errors.New(errmsg)
  3407  	}
  3408  	if major > 3 {
  3409  		// 4.0 or later
  3410  		return nil
  3411  	}
  3412  
  3413  	// We have SWIG version 3.x.
  3414  	if len(matches[2]) > 0 {
  3415  		minor, err := strconv.Atoi(string(matches[2][1:]))
  3416  		if err != nil {
  3417  			return nil
  3418  		}
  3419  		if minor > 0 {
  3420  			// 3.1 or later
  3421  			return nil
  3422  		}
  3423  	}
  3424  
  3425  	// We have SWIG version 3.0.x.
  3426  	if len(matches[3]) > 0 {
  3427  		patch, err := strconv.Atoi(string(matches[3][1:]))
  3428  		if err != nil {
  3429  			return nil
  3430  		}
  3431  		if patch < 6 {
  3432  			// Before 3.0.6.
  3433  			return errors.New(errmsg)
  3434  		}
  3435  	}
  3436  
  3437  	return nil
  3438  }
  3439  
  3440  func (b *Builder) swigVersionCheck() error {
  3441  	swigCheckOnce.Do(func() {
  3442  		swigCheck = b.swigDoVersionCheck()
  3443  	})
  3444  	return swigCheck
  3445  }
  3446  
  3447  // Find the value to pass for the -intgosize option to swig.
  3448  var (
  3449  	swigIntSizeOnce  sync.Once
  3450  	swigIntSize      string
  3451  	swigIntSizeError error
  3452  )
  3453  
  3454  // This code fails to build if sizeof(int) <= 32
  3455  const swigIntSizeCode = `
  3456  package main
  3457  const i int = 1 << 32
  3458  `
  3459  
  3460  // Determine the size of int on the target system for the -intgosize option
  3461  // of swig >= 2.0.9.  Run only once.
  3462  func (b *Builder) swigDoIntSize(obj string) (intsize string, err error) {
  3463  	if cfg.BuildN {
  3464  		return "$INTBITS", nil
  3465  	}
  3466  	src := filepath.Join(b.WorkDir, "swig_intsize.go")
  3467  	if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
  3468  		return
  3469  	}
  3470  	srcs := []string{src}
  3471  
  3472  	p := load.GoFilesPackage(srcs)
  3473  
  3474  	if _, _, e := BuildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil {
  3475  		return "32", nil
  3476  	}
  3477  	return "64", nil
  3478  }
  3479  
  3480  // Determine the size of int on the target system for the -intgosize option
  3481  // of swig >= 2.0.9.
  3482  func (b *Builder) swigIntSize(obj string) (intsize string, err error) {
  3483  	swigIntSizeOnce.Do(func() {
  3484  		swigIntSize, swigIntSizeError = b.swigDoIntSize(obj)
  3485  	})
  3486  	return swigIntSize, swigIntSizeError
  3487  }
  3488  
  3489  // Run SWIG on one SWIG input file.
  3490  func (b *Builder) swigOne(p *load.Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
  3491  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _ := b.CFlags(p)
  3492  	var cflags []string
  3493  	if cxx {
  3494  		cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
  3495  	} else {
  3496  		cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
  3497  	}
  3498  
  3499  	n := 5 // length of ".swig"
  3500  	if cxx {
  3501  		n = 8 // length of ".swigcxx"
  3502  	}
  3503  	base := file[:len(file)-n]
  3504  	goFile := base + ".go"
  3505  	gccBase := base + "_wrap."
  3506  	gccExt := "c"
  3507  	if cxx {
  3508  		gccExt = "cxx"
  3509  	}
  3510  
  3511  	gccgo := cfg.BuildToolchainName == "gccgo"
  3512  
  3513  	// swig
  3514  	args := []string{
  3515  		"-go",
  3516  		"-cgo",
  3517  		"-intgosize", intgosize,
  3518  		"-module", base,
  3519  		"-o", obj + gccBase + gccExt,
  3520  		"-outdir", obj,
  3521  	}
  3522  
  3523  	for _, f := range cflags {
  3524  		if len(f) > 3 && f[:2] == "-I" {
  3525  			args = append(args, f)
  3526  		}
  3527  	}
  3528  
  3529  	if gccgo {
  3530  		args = append(args, "-gccgo")
  3531  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  3532  			args = append(args, "-go-pkgpath", pkgpath)
  3533  		}
  3534  	}
  3535  	if cxx {
  3536  		args = append(args, "-c++")
  3537  	}
  3538  
  3539  	out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file)
  3540  	if err != nil {
  3541  		if len(out) > 0 {
  3542  			if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
  3543  				return "", "", errors.New("must have SWIG version >= 3.0.6")
  3544  			}
  3545  			b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig error
  3546  			return "", "", errPrintedOutput
  3547  		}
  3548  		return "", "", err
  3549  	}
  3550  	if len(out) > 0 {
  3551  		b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig warning
  3552  	}
  3553  
  3554  	return goFile, obj + gccBase + gccExt, nil
  3555  }
  3556  
  3557  // disableBuildID adjusts a linker command line to avoid creating a
  3558  // build ID when creating an object file rather than an executable or
  3559  // shared library. Some systems, such as Ubuntu, always add
  3560  // --build-id to every link, but we don't want a build ID when we are
  3561  // producing an object file. On some of those system a plain -r (not
  3562  // -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a
  3563  // plain -r. I don't know how to turn off --build-id when using clang
  3564  // other than passing a trailing --build-id=none. So that is what we
  3565  // do, but only on systems likely to support it, which is to say,
  3566  // systems that normally use gold or the GNU linker.
  3567  func (b *Builder) disableBuildID(ldflags []string) []string {
  3568  	switch cfg.Goos {
  3569  	case "android", "dragonfly", "linux", "netbsd":
  3570  		ldflags = append(ldflags, "-Wl,--build-id=none")
  3571  	}
  3572  	return ldflags
  3573  }
  3574  
  3575  // An actionQueue is a priority queue of actions.
  3576  type actionQueue []*Action
  3577  
  3578  // Implement heap.Interface
  3579  func (q *actionQueue) Len() int           { return len(*q) }
  3580  func (q *actionQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
  3581  func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
  3582  func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*Action)) }
  3583  func (q *actionQueue) Pop() interface{} {
  3584  	n := len(*q) - 1
  3585  	x := (*q)[n]
  3586  	*q = (*q)[:n]
  3587  	return x
  3588  }
  3589  
  3590  func (q *actionQueue) push(a *Action) {
  3591  	heap.Push(q, a)
  3592  }
  3593  
  3594  func (q *actionQueue) pop() *Action {
  3595  	return heap.Pop(q).(*Action)
  3596  }
  3597  
  3598  func InstrumentInit() {
  3599  	if !cfg.BuildRace && !cfg.BuildMSan {
  3600  		return
  3601  	}
  3602  	if cfg.BuildRace && cfg.BuildMSan {
  3603  		fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0])
  3604  		os.Exit(2)
  3605  	}
  3606  	if cfg.BuildMSan && (cfg.Goos != "linux" || cfg.Goarch != "amd64") {
  3607  		fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", cfg.Goos, cfg.Goarch)
  3608  		os.Exit(2)
  3609  	}
  3610  	if cfg.Goarch != "amd64" || cfg.Goos != "linux" && cfg.Goos != "freebsd" && cfg.Goos != "darwin" && cfg.Goos != "windows" {
  3611  		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])
  3612  		os.Exit(2)
  3613  	}
  3614  	if !cfg.BuildContext.CgoEnabled {
  3615  		fmt.Fprintf(os.Stderr, "go %s: -race requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0])
  3616  		os.Exit(2)
  3617  	}
  3618  	if cfg.BuildRace {
  3619  		buildGcflags = append(buildGcflags, "-race")
  3620  		cfg.BuildLdflags = append(cfg.BuildLdflags, "-race")
  3621  	} else {
  3622  		buildGcflags = append(buildGcflags, "-msan")
  3623  		cfg.BuildLdflags = append(cfg.BuildLdflags, "-msan")
  3624  	}
  3625  	if cfg.BuildContext.InstallSuffix != "" {
  3626  		cfg.BuildContext.InstallSuffix += "_"
  3627  	}
  3628  
  3629  	if cfg.BuildRace {
  3630  		cfg.BuildContext.InstallSuffix += "race"
  3631  		cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "race")
  3632  	} else {
  3633  		cfg.BuildContext.InstallSuffix += "msan"
  3634  		cfg.BuildContext.BuildTags = append(cfg.BuildContext.BuildTags, "msan")
  3635  	}
  3636  }
  3637  
  3638  // ExecCmd is the command to use to run user binaries.
  3639  // Normally it is empty, meaning run the binaries directly.
  3640  // If cross-compiling and running on a remote system or
  3641  // simulator, it is typically go_GOOS_GOARCH_exec, with
  3642  // the target GOOS and GOARCH substituted.
  3643  // The -exec flag overrides these defaults.
  3644  var ExecCmd []string
  3645  
  3646  // FindExecCmd derives the value of ExecCmd to use.
  3647  // It returns that value and leaves ExecCmd set for direct use.
  3648  func FindExecCmd() []string {
  3649  	if ExecCmd != nil {
  3650  		return ExecCmd
  3651  	}
  3652  	ExecCmd = []string{} // avoid work the second time
  3653  	if cfg.Goos == runtime.GOOS && cfg.Goarch == runtime.GOARCH {
  3654  		return ExecCmd
  3655  	}
  3656  	path, err := exec.LookPath(fmt.Sprintf("go_%s_%s_exec", cfg.Goos, cfg.Goarch))
  3657  	if err == nil {
  3658  		ExecCmd = []string{path}
  3659  	}
  3660  	return ExecCmd
  3661  }