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