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