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