github.com/peggyl/go@v0.0.0-20151008231540-ae315999c2d5/src/cmd/go/build.go (about)

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