github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/cmd/go/internal/work/build.go (about)

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