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