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