github.com/FenixAra/go@v0.0.0-20170127160404-96ea0918e670/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  		var out []byte
  1674  		out, err = b.runOut(p.Dir, p.ImportPath, nil, b.pkgconfigCmd(), "--cflags", pkgs)
  1675  		if err != nil {
  1676  			b.showOutput(p.Dir, b.pkgconfigCmd()+" --cflags "+strings.Join(pkgs, " "), string(out))
  1677  			b.print(err.Error() + "\n")
  1678  			err = errPrintedOutput
  1679  			return
  1680  		}
  1681  		if len(out) > 0 {
  1682  			cflags = splitPkgConfigOutput(out)
  1683  		}
  1684  		out, err = b.runOut(p.Dir, p.ImportPath, nil, b.pkgconfigCmd(), "--libs", pkgs)
  1685  		if err != nil {
  1686  			b.showOutput(p.Dir, b.pkgconfigCmd()+" --libs "+strings.Join(pkgs, " "), string(out))
  1687  			b.print(err.Error() + "\n")
  1688  			err = errPrintedOutput
  1689  			return
  1690  		}
  1691  		if len(out) > 0 {
  1692  			ldflags = strings.Fields(string(out))
  1693  		}
  1694  	}
  1695  	return
  1696  }
  1697  
  1698  func (b *builder) installShlibname(a *action) error {
  1699  	a1 := a.deps[0]
  1700  	err := ioutil.WriteFile(a.target, []byte(filepath.Base(a1.target)+"\n"), 0666)
  1701  	if err != nil {
  1702  		return err
  1703  	}
  1704  	if buildX {
  1705  		b.showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.target), a.target)
  1706  	}
  1707  	return nil
  1708  }
  1709  
  1710  func (b *builder) linkShared(a *action) (err error) {
  1711  	allactions := actionList(a)
  1712  	allactions = allactions[:len(allactions)-1]
  1713  	return buildToolchain.ldShared(b, a.deps, a.target, allactions)
  1714  }
  1715  
  1716  // install is the action for installing a single package or executable.
  1717  func (b *builder) install(a *action) (err error) {
  1718  	defer func() {
  1719  		if err != nil && err != errPrintedOutput {
  1720  			err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err)
  1721  		}
  1722  	}()
  1723  	a1 := a.deps[0]
  1724  	perm := os.FileMode(0666)
  1725  	if a1.link {
  1726  		switch buildBuildmode {
  1727  		case "c-archive", "c-shared", "plugin":
  1728  		default:
  1729  			perm = 0777
  1730  		}
  1731  	}
  1732  
  1733  	// make target directory
  1734  	dir, _ := filepath.Split(a.target)
  1735  	if dir != "" {
  1736  		if err := b.mkdir(dir); err != nil {
  1737  			return err
  1738  		}
  1739  	}
  1740  
  1741  	// remove object dir to keep the amount of
  1742  	// garbage down in a large build. On an operating system
  1743  	// with aggressive buffering, cleaning incrementally like
  1744  	// this keeps the intermediate objects from hitting the disk.
  1745  	if !buildWork {
  1746  		defer os.RemoveAll(a1.objdir)
  1747  		defer os.Remove(a1.target)
  1748  	}
  1749  
  1750  	return b.moveOrCopyFile(a, a.target, a1.target, perm, false)
  1751  }
  1752  
  1753  // includeArgs returns the -I or -L directory list for access
  1754  // to the results of the list of actions.
  1755  func (b *builder) includeArgs(flag string, all []*action) []string {
  1756  	inc := []string{}
  1757  	incMap := map[string]bool{
  1758  		b.work:    true, // handled later
  1759  		gorootPkg: true,
  1760  		"":        true, // ignore empty strings
  1761  	}
  1762  
  1763  	// Look in the temporary space for results of test-specific actions.
  1764  	// This is the $WORK/my/package/_test directory for the
  1765  	// package being built, so there are few of these.
  1766  	for _, a1 := range all {
  1767  		if a1.p == nil {
  1768  			continue
  1769  		}
  1770  		if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
  1771  			incMap[dir] = true
  1772  			inc = append(inc, flag, dir)
  1773  		}
  1774  	}
  1775  
  1776  	// Also look in $WORK for any non-test packages that have
  1777  	// been built but not installed.
  1778  	inc = append(inc, flag, b.work)
  1779  
  1780  	// Finally, look in the installed package directories for each action.
  1781  	// First add the package dirs corresponding to GOPATH entries
  1782  	// in the original GOPATH order.
  1783  	need := map[string]*build.Package{}
  1784  	for _, a1 := range all {
  1785  		if a1.p != nil && a1.pkgdir == a1.p.build.PkgRoot {
  1786  			need[a1.p.build.Root] = a1.p.build
  1787  		}
  1788  	}
  1789  	for _, root := range gopath {
  1790  		if p := need[root]; p != nil && !incMap[p.PkgRoot] {
  1791  			incMap[p.PkgRoot] = true
  1792  			inc = append(inc, flag, p.PkgTargetRoot)
  1793  		}
  1794  	}
  1795  
  1796  	// Then add anything that's left.
  1797  	for _, a1 := range all {
  1798  		if a1.p == nil {
  1799  			continue
  1800  		}
  1801  		if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
  1802  			incMap[dir] = true
  1803  			inc = append(inc, flag, a1.p.build.PkgTargetRoot)
  1804  		}
  1805  	}
  1806  
  1807  	return inc
  1808  }
  1809  
  1810  // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
  1811  func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
  1812  	if buildN {
  1813  		b.showcmd("", "mv %s %s", src, dst)
  1814  		return nil
  1815  	}
  1816  
  1817  	// If we can update the mode and rename to the dst, do it.
  1818  	// Otherwise fall back to standard copy.
  1819  
  1820  	// The perm argument is meant to be adjusted according to umask,
  1821  	// but we don't know what the umask is.
  1822  	// Create a dummy file to find out.
  1823  	// This avoids build tags and works even on systems like Plan 9
  1824  	// where the file mask computation incorporates other information.
  1825  	mode := perm
  1826  	f, err := os.OpenFile(filepath.Clean(dst)+"-go-tmp-umask", os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
  1827  	if err == nil {
  1828  		fi, err := f.Stat()
  1829  		if err == nil {
  1830  			mode = fi.Mode() & 0777
  1831  		}
  1832  		name := f.Name()
  1833  		f.Close()
  1834  		os.Remove(name)
  1835  	}
  1836  
  1837  	if err := os.Chmod(src, mode); err == nil {
  1838  		if err := os.Rename(src, dst); err == nil {
  1839  			if buildX {
  1840  				b.showcmd("", "mv %s %s", src, dst)
  1841  			}
  1842  			return nil
  1843  		}
  1844  	}
  1845  
  1846  	return b.copyFile(a, dst, src, perm, force)
  1847  }
  1848  
  1849  // copyFile is like 'cp src dst'.
  1850  func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode, force bool) error {
  1851  	if buildN || buildX {
  1852  		b.showcmd("", "cp %s %s", src, dst)
  1853  		if buildN {
  1854  			return nil
  1855  		}
  1856  	}
  1857  
  1858  	sf, err := os.Open(src)
  1859  	if err != nil {
  1860  		return err
  1861  	}
  1862  	defer sf.Close()
  1863  
  1864  	// Be careful about removing/overwriting dst.
  1865  	// Do not remove/overwrite if dst exists and is a directory
  1866  	// or a non-object file.
  1867  	if fi, err := os.Stat(dst); err == nil {
  1868  		if fi.IsDir() {
  1869  			return fmt.Errorf("build output %q already exists and is a directory", dst)
  1870  		}
  1871  		if !force && fi.Mode().IsRegular() && !isObject(dst) {
  1872  			return fmt.Errorf("build output %q already exists and is not an object file", dst)
  1873  		}
  1874  	}
  1875  
  1876  	// On Windows, remove lingering ~ file from last attempt.
  1877  	if toolIsWindows {
  1878  		if _, err := os.Stat(dst + "~"); err == nil {
  1879  			os.Remove(dst + "~")
  1880  		}
  1881  	}
  1882  
  1883  	mayberemovefile(dst)
  1884  	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1885  	if err != nil && toolIsWindows {
  1886  		// Windows does not allow deletion of a binary file
  1887  		// while it is executing. Try to move it out of the way.
  1888  		// If the move fails, which is likely, we'll try again the
  1889  		// next time we do an install of this binary.
  1890  		if err := os.Rename(dst, dst+"~"); err == nil {
  1891  			os.Remove(dst + "~")
  1892  		}
  1893  		df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
  1894  	}
  1895  	if err != nil {
  1896  		return err
  1897  	}
  1898  
  1899  	_, err = io.Copy(df, sf)
  1900  	df.Close()
  1901  	if err != nil {
  1902  		mayberemovefile(dst)
  1903  		return fmt.Errorf("copying %s to %s: %v", src, dst, err)
  1904  	}
  1905  	return nil
  1906  }
  1907  
  1908  // Install the cgo export header file, if there is one.
  1909  func (b *builder) installHeader(a *action) error {
  1910  	src := a.objdir + "_cgo_install.h"
  1911  	if _, err := os.Stat(src); os.IsNotExist(err) {
  1912  		// If the file does not exist, there are no exported
  1913  		// functions, and we do not install anything.
  1914  		return nil
  1915  	}
  1916  
  1917  	dir, _ := filepath.Split(a.target)
  1918  	if dir != "" {
  1919  		if err := b.mkdir(dir); err != nil {
  1920  			return err
  1921  		}
  1922  	}
  1923  
  1924  	return b.moveOrCopyFile(a, a.target, src, 0666, true)
  1925  }
  1926  
  1927  // cover runs, in effect,
  1928  //	go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
  1929  func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
  1930  	return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
  1931  		buildToolExec,
  1932  		tool("cover"),
  1933  		"-mode", a.p.coverMode,
  1934  		"-var", varName,
  1935  		"-o", dst,
  1936  		src)
  1937  }
  1938  
  1939  var objectMagic = [][]byte{
  1940  	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
  1941  	{'\x7F', 'E', 'L', 'F'},                   // ELF
  1942  	{0xFE, 0xED, 0xFA, 0xCE},                  // Mach-O big-endian 32-bit
  1943  	{0xFE, 0xED, 0xFA, 0xCF},                  // Mach-O big-endian 64-bit
  1944  	{0xCE, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 32-bit
  1945  	{0xCF, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 64-bit
  1946  	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00},      // PE (Windows) as generated by 6l/8l and gcc
  1947  	{0x00, 0x00, 0x01, 0xEB},                  // Plan 9 i386
  1948  	{0x00, 0x00, 0x8a, 0x97},                  // Plan 9 amd64
  1949  	{0x00, 0x00, 0x06, 0x47},                  // Plan 9 arm
  1950  }
  1951  
  1952  func isObject(s string) bool {
  1953  	f, err := os.Open(s)
  1954  	if err != nil {
  1955  		return false
  1956  	}
  1957  	defer f.Close()
  1958  	buf := make([]byte, 64)
  1959  	io.ReadFull(f, buf)
  1960  	for _, magic := range objectMagic {
  1961  		if bytes.HasPrefix(buf, magic) {
  1962  			return true
  1963  		}
  1964  	}
  1965  	return false
  1966  }
  1967  
  1968  // mayberemovefile removes a file only if it is a regular file
  1969  // When running as a user with sufficient privileges, we may delete
  1970  // even device files, for example, which is not intended.
  1971  func mayberemovefile(s string) {
  1972  	if fi, err := os.Lstat(s); err == nil && !fi.Mode().IsRegular() {
  1973  		return
  1974  	}
  1975  	os.Remove(s)
  1976  }
  1977  
  1978  // fmtcmd formats a command in the manner of fmt.Sprintf but also:
  1979  //
  1980  //	If dir is non-empty and the script is not in dir right now,
  1981  //	fmtcmd inserts "cd dir\n" before the command.
  1982  //
  1983  //	fmtcmd replaces the value of b.work with $WORK.
  1984  //	fmtcmd replaces the value of goroot with $GOROOT.
  1985  //	fmtcmd replaces the value of b.gobin with $GOBIN.
  1986  //
  1987  //	fmtcmd replaces the name of the current directory with dot (.)
  1988  //	but only when it is at the beginning of a space-separated token.
  1989  //
  1990  func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
  1991  	cmd := fmt.Sprintf(format, args...)
  1992  	if dir != "" && dir != "/" {
  1993  		cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
  1994  		if b.scriptDir != dir {
  1995  			b.scriptDir = dir
  1996  			cmd = "cd " + dir + "\n" + cmd
  1997  		}
  1998  	}
  1999  	if b.work != "" {
  2000  		cmd = strings.Replace(cmd, b.work, "$WORK", -1)
  2001  	}
  2002  	return cmd
  2003  }
  2004  
  2005  // showcmd prints the given command to standard output
  2006  // for the implementation of -n or -x.
  2007  func (b *builder) showcmd(dir string, format string, args ...interface{}) {
  2008  	b.output.Lock()
  2009  	defer b.output.Unlock()
  2010  	b.print(b.fmtcmd(dir, format, args...) + "\n")
  2011  }
  2012  
  2013  // showOutput prints "# desc" followed by the given output.
  2014  // The output is expected to contain references to 'dir', usually
  2015  // the source directory for the package that has failed to build.
  2016  // showOutput rewrites mentions of dir with a relative path to dir
  2017  // when the relative path is shorter. This is usually more pleasant.
  2018  // For example, if fmt doesn't compile and we are in src/html,
  2019  // the output is
  2020  //
  2021  //	$ go build
  2022  //	# fmt
  2023  //	../fmt/print.go:1090: undefined: asdf
  2024  //	$
  2025  //
  2026  // instead of
  2027  //
  2028  //	$ go build
  2029  //	# fmt
  2030  //	/usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
  2031  //	$
  2032  //
  2033  // showOutput also replaces references to the work directory with $WORK.
  2034  //
  2035  func (b *builder) showOutput(dir, desc, out string) {
  2036  	prefix := "# " + desc
  2037  	suffix := "\n" + out
  2038  	if reldir := shortPath(dir); reldir != dir {
  2039  		suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
  2040  		suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
  2041  	}
  2042  	suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
  2043  
  2044  	b.output.Lock()
  2045  	defer b.output.Unlock()
  2046  	b.print(prefix, suffix)
  2047  }
  2048  
  2049  // shortPath returns an absolute or relative name for path, whatever is shorter.
  2050  func shortPath(path string) string {
  2051  	if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
  2052  		return rel
  2053  	}
  2054  	return path
  2055  }
  2056  
  2057  // relPaths returns a copy of paths with absolute paths
  2058  // made relative to the current directory if they would be shorter.
  2059  func relPaths(paths []string) []string {
  2060  	var out []string
  2061  	pwd, _ := os.Getwd()
  2062  	for _, p := range paths {
  2063  		rel, err := filepath.Rel(pwd, p)
  2064  		if err == nil && len(rel) < len(p) {
  2065  			p = rel
  2066  		}
  2067  		out = append(out, p)
  2068  	}
  2069  	return out
  2070  }
  2071  
  2072  // errPrintedOutput is a special error indicating that a command failed
  2073  // but that it generated output as well, and that output has already
  2074  // been printed, so there's no point showing 'exit status 1' or whatever
  2075  // the wait status was. The main executor, builder.do, knows not to
  2076  // print this error.
  2077  var errPrintedOutput = errors.New("already printed output - no need to show error")
  2078  
  2079  var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
  2080  var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
  2081  
  2082  // run runs the command given by cmdline in the directory dir.
  2083  // If the command fails, run prints information about the failure
  2084  // and returns a non-nil error.
  2085  func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
  2086  	out, err := b.runOut(dir, desc, env, cmdargs...)
  2087  	if len(out) > 0 {
  2088  		if desc == "" {
  2089  			desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
  2090  		}
  2091  		b.showOutput(dir, desc, b.processOutput(out))
  2092  		if err != nil {
  2093  			err = errPrintedOutput
  2094  		}
  2095  	}
  2096  	return err
  2097  }
  2098  
  2099  // processOutput prepares the output of runOut to be output to the console.
  2100  func (b *builder) processOutput(out []byte) string {
  2101  	if out[len(out)-1] != '\n' {
  2102  		out = append(out, '\n')
  2103  	}
  2104  	messages := string(out)
  2105  	// Fix up output referring to cgo-generated code to be more readable.
  2106  	// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
  2107  	// Replace *[100]_Ctype_foo with *[100]C.foo.
  2108  	// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
  2109  	if !buildX && cgoLine.MatchString(messages) {
  2110  		messages = cgoLine.ReplaceAllString(messages, "")
  2111  		messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
  2112  	}
  2113  	return messages
  2114  }
  2115  
  2116  // runOut runs the command given by cmdline in the directory dir.
  2117  // It returns the command output and any errors that occurred.
  2118  func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
  2119  	cmdline := stringList(cmdargs...)
  2120  	if buildN || buildX {
  2121  		var envcmdline string
  2122  		for i := range env {
  2123  			envcmdline += env[i]
  2124  			envcmdline += " "
  2125  		}
  2126  		envcmdline += joinUnambiguously(cmdline)
  2127  		b.showcmd(dir, "%s", envcmdline)
  2128  		if buildN {
  2129  			return nil, nil
  2130  		}
  2131  	}
  2132  
  2133  	nbusy := 0
  2134  	for {
  2135  		var buf bytes.Buffer
  2136  		cmd := exec.Command(cmdline[0], cmdline[1:]...)
  2137  		cmd.Stdout = &buf
  2138  		cmd.Stderr = &buf
  2139  		cmd.Dir = dir
  2140  		cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir, os.Environ()))
  2141  		err := cmd.Run()
  2142  
  2143  		// cmd.Run will fail on Unix if some other process has the binary
  2144  		// we want to run open for writing. This can happen here because
  2145  		// we build and install the cgo command and then run it.
  2146  		// If another command was kicked off while we were writing the
  2147  		// cgo binary, the child process for that command may be holding
  2148  		// a reference to the fd, keeping us from running exec.
  2149  		//
  2150  		// But, you might reasonably wonder, how can this happen?
  2151  		// The cgo fd, like all our fds, is close-on-exec, so that we need
  2152  		// not worry about other processes inheriting the fd accidentally.
  2153  		// The answer is that running a command is fork and exec.
  2154  		// A child forked while the cgo fd is open inherits that fd.
  2155  		// Until the child has called exec, it holds the fd open and the
  2156  		// kernel will not let us run cgo. Even if the child were to close
  2157  		// the fd explicitly, it would still be open from the time of the fork
  2158  		// until the time of the explicit close, and the race would remain.
  2159  		//
  2160  		// On Unix systems, this results in ETXTBSY, which formats
  2161  		// as "text file busy".  Rather than hard-code specific error cases,
  2162  		// we just look for that string. If this happens, sleep a little
  2163  		// and try again. We let this happen three times, with increasing
  2164  		// sleep lengths: 100+200+400 ms = 0.7 seconds.
  2165  		//
  2166  		// An alternate solution might be to split the cmd.Run into
  2167  		// separate cmd.Start and cmd.Wait, and then use an RWLock
  2168  		// to make sure that copyFile only executes when no cmd.Start
  2169  		// call is in progress. However, cmd.Start (really syscall.forkExec)
  2170  		// only guarantees that when it returns, the exec is committed to
  2171  		// happen and succeed. It uses a close-on-exec file descriptor
  2172  		// itself to determine this, so we know that when cmd.Start returns,
  2173  		// at least one close-on-exec file descriptor has been closed.
  2174  		// However, we cannot be sure that all of them have been closed,
  2175  		// so the program might still encounter ETXTBSY even with such
  2176  		// an RWLock. The race window would be smaller, perhaps, but not
  2177  		// guaranteed to be gone.
  2178  		//
  2179  		// Sleeping when we observe the race seems to be the most reliable
  2180  		// option we have.
  2181  		//
  2182  		// https://golang.org/issue/3001
  2183  		//
  2184  		if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
  2185  			time.Sleep(100 * time.Millisecond << uint(nbusy))
  2186  			nbusy++
  2187  			continue
  2188  		}
  2189  
  2190  		// err can be something like 'exit status 1'.
  2191  		// Add information about what program was running.
  2192  		// Note that if buf.Bytes() is non-empty, the caller usually
  2193  		// shows buf.Bytes() and does not print err at all, so the
  2194  		// prefix here does not make most output any more verbose.
  2195  		if err != nil {
  2196  			err = errors.New(cmdline[0] + ": " + err.Error())
  2197  		}
  2198  		return buf.Bytes(), err
  2199  	}
  2200  }
  2201  
  2202  // joinUnambiguously prints the slice, quoting where necessary to make the
  2203  // output unambiguous.
  2204  // TODO: See issue 5279. The printing of commands needs a complete redo.
  2205  func joinUnambiguously(a []string) string {
  2206  	var buf bytes.Buffer
  2207  	for i, s := range a {
  2208  		if i > 0 {
  2209  			buf.WriteByte(' ')
  2210  		}
  2211  		q := strconv.Quote(s)
  2212  		if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
  2213  			buf.WriteString(q)
  2214  		} else {
  2215  			buf.WriteString(s)
  2216  		}
  2217  	}
  2218  	return buf.String()
  2219  }
  2220  
  2221  // mkdir makes the named directory.
  2222  func (b *builder) mkdir(dir string) error {
  2223  	b.exec.Lock()
  2224  	defer b.exec.Unlock()
  2225  	// We can be a little aggressive about being
  2226  	// sure directories exist. Skip repeated calls.
  2227  	if b.mkdirCache[dir] {
  2228  		return nil
  2229  	}
  2230  	b.mkdirCache[dir] = true
  2231  
  2232  	if buildN || buildX {
  2233  		b.showcmd("", "mkdir -p %s", dir)
  2234  		if buildN {
  2235  			return nil
  2236  		}
  2237  	}
  2238  
  2239  	if err := os.MkdirAll(dir, 0777); err != nil {
  2240  		return err
  2241  	}
  2242  	return nil
  2243  }
  2244  
  2245  // mkAbs returns an absolute path corresponding to
  2246  // evaluating f in the directory dir.
  2247  // We always pass absolute paths of source files so that
  2248  // the error messages will include the full path to a file
  2249  // in need of attention.
  2250  func mkAbs(dir, f string) string {
  2251  	// Leave absolute paths alone.
  2252  	// Also, during -n mode we use the pseudo-directory $WORK
  2253  	// instead of creating an actual work directory that won't be used.
  2254  	// Leave paths beginning with $WORK alone too.
  2255  	if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
  2256  		return f
  2257  	}
  2258  	return filepath.Join(dir, f)
  2259  }
  2260  
  2261  type toolchain interface {
  2262  	// gc runs the compiler in a specific directory on a set of files
  2263  	// and returns the name of the generated output file.
  2264  	gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
  2265  	// cc runs the toolchain's C compiler in a directory on a C file
  2266  	// to produce an output file.
  2267  	cc(b *builder, p *Package, objdir, ofile, cfile string) error
  2268  	// asm runs the assembler in a specific directory on specific files
  2269  	// and returns a list of named output files.
  2270  	asm(b *builder, p *Package, obj string, sfiles []string) ([]string, error)
  2271  	// pkgpath builds an appropriate path for a temporary package file.
  2272  	pkgpath(basedir string, p *Package) string
  2273  	// pack runs the archive packer in a specific directory to create
  2274  	// an archive from a set of object files.
  2275  	// typically it is run in the object directory.
  2276  	pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
  2277  	// ld runs the linker to create an executable starting at mainpkg.
  2278  	ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error
  2279  	// ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
  2280  	ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error
  2281  
  2282  	compiler() string
  2283  	linker() string
  2284  }
  2285  
  2286  type noToolchain struct{}
  2287  
  2288  func noCompiler() error {
  2289  	log.Fatalf("unknown compiler %q", buildContext.Compiler)
  2290  	return nil
  2291  }
  2292  
  2293  func (noToolchain) compiler() string {
  2294  	noCompiler()
  2295  	return ""
  2296  }
  2297  
  2298  func (noToolchain) linker() string {
  2299  	noCompiler()
  2300  	return ""
  2301  }
  2302  
  2303  func (noToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
  2304  	return "", nil, noCompiler()
  2305  }
  2306  
  2307  func (noToolchain) asm(b *builder, p *Package, obj string, sfiles []string) ([]string, error) {
  2308  	return nil, noCompiler()
  2309  }
  2310  
  2311  func (noToolchain) pkgpath(basedir string, p *Package) string {
  2312  	noCompiler()
  2313  	return ""
  2314  }
  2315  
  2316  func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  2317  	return noCompiler()
  2318  }
  2319  
  2320  func (noToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
  2321  	return noCompiler()
  2322  }
  2323  
  2324  func (noToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
  2325  	return noCompiler()
  2326  }
  2327  
  2328  func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  2329  	return noCompiler()
  2330  }
  2331  
  2332  // The Go toolchain.
  2333  type gcToolchain struct{}
  2334  
  2335  func (gcToolchain) compiler() string {
  2336  	return tool("compile")
  2337  }
  2338  
  2339  func (gcToolchain) linker() string {
  2340  	return tool("link")
  2341  }
  2342  
  2343  func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
  2344  	if archive != "" {
  2345  		ofile = archive
  2346  	} else {
  2347  		out := "_go_.o"
  2348  		ofile = obj + out
  2349  	}
  2350  
  2351  	gcargs := []string{"-p", p.ImportPath}
  2352  	if p.Name == "main" {
  2353  		gcargs[1] = "main"
  2354  	}
  2355  	if p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) {
  2356  		// runtime compiles with a special gc flag to emit
  2357  		// additional reflect type data.
  2358  		gcargs = append(gcargs, "-+")
  2359  	}
  2360  
  2361  	// If we're giving the compiler the entire package (no C etc files), tell it that,
  2362  	// so that it can give good error messages about forward declarations.
  2363  	// Exceptions: a few standard packages have forward declarations for
  2364  	// pieces supplied behind-the-scenes by package runtime.
  2365  	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)
  2366  	if p.Standard {
  2367  		switch p.ImportPath {
  2368  		case "bytes", "net", "os", "runtime/pprof", "sync", "time":
  2369  			extFiles++
  2370  		}
  2371  	}
  2372  	if extFiles == 0 {
  2373  		gcargs = append(gcargs, "-complete")
  2374  	}
  2375  	if buildContext.InstallSuffix != "" {
  2376  		gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
  2377  	}
  2378  	if p.buildID != "" {
  2379  		gcargs = append(gcargs, "-buildid", p.buildID)
  2380  	}
  2381  
  2382  	for _, path := range p.Imports {
  2383  		if i := strings.LastIndex(path, "/vendor/"); i >= 0 {
  2384  			gcargs = append(gcargs, "-importmap", path[i+len("/vendor/"):]+"="+path)
  2385  		} else if strings.HasPrefix(path, "vendor/") {
  2386  			gcargs = append(gcargs, "-importmap", path[len("vendor/"):]+"="+path)
  2387  		}
  2388  	}
  2389  
  2390  	args := []interface{}{buildToolExec, tool("compile"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs}
  2391  	if ofile == archive {
  2392  		args = append(args, "-pack")
  2393  	}
  2394  	if asmhdr {
  2395  		args = append(args, "-asmhdr", obj+"go_asm.h")
  2396  	}
  2397  	for _, f := range gofiles {
  2398  		args = append(args, mkAbs(p.Dir, f))
  2399  	}
  2400  
  2401  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args...)
  2402  	return ofile, output, err
  2403  }
  2404  
  2405  func (gcToolchain) asm(b *builder, p *Package, obj string, sfiles []string) ([]string, error) {
  2406  	// Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
  2407  	inc := filepath.Join(goroot, "pkg", "include")
  2408  	args := []interface{}{buildToolExec, tool("asm"), "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch, buildAsmflags}
  2409  	if p.ImportPath == "runtime" && goarch == "386" {
  2410  		for _, arg := range buildAsmflags {
  2411  			if arg == "-dynlink" {
  2412  				args = append(args, "-D=GOBUILDMODE_shared=1")
  2413  			}
  2414  		}
  2415  	}
  2416  	var ofiles []string
  2417  	for _, sfile := range sfiles {
  2418  		ofile := obj + sfile[:len(sfile)-len(".s")] + ".o"
  2419  		ofiles = append(ofiles, ofile)
  2420  		a := append(args, "-o", ofile, mkAbs(p.Dir, sfile))
  2421  		if err := b.run(p.Dir, p.ImportPath, nil, a...); err != nil {
  2422  			return nil, err
  2423  		}
  2424  	}
  2425  	return ofiles, nil
  2426  }
  2427  
  2428  // toolVerify checks that the command line args writes the same output file
  2429  // if run using newTool instead.
  2430  // Unused now but kept around for future use.
  2431  func toolVerify(b *builder, p *Package, newTool string, ofile string, args []interface{}) error {
  2432  	newArgs := make([]interface{}, len(args))
  2433  	copy(newArgs, args)
  2434  	newArgs[1] = tool(newTool)
  2435  	newArgs[3] = ofile + ".new" // x.6 becomes x.6.new
  2436  	if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil {
  2437  		return err
  2438  	}
  2439  	data1, err := ioutil.ReadFile(ofile)
  2440  	if err != nil {
  2441  		return err
  2442  	}
  2443  	data2, err := ioutil.ReadFile(ofile + ".new")
  2444  	if err != nil {
  2445  		return err
  2446  	}
  2447  	if !bytes.Equal(data1, data2) {
  2448  		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...), " "))
  2449  	}
  2450  	os.Remove(ofile + ".new")
  2451  	return nil
  2452  }
  2453  
  2454  func (gcToolchain) pkgpath(basedir string, p *Package) string {
  2455  	end := filepath.FromSlash(p.ImportPath + ".a")
  2456  	return filepath.Join(basedir, end)
  2457  }
  2458  
  2459  func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  2460  	var absOfiles []string
  2461  	for _, f := range ofiles {
  2462  		absOfiles = append(absOfiles, mkAbs(objDir, f))
  2463  	}
  2464  	absAfile := mkAbs(objDir, afile)
  2465  
  2466  	// The archive file should have been created by the compiler.
  2467  	// Since it used to not work that way, verify.
  2468  	if !buildN {
  2469  		if _, err := os.Stat(absAfile); err != nil {
  2470  			fatalf("os.Stat of archive file failed: %v", err)
  2471  		}
  2472  	}
  2473  
  2474  	if buildN || buildX {
  2475  		cmdline := stringList("pack", "r", absAfile, absOfiles)
  2476  		b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
  2477  	}
  2478  	if buildN {
  2479  		return nil
  2480  	}
  2481  	if err := packInternal(b, absAfile, absOfiles); err != nil {
  2482  		b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
  2483  		return errPrintedOutput
  2484  	}
  2485  	return nil
  2486  }
  2487  
  2488  func packInternal(b *builder, afile string, ofiles []string) error {
  2489  	dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
  2490  	if err != nil {
  2491  		return err
  2492  	}
  2493  	defer dst.Close() // only for error returns or panics
  2494  	w := bufio.NewWriter(dst)
  2495  
  2496  	for _, ofile := range ofiles {
  2497  		src, err := os.Open(ofile)
  2498  		if err != nil {
  2499  			return err
  2500  		}
  2501  		fi, err := src.Stat()
  2502  		if err != nil {
  2503  			src.Close()
  2504  			return err
  2505  		}
  2506  		// Note: Not using %-16.16s format because we care
  2507  		// about bytes, not runes.
  2508  		name := fi.Name()
  2509  		if len(name) > 16 {
  2510  			name = name[:16]
  2511  		} else {
  2512  			name += strings.Repeat(" ", 16-len(name))
  2513  		}
  2514  		size := fi.Size()
  2515  		fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
  2516  			name, 0, 0, 0, 0644, size)
  2517  		n, err := io.Copy(w, src)
  2518  		src.Close()
  2519  		if err == nil && n < size {
  2520  			err = io.ErrUnexpectedEOF
  2521  		} else if err == nil && n > size {
  2522  			err = fmt.Errorf("file larger than size reported by stat")
  2523  		}
  2524  		if err != nil {
  2525  			return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
  2526  		}
  2527  		if size&1 != 0 {
  2528  			w.WriteByte(0)
  2529  		}
  2530  	}
  2531  
  2532  	if err := w.Flush(); err != nil {
  2533  		return err
  2534  	}
  2535  	return dst.Close()
  2536  }
  2537  
  2538  // setextld sets the appropriate linker flags for the specified compiler.
  2539  func setextld(ldflags []string, compiler []string) []string {
  2540  	for _, f := range ldflags {
  2541  		if f == "-extld" || strings.HasPrefix(f, "-extld=") {
  2542  			// don't override -extld if supplied
  2543  			return ldflags
  2544  		}
  2545  	}
  2546  	ldflags = append(ldflags, "-extld="+compiler[0])
  2547  	if len(compiler) > 1 {
  2548  		extldflags := false
  2549  		add := strings.Join(compiler[1:], " ")
  2550  		for i, f := range ldflags {
  2551  			if f == "-extldflags" && i+1 < len(ldflags) {
  2552  				ldflags[i+1] = add + " " + ldflags[i+1]
  2553  				extldflags = true
  2554  				break
  2555  			} else if strings.HasPrefix(f, "-extldflags=") {
  2556  				ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
  2557  				extldflags = true
  2558  				break
  2559  			}
  2560  		}
  2561  		if !extldflags {
  2562  			ldflags = append(ldflags, "-extldflags="+add)
  2563  		}
  2564  	}
  2565  	return ldflags
  2566  }
  2567  
  2568  func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
  2569  	importArgs := b.includeArgs("-L", allactions)
  2570  	cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
  2571  	for _, a := range allactions {
  2572  		if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
  2573  			cxx = true
  2574  		}
  2575  	}
  2576  	var ldflags []string
  2577  	if buildContext.InstallSuffix != "" {
  2578  		ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
  2579  	}
  2580  	if root.p.omitDWARF {
  2581  		ldflags = append(ldflags, "-w")
  2582  	}
  2583  	if buildBuildmode == "plugin" {
  2584  		pluginpath := root.p.ImportPath
  2585  		if pluginpath == "command-line-arguments" {
  2586  			pluginpath = "plugin/unnamed-" + root.p.buildID
  2587  		}
  2588  		ldflags = append(ldflags, "-pluginpath", pluginpath)
  2589  	}
  2590  
  2591  	// If the user has not specified the -extld option, then specify the
  2592  	// appropriate linker. In case of C++ code, use the compiler named
  2593  	// by the CXX environment variable or defaultCXX if CXX is not set.
  2594  	// Else, use the CC environment variable and defaultCC as fallback.
  2595  	var compiler []string
  2596  	if cxx {
  2597  		compiler = envList("CXX", defaultCXX)
  2598  	} else {
  2599  		compiler = envList("CC", defaultCC)
  2600  	}
  2601  	ldflags = setextld(ldflags, compiler)
  2602  	ldflags = append(ldflags, "-buildmode="+ldBuildmode)
  2603  	if root.p.buildID != "" {
  2604  		ldflags = append(ldflags, "-buildid="+root.p.buildID)
  2605  	}
  2606  	ldflags = append(ldflags, buildLdflags...)
  2607  
  2608  	// On OS X when using external linking to build a shared library,
  2609  	// the argument passed here to -o ends up recorded in the final
  2610  	// shared library in the LC_ID_DYLIB load command.
  2611  	// To avoid putting the temporary output directory name there
  2612  	// (and making the resulting shared library useless),
  2613  	// run the link in the output directory so that -o can name
  2614  	// just the final path element.
  2615  	dir := "."
  2616  	if goos == "darwin" && buildBuildmode == "c-shared" {
  2617  		dir, out = filepath.Split(out)
  2618  	}
  2619  
  2620  	return b.run(dir, root.p.ImportPath, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags, mainpkg)
  2621  }
  2622  
  2623  func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
  2624  	importArgs := b.includeArgs("-L", allactions)
  2625  	ldflags := []string{"-installsuffix", buildContext.InstallSuffix}
  2626  	ldflags = append(ldflags, "-buildmode=shared")
  2627  	ldflags = append(ldflags, buildLdflags...)
  2628  	cxx := false
  2629  	for _, a := range allactions {
  2630  		if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) {
  2631  			cxx = true
  2632  		}
  2633  	}
  2634  	// If the user has not specified the -extld option, then specify the
  2635  	// appropriate linker. In case of C++ code, use the compiler named
  2636  	// by the CXX environment variable or defaultCXX if CXX is not set.
  2637  	// Else, use the CC environment variable and defaultCC as fallback.
  2638  	var compiler []string
  2639  	if cxx {
  2640  		compiler = envList("CXX", defaultCXX)
  2641  	} else {
  2642  		compiler = envList("CC", defaultCC)
  2643  	}
  2644  	ldflags = setextld(ldflags, compiler)
  2645  	for _, d := range toplevelactions {
  2646  		if !strings.HasSuffix(d.target, ".a") { // omit unsafe etc and actions for other shared libraries
  2647  			continue
  2648  		}
  2649  		ldflags = append(ldflags, d.p.ImportPath+"="+d.target)
  2650  	}
  2651  	return b.run(".", out, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags)
  2652  }
  2653  
  2654  func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  2655  	return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
  2656  }
  2657  
  2658  // The Gccgo toolchain.
  2659  type gccgoToolchain struct{}
  2660  
  2661  var gccgoName, gccgoBin string
  2662  
  2663  func init() {
  2664  	gccgoName = os.Getenv("GCCGO")
  2665  	if gccgoName == "" {
  2666  		gccgoName = "gccgo"
  2667  	}
  2668  	gccgoBin, _ = exec.LookPath(gccgoName)
  2669  }
  2670  
  2671  func (gccgoToolchain) compiler() string {
  2672  	return gccgoBin
  2673  }
  2674  
  2675  func (gccgoToolchain) linker() string {
  2676  	return gccgoBin
  2677  }
  2678  
  2679  func (tools gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
  2680  	out := "_go_.o"
  2681  	ofile = obj + out
  2682  	gcargs := []string{"-g"}
  2683  	gcargs = append(gcargs, b.gccArchArgs()...)
  2684  	if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  2685  		gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
  2686  	}
  2687  	if p.localPrefix != "" {
  2688  		gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
  2689  	}
  2690  	args := stringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
  2691  	for _, f := range gofiles {
  2692  		args = append(args, mkAbs(p.Dir, f))
  2693  	}
  2694  
  2695  	output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
  2696  	return ofile, output, err
  2697  }
  2698  
  2699  func (tools gccgoToolchain) asm(b *builder, p *Package, obj string, sfiles []string) ([]string, error) {
  2700  	var ofiles []string
  2701  	for _, sfile := range sfiles {
  2702  		ofile := obj + sfile[:len(sfile)-len(".s")] + ".o"
  2703  		ofiles = append(ofiles, ofile)
  2704  		sfile = mkAbs(p.Dir, sfile)
  2705  		defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
  2706  		if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  2707  			defs = append(defs, `-D`, `GOPKGPATH=`+pkgpath)
  2708  		}
  2709  		defs = tools.maybePIC(defs)
  2710  		defs = append(defs, b.gccArchArgs()...)
  2711  		err := b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-xassembler-with-cpp", "-I", obj, "-c", "-o", ofile, defs, sfile)
  2712  		if err != nil {
  2713  			return nil, err
  2714  		}
  2715  	}
  2716  	return ofiles, nil
  2717  }
  2718  
  2719  func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
  2720  	end := filepath.FromSlash(p.ImportPath + ".a")
  2721  	afile := filepath.Join(basedir, end)
  2722  	// add "lib" to the final element
  2723  	return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
  2724  }
  2725  
  2726  func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
  2727  	var absOfiles []string
  2728  	for _, f := range ofiles {
  2729  		absOfiles = append(absOfiles, mkAbs(objDir, f))
  2730  	}
  2731  	return b.run(p.Dir, p.ImportPath, nil, "ar", "rc", mkAbs(objDir, afile), absOfiles)
  2732  }
  2733  
  2734  func (tools gccgoToolchain) link(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string, buildmode, desc string) error {
  2735  	// gccgo needs explicit linking with all package dependencies,
  2736  	// and all LDFLAGS from cgo dependencies.
  2737  	apackagePathsSeen := make(map[string]bool)
  2738  	afiles := []string{}
  2739  	shlibs := []string{}
  2740  	ldflags := b.gccArchArgs()
  2741  	cgoldflags := []string{}
  2742  	usesCgo := false
  2743  	cxx := false
  2744  	objc := false
  2745  	fortran := false
  2746  	if root.p != nil {
  2747  		cxx = len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0
  2748  		objc = len(root.p.MFiles) > 0
  2749  		fortran = len(root.p.FFiles) > 0
  2750  	}
  2751  
  2752  	readCgoFlags := func(flagsFile string) error {
  2753  		flags, err := ioutil.ReadFile(flagsFile)
  2754  		if err != nil {
  2755  			return err
  2756  		}
  2757  		const ldflagsPrefix = "_CGO_LDFLAGS="
  2758  		for _, line := range strings.Split(string(flags), "\n") {
  2759  			if strings.HasPrefix(line, ldflagsPrefix) {
  2760  				newFlags := strings.Fields(line[len(ldflagsPrefix):])
  2761  				for _, flag := range newFlags {
  2762  					// Every _cgo_flags file has -g and -O2 in _CGO_LDFLAGS
  2763  					// but they don't mean anything to the linker so filter
  2764  					// them out.
  2765  					if flag != "-g" && !strings.HasPrefix(flag, "-O") {
  2766  						cgoldflags = append(cgoldflags, flag)
  2767  					}
  2768  				}
  2769  			}
  2770  		}
  2771  		return nil
  2772  	}
  2773  
  2774  	readAndRemoveCgoFlags := func(archive string) (string, error) {
  2775  		newa, err := ioutil.TempFile(b.work, filepath.Base(archive))
  2776  		if err != nil {
  2777  			return "", err
  2778  		}
  2779  		olda, err := os.Open(archive)
  2780  		if err != nil {
  2781  			return "", err
  2782  		}
  2783  		_, err = io.Copy(newa, olda)
  2784  		if err != nil {
  2785  			return "", err
  2786  		}
  2787  		err = olda.Close()
  2788  		if err != nil {
  2789  			return "", err
  2790  		}
  2791  		err = newa.Close()
  2792  		if err != nil {
  2793  			return "", err
  2794  		}
  2795  
  2796  		newarchive := newa.Name()
  2797  		err = b.run(b.work, desc, nil, "ar", "x", newarchive, "_cgo_flags")
  2798  		if err != nil {
  2799  			return "", err
  2800  		}
  2801  		err = b.run(".", desc, nil, "ar", "d", newarchive, "_cgo_flags")
  2802  		if err != nil {
  2803  			return "", err
  2804  		}
  2805  		err = readCgoFlags(filepath.Join(b.work, "_cgo_flags"))
  2806  		if err != nil {
  2807  			return "", err
  2808  		}
  2809  		return newarchive, nil
  2810  	}
  2811  
  2812  	actionsSeen := make(map[*action]bool)
  2813  	// Make a pre-order depth-first traversal of the action graph, taking note of
  2814  	// whether a shared library action has been seen on the way to an action (the
  2815  	// construction of the graph means that if any path to a node passes through
  2816  	// a shared library action, they all do).
  2817  	var walk func(a *action, seenShlib bool)
  2818  	var err error
  2819  	walk = func(a *action, seenShlib bool) {
  2820  		if actionsSeen[a] {
  2821  			return
  2822  		}
  2823  		actionsSeen[a] = true
  2824  		if a.p != nil && !seenShlib {
  2825  			if a.p.Standard {
  2826  				return
  2827  			}
  2828  			// We record the target of the first time we see a .a file
  2829  			// for a package to make sure that we prefer the 'install'
  2830  			// rather than the 'build' location (which may not exist any
  2831  			// more). We still need to traverse the dependencies of the
  2832  			// build action though so saying
  2833  			// if apackagePathsSeen[a.p.ImportPath] { return }
  2834  			// doesn't work.
  2835  			if !apackagePathsSeen[a.p.ImportPath] {
  2836  				apackagePathsSeen[a.p.ImportPath] = true
  2837  				target := a.target
  2838  				if len(a.p.CgoFiles) > 0 || a.p.usesSwig() {
  2839  					target, err = readAndRemoveCgoFlags(target)
  2840  					if err != nil {
  2841  						return
  2842  					}
  2843  				}
  2844  				afiles = append(afiles, target)
  2845  			}
  2846  		}
  2847  		if strings.HasSuffix(a.target, ".so") {
  2848  			shlibs = append(shlibs, a.target)
  2849  			seenShlib = true
  2850  		}
  2851  		for _, a1 := range a.deps {
  2852  			walk(a1, seenShlib)
  2853  			if err != nil {
  2854  				return
  2855  			}
  2856  		}
  2857  	}
  2858  	for _, a1 := range root.deps {
  2859  		walk(a1, false)
  2860  		if err != nil {
  2861  			return err
  2862  		}
  2863  	}
  2864  
  2865  	for _, a := range allactions {
  2866  		// Gather CgoLDFLAGS, but not from standard packages.
  2867  		// The go tool can dig up runtime/cgo from GOROOT and
  2868  		// think that it should use its CgoLDFLAGS, but gccgo
  2869  		// doesn't use runtime/cgo.
  2870  		if a.p == nil {
  2871  			continue
  2872  		}
  2873  		if !a.p.Standard {
  2874  			cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
  2875  		}
  2876  		if len(a.p.CgoFiles) > 0 {
  2877  			usesCgo = true
  2878  		}
  2879  		if a.p.usesSwig() {
  2880  			usesCgo = true
  2881  		}
  2882  		if len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0 {
  2883  			cxx = true
  2884  		}
  2885  		if len(a.p.MFiles) > 0 {
  2886  			objc = true
  2887  		}
  2888  		if len(a.p.FFiles) > 0 {
  2889  			fortran = true
  2890  		}
  2891  	}
  2892  
  2893  	for i, o := range ofiles {
  2894  		if filepath.Base(o) == "_cgo_flags" {
  2895  			readCgoFlags(o)
  2896  			ofiles = append(ofiles[:i], ofiles[i+1:]...)
  2897  			break
  2898  		}
  2899  	}
  2900  
  2901  	ldflags = append(ldflags, "-Wl,--whole-archive")
  2902  	ldflags = append(ldflags, afiles...)
  2903  	ldflags = append(ldflags, "-Wl,--no-whole-archive")
  2904  
  2905  	ldflags = append(ldflags, cgoldflags...)
  2906  	ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
  2907  	if root.p != nil {
  2908  		ldflags = append(ldflags, root.p.CgoLDFLAGS...)
  2909  	}
  2910  
  2911  	ldflags = stringList("-Wl,-(", ldflags, "-Wl,-)")
  2912  
  2913  	for _, shlib := range shlibs {
  2914  		ldflags = append(
  2915  			ldflags,
  2916  			"-L"+filepath.Dir(shlib),
  2917  			"-Wl,-rpath="+filepath.Dir(shlib),
  2918  			"-l"+strings.TrimSuffix(
  2919  				strings.TrimPrefix(filepath.Base(shlib), "lib"),
  2920  				".so"))
  2921  	}
  2922  
  2923  	var realOut string
  2924  	switch buildmode {
  2925  	case "exe":
  2926  		if usesCgo && goos == "linux" {
  2927  			ldflags = append(ldflags, "-Wl,-E")
  2928  		}
  2929  
  2930  	case "c-archive":
  2931  		// Link the Go files into a single .o, and also link
  2932  		// in -lgolibbegin.
  2933  		//
  2934  		// We need to use --whole-archive with -lgolibbegin
  2935  		// because it doesn't define any symbols that will
  2936  		// cause the contents to be pulled in; it's just
  2937  		// initialization code.
  2938  		//
  2939  		// The user remains responsible for linking against
  2940  		// -lgo -lpthread -lm in the final link. We can't use
  2941  		// -r to pick them up because we can't combine
  2942  		// split-stack and non-split-stack code in a single -r
  2943  		// link, and libgo picks up non-split-stack code from
  2944  		// libffi.
  2945  		ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive")
  2946  
  2947  		if b.gccSupportsNoPie() {
  2948  			ldflags = append(ldflags, "-no-pie")
  2949  		}
  2950  
  2951  		// We are creating an object file, so we don't want a build ID.
  2952  		ldflags = b.disableBuildID(ldflags)
  2953  
  2954  		realOut = out
  2955  		out = out + ".o"
  2956  
  2957  	case "c-shared":
  2958  		ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc", "-lc", "-lgcc")
  2959  	case "shared":
  2960  		ldflags = append(ldflags, "-zdefs", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc")
  2961  
  2962  	default:
  2963  		fatalf("-buildmode=%s not supported for gccgo", buildmode)
  2964  	}
  2965  
  2966  	switch buildmode {
  2967  	case "exe", "c-shared":
  2968  		if cxx {
  2969  			ldflags = append(ldflags, "-lstdc++")
  2970  		}
  2971  		if objc {
  2972  			ldflags = append(ldflags, "-lobjc")
  2973  		}
  2974  		if fortran {
  2975  			fc := os.Getenv("FC")
  2976  			if fc == "" {
  2977  				fc = "gfortran"
  2978  			}
  2979  			// support gfortran out of the box and let others pass the correct link options
  2980  			// via CGO_LDFLAGS
  2981  			if strings.Contains(fc, "gfortran") {
  2982  				ldflags = append(ldflags, "-lgfortran")
  2983  			}
  2984  		}
  2985  	}
  2986  
  2987  	if err := b.run(".", desc, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil {
  2988  		return err
  2989  	}
  2990  
  2991  	switch buildmode {
  2992  	case "c-archive":
  2993  		if err := b.run(".", desc, nil, "ar", "rc", realOut, out); err != nil {
  2994  			return err
  2995  		}
  2996  	}
  2997  	return nil
  2998  }
  2999  
  3000  func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error {
  3001  	return tools.link(b, root, out, allactions, mainpkg, ofiles, ldBuildmode, root.p.ImportPath)
  3002  }
  3003  
  3004  func (tools gccgoToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error {
  3005  	fakeRoot := &action{}
  3006  	fakeRoot.deps = toplevelactions
  3007  	return tools.link(b, fakeRoot, out, allactions, "", nil, "shared", out)
  3008  }
  3009  
  3010  func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
  3011  	inc := filepath.Join(goroot, "pkg", "include")
  3012  	cfile = mkAbs(p.Dir, cfile)
  3013  	defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
  3014  	defs = append(defs, b.gccArchArgs()...)
  3015  	if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
  3016  		defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
  3017  	}
  3018  	switch goarch {
  3019  	case "386", "amd64":
  3020  		defs = append(defs, "-fsplit-stack")
  3021  	}
  3022  	defs = tools.maybePIC(defs)
  3023  	return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g",
  3024  		"-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
  3025  }
  3026  
  3027  // maybePIC adds -fPIC to the list of arguments if needed.
  3028  func (tools gccgoToolchain) maybePIC(args []string) []string {
  3029  	switch buildBuildmode {
  3030  	case "c-shared", "shared", "plugin":
  3031  		args = append(args, "-fPIC")
  3032  	}
  3033  	return args
  3034  }
  3035  
  3036  func gccgoPkgpath(p *Package) string {
  3037  	if p.build.IsCommand() && !p.forceLibrary {
  3038  		return ""
  3039  	}
  3040  	return p.ImportPath
  3041  }
  3042  
  3043  func gccgoCleanPkgpath(p *Package) string {
  3044  	clean := func(r rune) rune {
  3045  		switch {
  3046  		case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
  3047  			'0' <= r && r <= '9':
  3048  			return r
  3049  		}
  3050  		return '_'
  3051  	}
  3052  	return strings.Map(clean, gccgoPkgpath(p))
  3053  }
  3054  
  3055  // gcc runs the gcc C compiler to create an object from a single C file.
  3056  func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
  3057  	return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
  3058  }
  3059  
  3060  // gxx runs the g++ C++ compiler to create an object from a single C++ file.
  3061  func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
  3062  	return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
  3063  }
  3064  
  3065  // gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.
  3066  func (b *builder) gfortran(p *Package, out string, flags []string, ffile string) error {
  3067  	return b.ccompile(p, out, flags, ffile, b.gfortranCmd(p.Dir))
  3068  }
  3069  
  3070  // ccompile runs the given C or C++ compiler and creates an object from a single source file.
  3071  func (b *builder) ccompile(p *Package, outfile string, flags []string, file string, compiler []string) error {
  3072  	file = mkAbs(p.Dir, file)
  3073  	desc := p.ImportPath
  3074  	output, err := b.runOut(p.Dir, desc, nil, compiler, flags, "-o", outfile, "-c", file)
  3075  	if len(output) > 0 {
  3076  		b.showOutput(p.Dir, desc, b.processOutput(output))
  3077  		if err != nil {
  3078  			err = errPrintedOutput
  3079  		} else if os.Getenv("GO_BUILDER_NAME") != "" {
  3080  			return errors.New("C compiler warning promoted to error on Go builders")
  3081  		}
  3082  	}
  3083  	return err
  3084  }
  3085  
  3086  // gccld runs the gcc linker to create an executable from a set of object files.
  3087  func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
  3088  	var cmd []string
  3089  	if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
  3090  		cmd = b.gxxCmd(p.Dir)
  3091  	} else {
  3092  		cmd = b.gccCmd(p.Dir)
  3093  	}
  3094  	return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
  3095  }
  3096  
  3097  // gccCmd returns a gcc command line prefix
  3098  // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
  3099  func (b *builder) gccCmd(objdir string) []string {
  3100  	return b.ccompilerCmd("CC", defaultCC, objdir)
  3101  }
  3102  
  3103  // gxxCmd returns a g++ command line prefix
  3104  // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
  3105  func (b *builder) gxxCmd(objdir string) []string {
  3106  	return b.ccompilerCmd("CXX", defaultCXX, objdir)
  3107  }
  3108  
  3109  // gfortranCmd returns a gfortran command line prefix.
  3110  func (b *builder) gfortranCmd(objdir string) []string {
  3111  	return b.ccompilerCmd("FC", "gfortran", objdir)
  3112  }
  3113  
  3114  // ccompilerCmd returns a command line prefix for the given environment
  3115  // variable and using the default command when the variable is empty.
  3116  func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
  3117  	// NOTE: env.go's mkEnv knows that the first three
  3118  	// strings returned are "gcc", "-I", objdir (and cuts them off).
  3119  
  3120  	compiler := envList(envvar, defcmd)
  3121  	a := []string{compiler[0], "-I", objdir}
  3122  	a = append(a, compiler[1:]...)
  3123  
  3124  	// Definitely want -fPIC but on Windows gcc complains
  3125  	// "-fPIC ignored for target (all code is position independent)"
  3126  	if goos != "windows" {
  3127  		a = append(a, "-fPIC")
  3128  	}
  3129  	a = append(a, b.gccArchArgs()...)
  3130  	// gcc-4.5 and beyond require explicit "-pthread" flag
  3131  	// for multithreading with pthread library.
  3132  	if buildContext.CgoEnabled {
  3133  		switch goos {
  3134  		case "windows":
  3135  			a = append(a, "-mthreads")
  3136  		default:
  3137  			a = append(a, "-pthread")
  3138  		}
  3139  	}
  3140  
  3141  	if strings.Contains(a[0], "clang") {
  3142  		// disable ASCII art in clang errors, if possible
  3143  		a = append(a, "-fno-caret-diagnostics")
  3144  		// clang is too smart about command-line arguments
  3145  		a = append(a, "-Qunused-arguments")
  3146  	}
  3147  
  3148  	// disable word wrapping in error messages
  3149  	a = append(a, "-fmessage-length=0")
  3150  
  3151  	// Tell gcc not to include the work directory in object files.
  3152  	if b.gccSupportsFlag("-fdebug-prefix-map=a=b") {
  3153  		a = append(a, "-fdebug-prefix-map="+b.work+"=/tmp/go-build")
  3154  	}
  3155  
  3156  	// Tell gcc not to include flags in object files, which defeats the
  3157  	// point of -fdebug-prefix-map above.
  3158  	if b.gccSupportsFlag("-gno-record-gcc-switches") {
  3159  		a = append(a, "-gno-record-gcc-switches")
  3160  	}
  3161  
  3162  	// On OS X, some of the compilers behave as if -fno-common
  3163  	// is always set, and the Mach-O linker in 6l/8l assumes this.
  3164  	// See https://golang.org/issue/3253.
  3165  	if goos == "darwin" {
  3166  		a = append(a, "-fno-common")
  3167  	}
  3168  
  3169  	return a
  3170  }
  3171  
  3172  // On systems with PIE (position independent executables) enabled by default,
  3173  // -no-pie must be passed when doing a partial link with -Wl,-r. But -no-pie is
  3174  // not supported by all compilers.
  3175  func (b *builder) gccSupportsNoPie() bool {
  3176  	return b.gccSupportsFlag("-no-pie")
  3177  }
  3178  
  3179  // gccSupportsFlag checks to see if the compiler supports a flag.
  3180  func (b *builder) gccSupportsFlag(flag string) bool {
  3181  	b.exec.Lock()
  3182  	defer b.exec.Unlock()
  3183  	if b, ok := b.flagCache[flag]; ok {
  3184  		return b
  3185  	}
  3186  	if b.flagCache == nil {
  3187  		src := filepath.Join(b.work, "trivial.c")
  3188  		if err := ioutil.WriteFile(src, []byte{}, 0666); err != nil {
  3189  			return false
  3190  		}
  3191  		b.flagCache = make(map[string]bool)
  3192  	}
  3193  	cmdArgs := append(envList("CC", defaultCC), flag, "-c", "trivial.c")
  3194  	if buildN || buildX {
  3195  		b.showcmd(b.work, "%s", joinUnambiguously(cmdArgs))
  3196  		if buildN {
  3197  			return false
  3198  		}
  3199  	}
  3200  	cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
  3201  	cmd.Dir = b.work
  3202  	cmd.Env = mergeEnvLists([]string{"LC_ALL=C"}, envForDir(cmd.Dir, os.Environ()))
  3203  	out, err := cmd.CombinedOutput()
  3204  	supported := err == nil && !bytes.Contains(out, []byte("unrecognized"))
  3205  	b.flagCache[flag] = supported
  3206  	return supported
  3207  }
  3208  
  3209  // gccArchArgs returns arguments to pass to gcc based on the architecture.
  3210  func (b *builder) gccArchArgs() []string {
  3211  	switch goarch {
  3212  	case "386":
  3213  		return []string{"-m32"}
  3214  	case "amd64", "amd64p32":
  3215  		return []string{"-m64"}
  3216  	case "arm":
  3217  		return []string{"-marm"} // not thumb
  3218  	case "s390x":
  3219  		return []string{"-m64", "-march=z196"}
  3220  	case "mips64", "mips64le":
  3221  		return []string{"-mabi=64"}
  3222  	case "mips", "mipsle":
  3223  		return []string{"-mabi=32", "-march=mips32"}
  3224  	}
  3225  	return nil
  3226  }
  3227  
  3228  // envList returns the value of the given environment variable broken
  3229  // into fields, using the default value when the variable is empty.
  3230  func envList(key, def string) []string {
  3231  	v := os.Getenv(key)
  3232  	if v == "" {
  3233  		v = def
  3234  	}
  3235  	return strings.Fields(v)
  3236  }
  3237  
  3238  // Return the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
  3239  func (b *builder) cflags(p *Package) (cppflags, cflags, cxxflags, fflags, ldflags []string) {
  3240  	defaults := "-g -O2"
  3241  
  3242  	cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
  3243  	cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
  3244  	cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
  3245  	fflags = stringList(envList("CGO_FFLAGS", defaults), p.CgoFFLAGS)
  3246  	ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
  3247  	return
  3248  }
  3249  
  3250  var cgoRe = regexp.MustCompile(`[/\\:]`)
  3251  
  3252  func (b *builder) cgo(a *action, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofiles, objdirCgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) {
  3253  	p := a.p
  3254  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS := b.cflags(p)
  3255  	cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
  3256  	cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
  3257  	// If we are compiling Objective-C code, then we need to link against libobjc
  3258  	if len(mfiles) > 0 {
  3259  		cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
  3260  	}
  3261  
  3262  	// Likewise for Fortran, except there are many Fortran compilers.
  3263  	// Support gfortran out of the box and let others pass the correct link options
  3264  	// via CGO_LDFLAGS
  3265  	if len(ffiles) > 0 {
  3266  		fc := os.Getenv("FC")
  3267  		if fc == "" {
  3268  			fc = "gfortran"
  3269  		}
  3270  		if strings.Contains(fc, "gfortran") {
  3271  			cgoLDFLAGS = append(cgoLDFLAGS, "-lgfortran")
  3272  		}
  3273  	}
  3274  
  3275  	if buildMSan {
  3276  		cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
  3277  		cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
  3278  	}
  3279  
  3280  	// Allows including _cgo_export.h from .[ch] files in the package.
  3281  	cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
  3282  
  3283  	// If we have cgo files in the object directory, then copy any
  3284  	// other cgo files into the object directory, and pass a
  3285  	// -srcdir option to cgo.
  3286  	var srcdirarg []string
  3287  	if len(objdirCgofiles) > 0 {
  3288  		for _, fn := range cgofiles {
  3289  			if err := b.copyFile(a, obj+filepath.Base(fn), filepath.Join(p.Dir, fn), 0666, false); err != nil {
  3290  				return nil, nil, err
  3291  			}
  3292  		}
  3293  		cgofiles = append(cgofiles, objdirCgofiles...)
  3294  		srcdirarg = []string{"-srcdir", obj}
  3295  	}
  3296  
  3297  	// cgo
  3298  	// TODO: CGO_FLAGS?
  3299  	gofiles := []string{obj + "_cgo_gotypes.go"}
  3300  	cfiles := []string{"_cgo_export.c"}
  3301  	for _, fn := range cgofiles {
  3302  		f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
  3303  		gofiles = append(gofiles, obj+f+"cgo1.go")
  3304  		cfiles = append(cfiles, f+"cgo2.c")
  3305  	}
  3306  
  3307  	// TODO: make cgo not depend on $GOARCH?
  3308  
  3309  	cgoflags := []string{}
  3310  	if p.Standard && p.ImportPath == "runtime/cgo" {
  3311  		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
  3312  	}
  3313  	if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") {
  3314  		cgoflags = append(cgoflags, "-import_syscall=false")
  3315  	}
  3316  
  3317  	// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
  3318  	var cgoenv []string
  3319  	if len(cgoLDFLAGS) > 0 {
  3320  		flags := make([]string, len(cgoLDFLAGS))
  3321  		for i, f := range cgoLDFLAGS {
  3322  			flags[i] = strconv.Quote(f)
  3323  		}
  3324  		cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
  3325  	}
  3326  
  3327  	if _, ok := buildToolchain.(gccgoToolchain); ok {
  3328  		switch goarch {
  3329  		case "386", "amd64":
  3330  			cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
  3331  		}
  3332  		cgoflags = append(cgoflags, "-gccgo")
  3333  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  3334  			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
  3335  		}
  3336  	}
  3337  
  3338  	switch buildBuildmode {
  3339  	case "c-archive", "c-shared":
  3340  		// Tell cgo that if there are any exported functions
  3341  		// it should generate a header file that C code can
  3342  		// #include.
  3343  		cgoflags = append(cgoflags, "-exportheader="+obj+"_cgo_install.h")
  3344  	}
  3345  
  3346  	if err := b.run(p.Dir, p.ImportPath, cgoenv, buildToolExec, cgoExe, srcdirarg, "-objdir", obj, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil {
  3347  		return nil, nil, err
  3348  	}
  3349  	outGo = append(outGo, gofiles...)
  3350  
  3351  	// gcc
  3352  	cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
  3353  	for _, cfile := range cfiles {
  3354  		ofile := obj + cfile[:len(cfile)-1] + "o"
  3355  		if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
  3356  			return nil, nil, err
  3357  		}
  3358  		outObj = append(outObj, ofile)
  3359  	}
  3360  
  3361  	for _, file := range gccfiles {
  3362  		base := filepath.Base(file)
  3363  		ofile := obj + cgoRe.ReplaceAllString(base[:len(base)-1], "_") + "o"
  3364  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  3365  			return nil, nil, err
  3366  		}
  3367  		outObj = append(outObj, ofile)
  3368  	}
  3369  
  3370  	cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
  3371  	for _, file := range gxxfiles {
  3372  		// Append .o to the file, just in case the pkg has file.c and file.cpp
  3373  		ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
  3374  		if err := b.gxx(p, ofile, cxxflags, file); err != nil {
  3375  			return nil, nil, err
  3376  		}
  3377  		outObj = append(outObj, ofile)
  3378  	}
  3379  
  3380  	for _, file := range mfiles {
  3381  		// Append .o to the file, just in case the pkg has file.c and file.m
  3382  		ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
  3383  		if err := b.gcc(p, ofile, cflags, file); err != nil {
  3384  			return nil, nil, err
  3385  		}
  3386  		outObj = append(outObj, ofile)
  3387  	}
  3388  
  3389  	fflags := stringList(cgoCPPFLAGS, cgoFFLAGS)
  3390  	for _, file := range ffiles {
  3391  		// Append .o to the file, just in case the pkg has file.c and file.f
  3392  		ofile := obj + cgoRe.ReplaceAllString(filepath.Base(file), "_") + ".o"
  3393  		if err := b.gfortran(p, ofile, fflags, file); err != nil {
  3394  			return nil, nil, err
  3395  		}
  3396  		outObj = append(outObj, ofile)
  3397  	}
  3398  
  3399  	switch buildToolchain.(type) {
  3400  	case gcToolchain:
  3401  		importGo := obj + "_cgo_import.go"
  3402  		if err := b.dynimport(p, obj, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil {
  3403  			return nil, nil, err
  3404  		}
  3405  		outGo = append(outGo, importGo)
  3406  
  3407  		ofile := obj + "_all.o"
  3408  		if err := b.collect(p, obj, ofile, cgoLDFLAGS, outObj); err != nil {
  3409  			return nil, nil, err
  3410  		}
  3411  		outObj = []string{ofile}
  3412  
  3413  	case gccgoToolchain:
  3414  		defunC := obj + "_cgo_defun.c"
  3415  		defunObj := obj + "_cgo_defun.o"
  3416  		if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
  3417  			return nil, nil, err
  3418  		}
  3419  		outObj = append(outObj, defunObj)
  3420  
  3421  	default:
  3422  		noCompiler()
  3423  	}
  3424  
  3425  	return outGo, outObj, nil
  3426  }
  3427  
  3428  // dynimport creates a Go source file named importGo containing
  3429  // //go:cgo_import_dynamic directives for each symbol or library
  3430  // dynamically imported by the object files outObj.
  3431  func (b *builder) dynimport(p *Package, obj, importGo, cgoExe string, cflags, cgoLDFLAGS, outObj []string) error {
  3432  	cfile := obj + "_cgo_main.c"
  3433  	ofile := obj + "_cgo_main.o"
  3434  	if err := b.gcc(p, ofile, cflags, cfile); err != nil {
  3435  		return err
  3436  	}
  3437  
  3438  	linkobj := stringList(ofile, outObj, p.SysoFiles)
  3439  	dynobj := obj + "_cgo_.o"
  3440  
  3441  	// we need to use -pie for Linux/ARM to get accurate imported sym
  3442  	ldflags := cgoLDFLAGS
  3443  	if (goarch == "arm" && goos == "linux") || goos == "android" {
  3444  		ldflags = append(ldflags, "-pie")
  3445  	}
  3446  	if err := b.gccld(p, dynobj, ldflags, linkobj); err != nil {
  3447  		return err
  3448  	}
  3449  
  3450  	// cgo -dynimport
  3451  	var cgoflags []string
  3452  	if p.Standard && p.ImportPath == "runtime/cgo" {
  3453  		cgoflags = []string{"-dynlinker"} // record path to dynamic linker
  3454  	}
  3455  	return b.run(p.Dir, p.ImportPath, nil, buildToolExec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
  3456  }
  3457  
  3458  // collect partially links the object files outObj into a single
  3459  // relocatable object file named ofile.
  3460  func (b *builder) collect(p *Package, obj, ofile string, cgoLDFLAGS, outObj []string) error {
  3461  	// When linking relocatable objects, various flags need to be
  3462  	// filtered out as they are inapplicable and can cause some linkers
  3463  	// to fail.
  3464  	var ldflags []string
  3465  	for i := 0; i < len(cgoLDFLAGS); i++ {
  3466  		f := cgoLDFLAGS[i]
  3467  		switch {
  3468  		// skip "-lc" or "-l somelib"
  3469  		case strings.HasPrefix(f, "-l"):
  3470  			if f == "-l" {
  3471  				i++
  3472  			}
  3473  		// skip "-framework X" on Darwin
  3474  		case goos == "darwin" && f == "-framework":
  3475  			i++
  3476  		// skip "*.{dylib,so,dll,o,a}"
  3477  		case strings.HasSuffix(f, ".dylib"),
  3478  			strings.HasSuffix(f, ".so"),
  3479  			strings.HasSuffix(f, ".dll"),
  3480  			strings.HasSuffix(f, ".o"),
  3481  			strings.HasSuffix(f, ".a"):
  3482  		// Remove any -fsanitize=foo flags.
  3483  		// Otherwise the compiler driver thinks that we are doing final link
  3484  		// and links sanitizer runtime into the object file. But we are not doing
  3485  		// the final link, we will link the resulting object file again. And
  3486  		// so the program ends up with two copies of sanitizer runtime.
  3487  		// See issue 8788 for details.
  3488  		case strings.HasPrefix(f, "-fsanitize="):
  3489  			continue
  3490  		// runpath flags not applicable unless building a shared
  3491  		// object or executable; see issue 12115 for details. This
  3492  		// is necessary as Go currently does not offer a way to
  3493  		// specify the set of LDFLAGS that only apply to shared
  3494  		// objects.
  3495  		case strings.HasPrefix(f, "-Wl,-rpath"):
  3496  			if f == "-Wl,-rpath" || f == "-Wl,-rpath-link" {
  3497  				// Skip following argument to -rpath* too.
  3498  				i++
  3499  			}
  3500  		default:
  3501  			ldflags = append(ldflags, f)
  3502  		}
  3503  	}
  3504  
  3505  	ldflags = append(ldflags, "-Wl,-r", "-nostdlib")
  3506  
  3507  	if b.gccSupportsNoPie() {
  3508  		ldflags = append(ldflags, "-no-pie")
  3509  	}
  3510  
  3511  	// We are creating an object file, so we don't want a build ID.
  3512  	ldflags = b.disableBuildID(ldflags)
  3513  
  3514  	return b.gccld(p, ofile, ldflags, outObj)
  3515  }
  3516  
  3517  // Run SWIG on all SWIG input files.
  3518  // TODO: Don't build a shared library, once SWIG emits the necessary
  3519  // pragmas for external linking.
  3520  func (b *builder) swig(p *Package, obj string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
  3521  	if err := b.swigVersionCheck(); err != nil {
  3522  		return nil, nil, nil, err
  3523  	}
  3524  
  3525  	intgosize, err := b.swigIntSize(obj)
  3526  	if err != nil {
  3527  		return nil, nil, nil, err
  3528  	}
  3529  
  3530  	for _, f := range p.SwigFiles {
  3531  		goFile, cFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
  3532  		if err != nil {
  3533  			return nil, nil, nil, err
  3534  		}
  3535  		if goFile != "" {
  3536  			outGo = append(outGo, goFile)
  3537  		}
  3538  		if cFile != "" {
  3539  			outC = append(outC, cFile)
  3540  		}
  3541  	}
  3542  	for _, f := range p.SwigCXXFiles {
  3543  		goFile, cxxFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
  3544  		if err != nil {
  3545  			return nil, nil, nil, err
  3546  		}
  3547  		if goFile != "" {
  3548  			outGo = append(outGo, goFile)
  3549  		}
  3550  		if cxxFile != "" {
  3551  			outCXX = append(outCXX, cxxFile)
  3552  		}
  3553  	}
  3554  	return outGo, outC, outCXX, nil
  3555  }
  3556  
  3557  // Make sure SWIG is new enough.
  3558  var (
  3559  	swigCheckOnce sync.Once
  3560  	swigCheck     error
  3561  )
  3562  
  3563  func (b *builder) swigDoVersionCheck() error {
  3564  	out, err := b.runOut("", "", nil, "swig", "-version")
  3565  	if err != nil {
  3566  		return err
  3567  	}
  3568  	re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
  3569  	matches := re.FindSubmatch(out)
  3570  	if matches == nil {
  3571  		// Can't find version number; hope for the best.
  3572  		return nil
  3573  	}
  3574  
  3575  	major, err := strconv.Atoi(string(matches[1]))
  3576  	if err != nil {
  3577  		// Can't find version number; hope for the best.
  3578  		return nil
  3579  	}
  3580  	const errmsg = "must have SWIG version >= 3.0.6"
  3581  	if major < 3 {
  3582  		return errors.New(errmsg)
  3583  	}
  3584  	if major > 3 {
  3585  		// 4.0 or later
  3586  		return nil
  3587  	}
  3588  
  3589  	// We have SWIG version 3.x.
  3590  	if len(matches[2]) > 0 {
  3591  		minor, err := strconv.Atoi(string(matches[2][1:]))
  3592  		if err != nil {
  3593  			return nil
  3594  		}
  3595  		if minor > 0 {
  3596  			// 3.1 or later
  3597  			return nil
  3598  		}
  3599  	}
  3600  
  3601  	// We have SWIG version 3.0.x.
  3602  	if len(matches[3]) > 0 {
  3603  		patch, err := strconv.Atoi(string(matches[3][1:]))
  3604  		if err != nil {
  3605  			return nil
  3606  		}
  3607  		if patch < 6 {
  3608  			// Before 3.0.6.
  3609  			return errors.New(errmsg)
  3610  		}
  3611  	}
  3612  
  3613  	return nil
  3614  }
  3615  
  3616  func (b *builder) swigVersionCheck() error {
  3617  	swigCheckOnce.Do(func() {
  3618  		swigCheck = b.swigDoVersionCheck()
  3619  	})
  3620  	return swigCheck
  3621  }
  3622  
  3623  // Find the value to pass for the -intgosize option to swig.
  3624  var (
  3625  	swigIntSizeOnce  sync.Once
  3626  	swigIntSize      string
  3627  	swigIntSizeError error
  3628  )
  3629  
  3630  // This code fails to build if sizeof(int) <= 32
  3631  const swigIntSizeCode = `
  3632  package main
  3633  const i int = 1 << 32
  3634  `
  3635  
  3636  // Determine the size of int on the target system for the -intgosize option
  3637  // of swig >= 2.0.9.  Run only once.
  3638  func (b *builder) swigDoIntSize(obj string) (intsize string, err error) {
  3639  	if buildN {
  3640  		return "$INTBITS", nil
  3641  	}
  3642  	src := filepath.Join(b.work, "swig_intsize.go")
  3643  	if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
  3644  		return
  3645  	}
  3646  	srcs := []string{src}
  3647  
  3648  	p := goFilesPackage(srcs)
  3649  
  3650  	if _, _, e := buildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil {
  3651  		return "32", nil
  3652  	}
  3653  	return "64", nil
  3654  }
  3655  
  3656  // Determine the size of int on the target system for the -intgosize option
  3657  // of swig >= 2.0.9.
  3658  func (b *builder) swigIntSize(obj string) (intsize string, err error) {
  3659  	swigIntSizeOnce.Do(func() {
  3660  		swigIntSize, swigIntSizeError = b.swigDoIntSize(obj)
  3661  	})
  3662  	return swigIntSize, swigIntSizeError
  3663  }
  3664  
  3665  // Run SWIG on one SWIG input file.
  3666  func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
  3667  	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _ := b.cflags(p)
  3668  	var cflags []string
  3669  	if cxx {
  3670  		cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
  3671  	} else {
  3672  		cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
  3673  	}
  3674  
  3675  	n := 5 // length of ".swig"
  3676  	if cxx {
  3677  		n = 8 // length of ".swigcxx"
  3678  	}
  3679  	base := file[:len(file)-n]
  3680  	goFile := base + ".go"
  3681  	gccBase := base + "_wrap."
  3682  	gccExt := "c"
  3683  	if cxx {
  3684  		gccExt = "cxx"
  3685  	}
  3686  
  3687  	_, gccgo := buildToolchain.(gccgoToolchain)
  3688  
  3689  	// swig
  3690  	args := []string{
  3691  		"-go",
  3692  		"-cgo",
  3693  		"-intgosize", intgosize,
  3694  		"-module", base,
  3695  		"-o", obj + gccBase + gccExt,
  3696  		"-outdir", obj,
  3697  	}
  3698  
  3699  	for _, f := range cflags {
  3700  		if len(f) > 3 && f[:2] == "-I" {
  3701  			args = append(args, f)
  3702  		}
  3703  	}
  3704  
  3705  	if gccgo {
  3706  		args = append(args, "-gccgo")
  3707  		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
  3708  			args = append(args, "-go-pkgpath", pkgpath)
  3709  		}
  3710  	}
  3711  	if cxx {
  3712  		args = append(args, "-c++")
  3713  	}
  3714  
  3715  	out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file)
  3716  	if err != nil {
  3717  		if len(out) > 0 {
  3718  			if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
  3719  				return "", "", errors.New("must have SWIG version >= 3.0.6")
  3720  			}
  3721  			b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig error
  3722  			return "", "", errPrintedOutput
  3723  		}
  3724  		return "", "", err
  3725  	}
  3726  	if len(out) > 0 {
  3727  		b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig warning
  3728  	}
  3729  
  3730  	return goFile, obj + gccBase + gccExt, nil
  3731  }
  3732  
  3733  // disableBuildID adjusts a linker command line to avoid creating a
  3734  // build ID when creating an object file rather than an executable or
  3735  // shared library. Some systems, such as Ubuntu, always add
  3736  // --build-id to every link, but we don't want a build ID when we are
  3737  // producing an object file. On some of those system a plain -r (not
  3738  // -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a
  3739  // plain -r. I don't know how to turn off --build-id when using clang
  3740  // other than passing a trailing --build-id=none. So that is what we
  3741  // do, but only on systems likely to support it, which is to say,
  3742  // systems that normally use gold or the GNU linker.
  3743  func (b *builder) disableBuildID(ldflags []string) []string {
  3744  	switch goos {
  3745  	case "android", "dragonfly", "linux", "netbsd":
  3746  		ldflags = append(ldflags, "-Wl,--build-id=none")
  3747  	}
  3748  	return ldflags
  3749  }
  3750  
  3751  // An actionQueue is a priority queue of actions.
  3752  type actionQueue []*action
  3753  
  3754  // Implement heap.Interface
  3755  func (q *actionQueue) Len() int           { return len(*q) }
  3756  func (q *actionQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
  3757  func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
  3758  func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) }
  3759  func (q *actionQueue) Pop() interface{} {
  3760  	n := len(*q) - 1
  3761  	x := (*q)[n]
  3762  	*q = (*q)[:n]
  3763  	return x
  3764  }
  3765  
  3766  func (q *actionQueue) push(a *action) {
  3767  	heap.Push(q, a)
  3768  }
  3769  
  3770  func (q *actionQueue) pop() *action {
  3771  	return heap.Pop(q).(*action)
  3772  }
  3773  
  3774  func instrumentInit() {
  3775  	if !buildRace && !buildMSan {
  3776  		return
  3777  	}
  3778  	if buildRace && buildMSan {
  3779  		fmt.Fprintf(os.Stderr, "go %s: may not use -race and -msan simultaneously\n", flag.Args()[0])
  3780  		os.Exit(2)
  3781  	}
  3782  	if buildMSan && (goos != "linux" || goarch != "amd64") {
  3783  		fmt.Fprintf(os.Stderr, "-msan is not supported on %s/%s\n", goos, goarch)
  3784  		os.Exit(2)
  3785  	}
  3786  	if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" {
  3787  		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])
  3788  		os.Exit(2)
  3789  	}
  3790  	if !buildContext.CgoEnabled {
  3791  		fmt.Fprintf(os.Stderr, "go %s: -race requires cgo; enable cgo by setting CGO_ENABLED=1\n", flag.Args()[0])
  3792  		os.Exit(2)
  3793  	}
  3794  	if buildRace {
  3795  		buildGcflags = append(buildGcflags, "-race")
  3796  		buildLdflags = append(buildLdflags, "-race")
  3797  	} else {
  3798  		buildGcflags = append(buildGcflags, "-msan")
  3799  		buildLdflags = append(buildLdflags, "-msan")
  3800  	}
  3801  	if buildContext.InstallSuffix != "" {
  3802  		buildContext.InstallSuffix += "_"
  3803  	}
  3804  
  3805  	if buildRace {
  3806  		buildContext.InstallSuffix += "race"
  3807  		buildContext.BuildTags = append(buildContext.BuildTags, "race")
  3808  	} else {
  3809  		buildContext.InstallSuffix += "msan"
  3810  		buildContext.BuildTags = append(buildContext.BuildTags, "msan")
  3811  	}
  3812  }