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