Home | History | Annotate | Download | only in work
      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 // Action graph execution.
      6 
      7 package work
      8 
      9 import (
     10 	"bytes"
     11 	"encoding/json"
     12 	"errors"
     13 	"fmt"
     14 	"io"
     15 	"io/ioutil"
     16 	"log"
     17 	"os"
     18 	"os/exec"
     19 	"path/filepath"
     20 	"regexp"
     21 	"runtime"
     22 	"strconv"
     23 	"strings"
     24 	"sync"
     25 	"time"
     26 
     27 	"cmd/go/internal/base"
     28 	"cmd/go/internal/cache"
     29 	"cmd/go/internal/cfg"
     30 	"cmd/go/internal/load"
     31 	"cmd/go/internal/str"
     32 )
     33 
     34 // actionList returns the list of actions in the dag rooted at root
     35 // as visited in a depth-first post-order traversal.
     36 func actionList(root *Action) []*Action {
     37 	seen := map[*Action]bool{}
     38 	all := []*Action{}
     39 	var walk func(*Action)
     40 	walk = func(a *Action) {
     41 		if seen[a] {
     42 			return
     43 		}
     44 		seen[a] = true
     45 		for _, a1 := range a.Deps {
     46 			walk(a1)
     47 		}
     48 		all = append(all, a)
     49 	}
     50 	walk(root)
     51 	return all
     52 }
     53 
     54 // do runs the action graph rooted at root.
     55 func (b *Builder) Do(root *Action) {
     56 	if c := cache.Default(); c != nil && !b.ComputeStaleOnly {
     57 		// If we're doing real work, take time at the end to trim the cache.
     58 		defer c.Trim()
     59 	}
     60 
     61 	// Build list of all actions, assigning depth-first post-order priority.
     62 	// The original implementation here was a true queue
     63 	// (using a channel) but it had the effect of getting
     64 	// distracted by low-level leaf actions to the detriment
     65 	// of completing higher-level actions. The order of
     66 	// work does not matter much to overall execution time,
     67 	// but when running "go test std" it is nice to see each test
     68 	// results as soon as possible. The priorities assigned
     69 	// ensure that, all else being equal, the execution prefers
     70 	// to do what it would have done first in a simple depth-first
     71 	// dependency order traversal.
     72 	all := actionList(root)
     73 	for i, a := range all {
     74 		a.priority = i
     75 	}
     76 
     77 	if cfg.DebugActiongraph != "" {
     78 		js := actionGraphJSON(root)
     79 		if err := ioutil.WriteFile(cfg.DebugActiongraph, []byte(js), 0666); err != nil {
     80 			fmt.Fprintf(os.Stderr, "go: writing action graph: %v\n", err)
     81 			base.SetExitStatus(1)
     82 		}
     83 	}
     84 
     85 	b.readySema = make(chan bool, len(all))
     86 
     87 	// Initialize per-action execution state.
     88 	for _, a := range all {
     89 		for _, a1 := range a.Deps {
     90 			a1.triggers = append(a1.triggers, a)
     91 		}
     92 		a.pending = len(a.Deps)
     93 		if a.pending == 0 {
     94 			b.ready.push(a)
     95 			b.readySema <- true
     96 		}
     97 	}
     98 
     99 	// Handle runs a single action and takes care of triggering
    100 	// any actions that are runnable as a result.
    101 	handle := func(a *Action) {
    102 		var err error
    103 
    104 		if a.Func != nil && (!a.Failed || a.IgnoreFail) {
    105 			if err == nil {
    106 				err = a.Func(b, a)
    107 			}
    108 		}
    109 
    110 		// The actions run in parallel but all the updates to the
    111 		// shared work state are serialized through b.exec.
    112 		b.exec.Lock()
    113 		defer b.exec.Unlock()
    114 
    115 		if err != nil {
    116 			if err == errPrintedOutput {
    117 				base.SetExitStatus(2)
    118 			} else {
    119 				base.Errorf("%s", err)
    120 			}
    121 			a.Failed = true
    122 		}
    123 
    124 		for _, a0 := range a.triggers {
    125 			if a.Failed {
    126 				a0.Failed = true
    127 			}
    128 			if a0.pending--; a0.pending == 0 {
    129 				b.ready.push(a0)
    130 				b.readySema <- true
    131 			}
    132 		}
    133 
    134 		if a == root {
    135 			close(b.readySema)
    136 		}
    137 	}
    138 
    139 	var wg sync.WaitGroup
    140 
    141 	// Kick off goroutines according to parallelism.
    142 	// If we are using the -n flag (just printing commands)
    143 	// drop the parallelism to 1, both to make the output
    144 	// deterministic and because there is no real work anyway.
    145 	par := cfg.BuildP
    146 	if cfg.BuildN {
    147 		par = 1
    148 	}
    149 	for i := 0; i < par; i++ {
    150 		wg.Add(1)
    151 		go func() {
    152 			defer wg.Done()
    153 			for {
    154 				select {
    155 				case _, ok := <-b.readySema:
    156 					if !ok {
    157 						return
    158 					}
    159 					// Receiving a value from b.readySema entitles
    160 					// us to take from the ready queue.
    161 					b.exec.Lock()
    162 					a := b.ready.pop()
    163 					b.exec.Unlock()
    164 					handle(a)
    165 				case <-base.Interrupted:
    166 					base.SetExitStatus(1)
    167 					return
    168 				}
    169 			}
    170 		}()
    171 	}
    172 
    173 	wg.Wait()
    174 }
    175 
    176 // buildActionID computes the action ID for a build action.
    177 func (b *Builder) buildActionID(a *Action) cache.ActionID {
    178 	p := a.Package
    179 	h := cache.NewHash("build " + p.ImportPath)
    180 
    181 	// Configuration independent of compiler toolchain.
    182 	// Note: buildmode has already been accounted for in buildGcflags
    183 	// and should not be inserted explicitly. Most buildmodes use the
    184 	// same compiler settings and can reuse each other's results.
    185 	// If not, the reason is already recorded in buildGcflags.
    186 	fmt.Fprintf(h, "compile\n")
    187 	// The compiler hides the exact value of $GOROOT
    188 	// when building things in GOROOT,
    189 	// but it does not hide the exact value of $GOPATH.
    190 	// Include the full dir in that case.
    191 	// Assume b.WorkDir is being trimmed properly.
    192 	if !p.Goroot && !strings.HasPrefix(p.Dir, b.WorkDir) {
    193 		fmt.Fprintf(h, "dir %s\n", p.Dir)
    194 	}
    195 	fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch)
    196 	fmt.Fprintf(h, "import %q\n", p.ImportPath)
    197 	fmt.Fprintf(h, "omitdebug %v standard %v local %v prefix %q\n", p.Internal.OmitDebug, p.Standard, p.Internal.Local, p.Internal.LocalPrefix)
    198 	if len(p.CgoFiles)+len(p.SwigFiles) > 0 {
    199 		fmt.Fprintf(h, "cgo %q\n", b.toolID("cgo"))
    200 		cppflags, cflags, cxxflags, fflags, _, _ := b.CFlags(p)
    201 		fmt.Fprintf(h, "CC=%q %q %q\n", b.ccExe(), cppflags, cflags)
    202 		if len(p.CXXFiles)+len(p.SwigFiles) > 0 {
    203 			fmt.Fprintf(h, "CXX=%q %q\n", b.cxxExe(), cxxflags)
    204 		}
    205 		if len(p.FFiles) > 0 {
    206 			fmt.Fprintf(h, "FC=%q %q\n", b.fcExe(), fflags)
    207 		}
    208 		// TODO(rsc): Should we include the SWIG version or Fortran/GCC/G++/Objective-C compiler versions?
    209 	}
    210 	if p.Internal.CoverMode != "" {
    211 		fmt.Fprintf(h, "cover %q %q\n", p.Internal.CoverMode, b.toolID("cover"))
    212 	}
    213 
    214 	// Configuration specific to compiler toolchain.
    215 	switch cfg.BuildToolchainName {
    216 	default:
    217 		base.Fatalf("buildActionID: unknown build toolchain %q", cfg.BuildToolchainName)
    218 	case "gc":
    219 		fmt.Fprintf(h, "compile %s %q %q\n", b.toolID("compile"), forcedGcflags, p.Internal.Gcflags)
    220 		if len(p.SFiles) > 0 {
    221 			fmt.Fprintf(h, "asm %q %q %q\n", b.toolID("asm"), forcedAsmflags, p.Internal.Asmflags)
    222 		}
    223 		fmt.Fprintf(h, "GO$GOARCH=%s\n", os.Getenv("GO"+strings.ToUpper(cfg.BuildContext.GOARCH))) // GO386, GOARM, etc
    224 
    225 		// TODO(rsc): Convince compiler team not to add more magic environment variables,
    226 		// or perhaps restrict the environment variables passed to subprocesses.
    227 		magic := []string{
    228 			"GOCLOBBERDEADHASH",
    229 			"GOSSAFUNC",
    230 			"GO_SSA_PHI_LOC_CUTOFF",
    231 			"GOSSAHASH",
    232 		}
    233 		for _, env := range magic {
    234 			if x := os.Getenv(env); x != "" {
    235 				fmt.Fprintf(h, "magic %s=%s\n", env, x)
    236 			}
    237 		}
    238 		if os.Getenv("GOSSAHASH") != "" {
    239 			for i := 0; ; i++ {
    240 				env := fmt.Sprintf("GOSSAHASH%d", i)
    241 				x := os.Getenv(env)
    242 				if x == "" {
    243 					break
    244 				}
    245 				fmt.Fprintf(h, "magic %s=%s\n", env, x)
    246 			}
    247 		}
    248 		if os.Getenv("GSHS_LOGFILE") != "" {
    249 			// Clumsy hack. Compiler writes to this log file,
    250 			// so do not allow use of cache at all.
    251 			// We will still write to the cache but it will be
    252 			// essentially unfindable.
    253 			fmt.Fprintf(h, "nocache %d\n", time.Now().UnixNano())
    254 		}
    255 
    256 	case "gccgo":
    257 		id, err := b.gccgoToolID(BuildToolchain.compiler(), "go")
    258 		if err != nil {
    259 			base.Fatalf("%v", err)
    260 		}
    261 		fmt.Fprintf(h, "compile %s %q %q\n", id, forcedGccgoflags, p.Internal.Gccgoflags)
    262 		fmt.Fprintf(h, "pkgpath %s\n", gccgoPkgpath(p))
    263 		if len(p.SFiles) > 0 {
    264 			id, err = b.gccgoToolID(BuildToolchain.compiler(), "assembler-with-cpp")
    265 			// Ignore error; different assembler versions
    266 			// are unlikely to make any difference anyhow.
    267 			fmt.Fprintf(h, "asm %q\n", id)
    268 		}
    269 	}
    270 
    271 	// Input files.
    272 	inputFiles := str.StringList(
    273 		p.GoFiles,
    274 		p.CgoFiles,
    275 		p.CFiles,
    276 		p.CXXFiles,
    277 		p.FFiles,
    278 		p.MFiles,
    279 		p.HFiles,
    280 		p.SFiles,
    281 		p.SysoFiles,
    282 		p.SwigFiles,
    283 		p.SwigCXXFiles,
    284 	)
    285 	for _, file := range inputFiles {
    286 		fmt.Fprintf(h, "file %s %s\n", file, b.fileHash(filepath.Join(p.Dir, file)))
    287 	}
    288 	for _, a1 := range a.Deps {
    289 		p1 := a1.Package
    290 		if p1 != nil {
    291 			fmt.Fprintf(h, "import %s %s\n", p1.ImportPath, contentID(a1.buildID))
    292 		}
    293 	}
    294 
    295 	return h.Sum()
    296 }
    297 
    298 // build is the action for building a single package.
    299 // Note that any new influence on this logic must be reported in b.buildActionID above as well.
    300 func (b *Builder) build(a *Action) (err error) {
    301 	p := a.Package
    302 	cached := false
    303 	if !p.BinaryOnly {
    304 		if b.useCache(a, p, b.buildActionID(a), p.Target) {
    305 			// If this build triggers a header install, run cgo to get the header.
    306 			// TODO(rsc): Once we can cache multiple file outputs from an action,
    307 			// the header should be cached, and then this awful test can be deleted.
    308 			// Need to look for install header actions depending on this action,
    309 			// or depending on a link that depends on this action.
    310 			needHeader := false
    311 			if (a.Package.UsesCgo() || a.Package.UsesSwig()) && (cfg.BuildBuildmode == "c-archive" || cfg.BuildBuildmode == "c-shared") {
    312 				for _, t1 := range a.triggers {
    313 					if t1.Mode == "install header" {
    314 						needHeader = true
    315 						goto CheckedHeader
    316 					}
    317 				}
    318 				for _, t1 := range a.triggers {
    319 					for _, t2 := range t1.triggers {
    320 						if t2.Mode == "install header" {
    321 							needHeader = true
    322 							goto CheckedHeader
    323 						}
    324 					}
    325 				}
    326 			}
    327 		CheckedHeader:
    328 			if b.ComputeStaleOnly || !a.needVet && !needHeader {
    329 				return nil
    330 			}
    331 			cached = true
    332 		}
    333 		defer b.flushOutput(a)
    334 	}
    335 
    336 	defer func() {
    337 		if err != nil && err != errPrintedOutput {
    338 			err = fmt.Errorf("go build %s: %v", a.Package.ImportPath, err)
    339 		}
    340 	}()
    341 	if cfg.BuildN {
    342 		// In -n mode, print a banner between packages.
    343 		// The banner is five lines so that when changes to
    344 		// different sections of the bootstrap script have to
    345 		// be merged, the banners give patch something
    346 		// to use to find its context.
    347 		b.Print("\n#\n# " + a.Package.ImportPath + "\n#\n\n")
    348 	}
    349 
    350 	if cfg.BuildV {
    351 		b.Print(a.Package.ImportPath + "\n")
    352 	}
    353 
    354 	if a.Package.BinaryOnly {
    355 		_, err := os.Stat(a.Package.Target)
    356 		if err == nil {
    357 			a.built = a.Package.Target
    358 			a.Target = a.Package.Target
    359 			a.buildID = b.fileHash(a.Package.Target)
    360 			a.Package.Stale = false
    361 			a.Package.StaleReason = "binary-only package"
    362 			return nil
    363 		}
    364 		if b.ComputeStaleOnly {
    365 			a.Package.Stale = true
    366 			a.Package.StaleReason = "missing or invalid binary-only package"
    367 			return nil
    368 		}
    369 		return fmt.Errorf("missing or invalid binary-only package")
    370 	}
    371 
    372 	if err := b.Mkdir(a.Objdir); err != nil {
    373 		return err
    374 	}
    375 	objdir := a.Objdir
    376 
    377 	// make target directory
    378 	dir, _ := filepath.Split(a.Target)
    379 	if dir != "" {
    380 		if err := b.Mkdir(dir); err != nil {
    381 			return err
    382 		}
    383 	}
    384 
    385 	var gofiles, cgofiles, cfiles, sfiles, cxxfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
    386 
    387 	gofiles = append(gofiles, a.Package.GoFiles...)
    388 	cgofiles = append(cgofiles, a.Package.CgoFiles...)
    389 	cfiles = append(cfiles, a.Package.CFiles...)
    390 	sfiles = append(sfiles, a.Package.SFiles...)
    391 	cxxfiles = append(cxxfiles, a.Package.CXXFiles...)
    392 
    393 	if a.Package.UsesCgo() || a.Package.UsesSwig() {
    394 		if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.Package); err != nil {
    395 			return
    396 		}
    397 	}
    398 
    399 	// Run SWIG on each .swig and .swigcxx file.
    400 	// Each run will generate two files, a .go file and a .c or .cxx file.
    401 	// The .go file will use import "C" and is to be processed by cgo.
    402 	if a.Package.UsesSwig() {
    403 		outGo, outC, outCXX, err := b.swig(a, a.Package, objdir, pcCFLAGS)
    404 		if err != nil {
    405 			return err
    406 		}
    407 		cgofiles = append(cgofiles, outGo...)
    408 		cfiles = append(cfiles, outC...)
    409 		cxxfiles = append(cxxfiles, outCXX...)
    410 	}
    411 
    412 	// If we're doing coverage, preprocess the .go files and put them in the work directory
    413 	if a.Package.Internal.CoverMode != "" {
    414 		for i, file := range str.StringList(gofiles, cgofiles) {
    415 			var sourceFile string
    416 			var coverFile string
    417 			var key string
    418 			if strings.HasSuffix(file, ".cgo1.go") {
    419 				// cgo files have absolute paths
    420 				base := filepath.Base(file)
    421 				sourceFile = file
    422 				coverFile = objdir + base
    423 				key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
    424 			} else {
    425 				sourceFile = filepath.Join(a.Package.Dir, file)
    426 				coverFile = objdir + file
    427 				key = file
    428 			}
    429 			coverFile = strings.TrimSuffix(coverFile, ".go") + ".cover.go"
    430 			cover := a.Package.Internal.CoverVars[key]
    431 			if cover == nil || base.IsTestFile(file) {
    432 				// Not covering this file.
    433 				continue
    434 			}
    435 			if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
    436 				return err
    437 			}
    438 			if i < len(gofiles) {
    439 				gofiles[i] = coverFile
    440 			} else {
    441 				cgofiles[i-len(gofiles)] = coverFile
    442 			}
    443 		}
    444 	}
    445 
    446 	// Run cgo.
    447 	if a.Package.UsesCgo() || a.Package.UsesSwig() {
    448 		// In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
    449 		// There is one exception: runtime/cgo's job is to bridge the
    450 		// cgo and non-cgo worlds, so it necessarily has files in both.
    451 		// In that case gcc only gets the gcc_* files.
    452 		var gccfiles []string
    453 		gccfiles = append(gccfiles, cfiles...)
    454 		cfiles = nil
    455 		if a.Package.Standard && a.Package.ImportPath == "runtime/cgo" {
    456 			filter := func(files, nongcc, gcc []string) ([]string, []string) {
    457 				for _, f := range files {
    458 					if strings.HasPrefix(f, "gcc_") {
    459 						gcc = append(gcc, f)
    460 					} else {
    461 						nongcc = append(nongcc, f)
    462 					}
    463 				}
    464 				return nongcc, gcc
    465 			}
    466 			sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
    467 		} else {
    468 			for _, sfile := range sfiles {
    469 				data, err := ioutil.ReadFile(filepath.Join(a.Package.Dir, sfile))
    470 				if err == nil {
    471 					if bytes.HasPrefix(data, []byte("TEXT")) || bytes.Contains(data, []byte("\nTEXT")) ||
    472 						bytes.HasPrefix(data, []byte("DATA")) || bytes.Contains(data, []byte("\nDATA")) ||
    473 						bytes.HasPrefix(data, []byte("GLOBL")) || bytes.Contains(data, []byte("\nGLOBL")) {
    474 						return fmt.Errorf("package using cgo has Go assembly file %s", sfile)
    475 					}
    476 				}
    477 			}
    478 			gccfiles = append(gccfiles, sfiles...)
    479 			sfiles = nil
    480 		}
    481 
    482 		outGo, outObj, err := b.cgo(a, base.Tool("cgo"), objdir, pcCFLAGS, pcLDFLAGS, mkAbsFiles(a.Package.Dir, cgofiles), gccfiles, cxxfiles, a.Package.MFiles, a.Package.FFiles)
    483 		if err != nil {
    484 			return err
    485 		}
    486 		if cfg.BuildToolchainName == "gccgo" {
    487 			cgoObjects = append(cgoObjects, a.Objdir+"_cgo_flags")
    488 		}
    489 		cgoObjects = append(cgoObjects, outObj...)
    490 		gofiles = append(gofiles, outGo...)
    491 	}
    492 	if cached && !a.needVet {
    493 		return nil
    494 	}
    495 
    496 	// Sanity check only, since Package.load already checked as well.
    497 	if len(gofiles) == 0 {
    498 		return &load.NoGoError{Package: a.Package}
    499 	}
    500 
    501 	// Prepare Go vet config if needed.
    502 	var vcfg *vetConfig
    503 	if a.needVet {
    504 		// Pass list of absolute paths to vet,
    505 		// so that vet's error messages will use absolute paths,
    506 		// so that we can reformat them relative to the directory
    507 		// in which the go command is invoked.
    508 		vcfg = &vetConfig{
    509 			Compiler:    cfg.BuildToolchainName,
    510 			Dir:         a.Package.Dir,
    511 			GoFiles:     mkAbsFiles(a.Package.Dir, gofiles),
    512 			ImportPath:  a.Package.ImportPath,
    513 			ImportMap:   make(map[string]string),
    514 			PackageFile: make(map[string]string),
    515 		}
    516 		a.vetCfg = vcfg
    517 		for i, raw := range a.Package.Internal.RawImports {
    518 			final := a.Package.Imports[i]
    519 			vcfg.ImportMap[raw] = final
    520 		}
    521 	}
    522 
    523 	// Prepare Go import config.
    524 	// We start it off with a comment so it can't be empty, so icfg.Bytes() below is never nil.
    525 	// It should never be empty anyway, but there have been bugs in the past that resulted
    526 	// in empty configs, which then unfortunately turn into "no config passed to compiler",
    527 	// and the compiler falls back to looking in pkg itself, which mostly works,
    528 	// except when it doesn't.
    529 	var icfg bytes.Buffer
    530 	fmt.Fprintf(&icfg, "# import config\n")
    531 
    532 	for i, raw := range a.Package.Internal.RawImports {
    533 		final := a.Package.Imports[i]
    534 		if final != raw {
    535 			fmt.Fprintf(&icfg, "importmap %s=%s\n", raw, final)
    536 		}
    537 	}
    538 
    539 	// Compute the list of mapped imports in the vet config
    540 	// so that we can add any missing mappings below.
    541 	var vcfgMapped map[string]bool
    542 	if vcfg != nil {
    543 		vcfgMapped = make(map[string]bool)
    544 		for _, p := range vcfg.ImportMap {
    545 			vcfgMapped[p] = true
    546 		}
    547 	}
    548 
    549 	for _, a1 := range a.Deps {
    550 		p1 := a1.Package
    551 		if p1 == nil || p1.ImportPath == "" || a1.built == "" {
    552 			continue
    553 		}
    554 		fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built)
    555 		if vcfg != nil {
    556 			// Add import mapping if needed
    557 			// (for imports like "runtime/cgo" that appear only in generated code).
    558 			if !vcfgMapped[p1.ImportPath] {
    559 				vcfg.ImportMap[p1.ImportPath] = p1.ImportPath
    560 			}
    561 			vcfg.PackageFile[p1.ImportPath] = a1.built
    562 		}
    563 	}
    564 
    565 	if cached {
    566 		// The cached package file is OK, so we don't need to run the compile.
    567 		// We've only going through the motions to prepare the vet configuration,
    568 		// which is now complete.
    569 		return nil
    570 	}
    571 
    572 	// Compile Go.
    573 	objpkg := objdir + "_pkg_.a"
    574 	ofile, out, err := BuildToolchain.gc(b, a, objpkg, icfg.Bytes(), len(sfiles) > 0, gofiles)
    575 	if len(out) > 0 {
    576 		b.showOutput(a, a.Package.Dir, a.Package.ImportPath, b.processOutput(out))
    577 		if err != nil {
    578 			return errPrintedOutput
    579 		}
    580 	}
    581 	if err != nil {
    582 		return err
    583 	}
    584 	if ofile != objpkg {
    585 		objects = append(objects, ofile)
    586 	}
    587 
    588 	// Copy .h files named for goos or goarch or goos_goarch
    589 	// to names using GOOS and GOARCH.
    590 	// For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
    591 	_goos_goarch := "_" + cfg.Goos + "_" + cfg.Goarch
    592 	_goos := "_" + cfg.Goos
    593 	_goarch := "_" + cfg.Goarch
    594 	for _, file := range a.Package.HFiles {
    595 		name, ext := fileExtSplit(file)
    596 		switch {
    597 		case strings.HasSuffix(name, _goos_goarch):
    598 			targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
    599 			if err := b.copyFile(a, objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
    600 				return err
    601 			}
    602 		case strings.HasSuffix(name, _goarch):
    603 			targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
    604 			if err := b.copyFile(a, objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
    605 				return err
    606 			}
    607 		case strings.HasSuffix(name, _goos):
    608 			targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
    609 			if err := b.copyFile(a, objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil {
    610 				return err
    611 			}
    612 		}
    613 	}
    614 
    615 	for _, file := range cfiles {
    616 		out := file[:len(file)-len(".c")] + ".o"
    617 		if err := BuildToolchain.cc(b, a, objdir+out, file); err != nil {
    618 			return err
    619 		}
    620 		objects = append(objects, out)
    621 	}
    622 
    623 	// Assemble .s files.
    624 	if len(sfiles) > 0 {
    625 		ofiles, err := BuildToolchain.asm(b, a, sfiles)
    626 		if err != nil {
    627 			return err
    628 		}
    629 		objects = append(objects, ofiles...)
    630 	}
    631 
    632 	// For gccgo on ELF systems, we write the build ID as an assembler file.
    633 	// This lets us set the the SHF_EXCLUDE flag.
    634 	// This is read by readGccgoArchive in cmd/internal/buildid/buildid.go.
    635 	if a.buildID != "" && cfg.BuildToolchainName == "gccgo" {
    636 		switch cfg.Goos {
    637 		case "android", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris":
    638 			asmfile, err := b.gccgoBuildIDELFFile(a)
    639 			if err != nil {
    640 				return err
    641 			}
    642 			ofiles, err := BuildToolchain.asm(b, a, []string{asmfile})
    643 			if err != nil {
    644 				return err
    645 			}
    646 			objects = append(objects, ofiles...)
    647 		}
    648 	}
    649 
    650 	// NOTE(rsc): On Windows, it is critically important that the
    651 	// gcc-compiled objects (cgoObjects) be listed after the ordinary
    652 	// objects in the archive. I do not know why this is.
    653 	// https://golang.org/issue/2601
    654 	objects = append(objects, cgoObjects...)
    655 
    656 	// Add system object files.
    657 	for _, syso := range a.Package.SysoFiles {
    658 		objects = append(objects, filepath.Join(a.Package.Dir, syso))
    659 	}
    660 
    661 	// Pack into archive in objdir directory.
    662 	// If the Go compiler wrote an archive, we only need to add the
    663 	// object files for non-Go sources to the archive.
    664 	// If the Go compiler wrote an archive and the package is entirely
    665 	// Go sources, there is no pack to execute at all.
    666 	if len(objects) > 0 {
    667 		if err := BuildToolchain.pack(b, a, objpkg, objects); err != nil {
    668 			return err
    669 		}
    670 	}
    671 
    672 	if err := b.updateBuildID(a, objpkg, true); err != nil {
    673 		return err
    674 	}
    675 
    676 	a.built = objpkg
    677 	return nil
    678 }
    679 
    680 type vetConfig struct {
    681 	Compiler    string
    682 	Dir         string
    683 	GoFiles     []string
    684 	ImportMap   map[string]string
    685 	PackageFile map[string]string
    686 	ImportPath  string
    687 
    688 	SucceedOnTypecheckFailure bool
    689 }
    690 
    691 // VetTool is the path to an alternate vet tool binary.
    692 // The caller is expected to set it (if needed) before executing any vet actions.
    693 var VetTool string
    694 
    695 // VetFlags are the flags to pass to vet.
    696 // The caller is expected to set them before executing any vet actions.
    697 var VetFlags []string
    698 
    699 func (b *Builder) vet(a *Action) error {
    700 	// a.Deps[0] is the build of the package being vetted.
    701 	// a.Deps[1] is the build of the "fmt" package.
    702 
    703 	vcfg := a.Deps[0].vetCfg
    704 	if vcfg == nil {
    705 		// Vet config should only be missing if the build failed.
    706 		if !a.Deps[0].Failed {
    707 			return fmt.Errorf("vet config not found")
    708 		}
    709 		return nil
    710 	}
    711 
    712 	if vcfg.ImportMap["fmt"] == "" {
    713 		a1 := a.Deps[1]
    714 		vcfg.ImportMap["fmt"] = "fmt"
    715 		vcfg.PackageFile["fmt"] = a1.built
    716 	}
    717 
    718 	// During go test, ignore type-checking failures during vet.
    719 	// We only run vet if the compilation has succeeded,
    720 	// so at least for now assume the bug is in vet.
    721 	// We know of at least #18395.
    722 	// TODO(rsc,gri): Try to remove this for Go 1.11.
    723 	vcfg.SucceedOnTypecheckFailure = cfg.CmdName == "test"
    724 
    725 	js, err := json.MarshalIndent(vcfg, "", "\t")
    726 	if err != nil {
    727 		return fmt.Errorf("internal error marshaling vet config: %v", err)
    728 	}
    729 	js = append(js, '\n')
    730 	if err := b.writeFile(a.Objdir+"vet.cfg", js); err != nil {
    731 		return err
    732 	}
    733 
    734 	var env []string
    735 	if cfg.BuildToolchainName == "gccgo" {
    736 		env = append(env, "GCCGO="+BuildToolchain.compiler())
    737 	}
    738 
    739 	p := a.Package
    740 	tool := VetTool
    741 	if tool == "" {
    742 		tool = base.Tool("vet")
    743 	}
    744 	return b.run(a, p.Dir, p.ImportPath, env, cfg.BuildToolexec, tool, VetFlags, a.Objdir+"vet.cfg")
    745 }
    746 
    747 // linkActionID computes the action ID for a link action.
    748 func (b *Builder) linkActionID(a *Action) cache.ActionID {
    749 	p := a.Package
    750 	h := cache.NewHash("link " + p.ImportPath)
    751 
    752 	// Toolchain-independent configuration.
    753 	fmt.Fprintf(h, "link\n")
    754 	fmt.Fprintf(h, "buildmode %s goos %s goarch %s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch)
    755 	fmt.Fprintf(h, "import %q\n", p.ImportPath)
    756 	fmt.Fprintf(h, "omitdebug %v standard %v local %v prefix %q\n", p.Internal.OmitDebug, p.Standard, p.Internal.Local, p.Internal.LocalPrefix)
    757 
    758 	// Toolchain-dependent configuration, shared with b.linkSharedActionID.
    759 	b.printLinkerConfig(h, p)
    760 
    761 	// Input files.
    762 	for _, a1 := range a.Deps {
    763 		p1 := a1.Package
    764 		if p1 != nil {
    765 			if a1.built != "" || a1.buildID != "" {
    766 				buildID := a1.buildID
    767 				if buildID == "" {
    768 					buildID = b.buildID(a1.built)
    769 				}
    770 				fmt.Fprintf(h, "packagefile %s=%s\n", p1.ImportPath, contentID(buildID))
    771 			}
    772 			// Because we put package main's full action ID into the binary's build ID,
    773 			// we must also put the full action ID into the binary's action ID hash.
    774 			if p1.Name == "main" {
    775 				fmt.Fprintf(h, "packagemain %s\n", a1.buildID)
    776 			}
    777 			if p1.Shlib != "" {
    778 				fmt.Fprintf(h, "packageshlib %s=%s\n", p1.ImportPath, contentID(b.buildID(p1.Shlib)))
    779 			}
    780 		}
    781 	}
    782 
    783 	return h.Sum()
    784 }
    785 
    786 // printLinkerConfig prints the linker config into the hash h,
    787 // as part of the computation of a linker-related action ID.
    788 func (b *Builder) printLinkerConfig(h io.Writer, p *load.Package) {
    789 	switch cfg.BuildToolchainName {
    790 	default:
    791 		base.Fatalf("linkActionID: unknown toolchain %q", cfg.BuildToolchainName)
    792 
    793 	case "gc":
    794 		fmt.Fprintf(h, "link %s %q %s\n", b.toolID("link"), forcedLdflags, ldBuildmode)
    795 		if p != nil {
    796 			fmt.Fprintf(h, "linkflags %q\n", p.Internal.Ldflags)
    797 		}
    798 		fmt.Fprintf(h, "GO$GOARCH=%s\n", os.Getenv("GO"+strings.ToUpper(cfg.BuildContext.GOARCH))) // GO386, GOARM, etc
    799 
    800 		// The linker writes source file paths that say GOROOT_FINAL.
    801 		fmt.Fprintf(h, "GOROOT=%s\n", cfg.GOROOT_FINAL)
    802 
    803 		// TODO(rsc): Convince linker team not to add more magic environment variables,
    804 		// or perhaps restrict the environment variables passed to subprocesses.
    805 		magic := []string{
    806 			"GO_EXTLINK_ENABLED",
    807 		}
    808 		for _, env := range magic {
    809 			if x := os.Getenv(env); x != "" {
    810 				fmt.Fprintf(h, "magic %s=%s\n", env, x)
    811 			}
    812 		}
    813 
    814 		// TODO(rsc): Do cgo settings and flags need to be included?
    815 		// Or external linker settings and flags?
    816 
    817 	case "gccgo":
    818 		id, err := b.gccgoToolID(BuildToolchain.linker(), "go")
    819 		if err != nil {
    820 			base.Fatalf("%v", err)
    821 		}
    822 		fmt.Fprintf(h, "link %s %s\n", id, ldBuildmode)
    823 		// TODO(iant): Should probably include cgo flags here.
    824 	}
    825 }
    826 
    827 // link is the action for linking a single command.
    828 // Note that any new influence on this logic must be reported in b.linkActionID above as well.
    829 func (b *Builder) link(a *Action) (err error) {
    830 	if b.useCache(a, a.Package, b.linkActionID(a), a.Package.Target) {
    831 		return nil
    832 	}
    833 	defer b.flushOutput(a)
    834 
    835 	if err := b.Mkdir(a.Objdir); err != nil {
    836 		return err
    837 	}
    838 
    839 	importcfg := a.Objdir + "importcfg.link"
    840 	if err := b.writeLinkImportcfg(a, importcfg); err != nil {
    841 		return err
    842 	}
    843 
    844 	// make target directory
    845 	dir, _ := filepath.Split(a.Target)
    846 	if dir != "" {
    847 		if err := b.Mkdir(dir); err != nil {
    848 			return err
    849 		}
    850 	}
    851 
    852 	if err := BuildToolchain.ld(b, a, a.Target, importcfg, a.Deps[0].built); err != nil {
    853 		return err
    854 	}
    855 
    856 	// Update the binary with the final build ID.
    857 	// But if OmitDebug is set, don't rewrite the binary, because we set OmitDebug
    858 	// on binaries that we are going to run and then delete.
    859 	// There's no point in doing work on such a binary.
    860 	// Worse, opening the binary for write here makes it
    861 	// essentially impossible to safely fork+exec due to a fundamental
    862 	// incompatibility between ETXTBSY and threads on modern Unix systems.
    863 	// See golang.org/issue/22220.
    864 	// We still call updateBuildID to update a.buildID, which is important
    865 	// for test result caching, but passing rewrite=false (final arg)
    866 	// means we don't actually rewrite the binary, nor store the
    867 	// result into the cache.
    868 	// Not calling updateBuildID means we also don't insert these
    869 	// binaries into the build object cache. That's probably a net win:
    870 	// less cache space wasted on large binaries we are not likely to
    871 	// need again. (On the other hand it does make repeated go test slower.)
    872 	if err := b.updateBuildID(a, a.Target, !a.Package.Internal.OmitDebug); err != nil {
    873 		return err
    874 	}
    875 
    876 	a.built = a.Target
    877 	return nil
    878 }
    879 
    880 func (b *Builder) writeLinkImportcfg(a *Action, file string) error {
    881 	// Prepare Go import cfg.
    882 	var icfg bytes.Buffer
    883 	for _, a1 := range a.Deps {
    884 		p1 := a1.Package
    885 		if p1 == nil {
    886 			continue
    887 		}
    888 		fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built)
    889 		if p1.Shlib != "" {
    890 			fmt.Fprintf(&icfg, "packageshlib %s=%s\n", p1.ImportPath, p1.Shlib)
    891 		}
    892 	}
    893 	return b.writeFile(file, icfg.Bytes())
    894 }
    895 
    896 // PkgconfigCmd returns a pkg-config binary name
    897 // defaultPkgConfig is defined in zdefaultcc.go, written by cmd/dist.
    898 func (b *Builder) PkgconfigCmd() string {
    899 	return envList("PKG_CONFIG", cfg.DefaultPkgConfig)[0]
    900 }
    901 
    902 // splitPkgConfigOutput parses the pkg-config output into a slice of
    903 // flags. pkg-config always uses \ to escape special characters.
    904 func splitPkgConfigOutput(out []byte) []string {
    905 	if len(out) == 0 {
    906 		return nil
    907 	}
    908 	var flags []string
    909 	flag := make([]byte, len(out))
    910 	r, w := 0, 0
    911 	for r < len(out) {
    912 		switch out[r] {
    913 		case ' ', '\t', '\r', '\n':
    914 			if w > 0 {
    915 				flags = append(flags, string(flag[:w]))
    916 			}
    917 			w = 0
    918 		case '\\':
    919 			r++
    920 			fallthrough
    921 		default:
    922 			if r < len(out) {
    923 				flag[w] = out[r]
    924 				w++
    925 			}
    926 		}
    927 		r++
    928 	}
    929 	if w > 0 {
    930 		flags = append(flags, string(flag[:w]))
    931 	}
    932 	return flags
    933 }
    934 
    935 // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
    936 func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, err error) {
    937 	if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
    938 		var pcflags []string
    939 		for len(pkgs) > 0 && strings.HasPrefix(pkgs[0], "--") {
    940 			pcflags = append(pcflags, pkgs[0])
    941 			pkgs = pkgs[1:]
    942 		}
    943 		for _, pkg := range pkgs {
    944 			if !load.SafeArg(pkg) {
    945 				return nil, nil, fmt.Errorf("invalid pkg-config package name: %s", pkg)
    946 			}
    947 		}
    948 		var out []byte
    949 		out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--cflags", pcflags, "--", pkgs)
    950 		if err != nil {
    951 			b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --cflags "+strings.Join(pcflags, " ")+strings.Join(pkgs, " "), string(out))
    952 			b.Print(err.Error() + "\n")
    953 			return nil, nil, errPrintedOutput
    954 		}
    955 		if len(out) > 0 {
    956 			cflags = splitPkgConfigOutput(out)
    957 			if err := checkCompilerFlags("CFLAGS", "pkg-config --cflags", cflags); err != nil {
    958 				return nil, nil, err
    959 			}
    960 		}
    961 		out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--libs", pcflags, "--", pkgs)
    962 		if err != nil {
    963 			b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pcflags, " ")+strings.Join(pkgs, " "), string(out))
    964 			b.Print(err.Error() + "\n")
    965 			return nil, nil, errPrintedOutput
    966 		}
    967 		if len(out) > 0 {
    968 			ldflags = strings.Fields(string(out))
    969 			if err := checkLinkerFlags("LDFLAGS", "pkg-config --libs", ldflags); err != nil {
    970 				return nil, nil, err
    971 			}
    972 		}
    973 	}
    974 
    975 	return
    976 }
    977 
    978 func (b *Builder) installShlibname(a *Action) error {
    979 	// TODO: BuildN
    980 	a1 := a.Deps[0]
    981 	err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666)
    982 	if err != nil {
    983 		return err
    984 	}
    985 	if cfg.BuildX {
    986 		b.Showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.Target), a.Target)
    987 	}
    988 	return nil
    989 }
    990 
    991 func (b *Builder) linkSharedActionID(a *Action) cache.ActionID {
    992 	h := cache.NewHash("linkShared")
    993 
    994 	// Toolchain-independent configuration.
    995 	fmt.Fprintf(h, "linkShared\n")
    996 	fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch)
    997 
    998 	// Toolchain-dependent configuration, shared with b.linkActionID.
    999 	b.printLinkerConfig(h, nil)
   1000 
   1001 	// Input files.
   1002 	for _, a1 := range a.Deps {
   1003 		p1 := a1.Package
   1004 		if a1.built == "" {
   1005 			continue
   1006 		}
   1007 		if p1 != nil {
   1008 			fmt.Fprintf(h, "packagefile %s=%s\n", p1.ImportPath, contentID(b.buildID(a1.built)))
   1009 			if p1.Shlib != "" {
   1010 				fmt.Fprintf(h, "packageshlib %s=%s\n", p1.ImportPath, contentID(b.buildID(p1.Shlib)))
   1011 			}
   1012 		}
   1013 	}
   1014 	// Files named on command line are special.
   1015 	for _, a1 := range a.Deps[0].Deps {
   1016 		p1 := a1.Package
   1017 		fmt.Fprintf(h, "top %s=%s\n", p1.ImportPath, contentID(b.buildID(a1.built)))
   1018 	}
   1019 
   1020 	return h.Sum()
   1021 }
   1022 
   1023 func (b *Builder) linkShared(a *Action) (err error) {
   1024 	if b.useCache(a, nil, b.linkSharedActionID(a), a.Target) {
   1025 		return nil
   1026 	}
   1027 	defer b.flushOutput(a)
   1028 
   1029 	if err := b.Mkdir(a.Objdir); err != nil {
   1030 		return err
   1031 	}
   1032 
   1033 	importcfg := a.Objdir + "importcfg.link"
   1034 	if err := b.writeLinkImportcfg(a, importcfg); err != nil {
   1035 		return err
   1036 	}
   1037 
   1038 	// TODO(rsc): There is a missing updateBuildID here,
   1039 	// but we have to decide where to store the build ID in these files.
   1040 	a.built = a.Target
   1041 	return BuildToolchain.ldShared(b, a, a.Deps[0].Deps, a.Target, importcfg, a.Deps)
   1042 }
   1043 
   1044 // BuildInstallFunc is the action for installing a single package or executable.
   1045 func BuildInstallFunc(b *Builder, a *Action) (err error) {
   1046 	defer func() {
   1047 		if err != nil && err != errPrintedOutput {
   1048 			// a.Package == nil is possible for the go install -buildmode=shared
   1049 			// action that installs libmangledname.so, which corresponds to
   1050 			// a list of packages, not just one.
   1051 			sep, path := "", ""
   1052 			if a.Package != nil {
   1053 				sep, path = " ", a.Package.ImportPath
   1054 			}
   1055 			err = fmt.Errorf("go %s%s%s: %v", cfg.CmdName, sep, path, err)
   1056 		}
   1057 	}()
   1058 
   1059 	a1 := a.Deps[0]
   1060 	a.buildID = a1.buildID
   1061 
   1062 	// If we are using the eventual install target as an up-to-date
   1063 	// cached copy of the thing we built, then there's no need to
   1064 	// copy it into itself (and that would probably fail anyway).
   1065 	// In this case a1.built == a.Target because a1.built == p.Target,
   1066 	// so the built target is not in the a1.Objdir tree that b.cleanup(a1) removes.
   1067 	if a1.built == a.Target {
   1068 		a.built = a.Target
   1069 		b.cleanup(a1)
   1070 		// Whether we're smart enough to avoid a complete rebuild
   1071 		// depends on exactly what the staleness and rebuild algorithms
   1072 		// are, as well as potentially the state of the Go build cache.
   1073 		// We don't really want users to be able to infer (or worse start depending on)
   1074 		// those details from whether the modification time changes during
   1075 		// "go install", so do a best-effort update of the file times to make it
   1076 		// look like we rewrote a.Target even if we did not. Updating the mtime
   1077 		// may also help other mtime-based systems that depend on our
   1078 		// previous mtime updates that happened more often.
   1079 		// This is still not perfect - we ignore the error result, and if the file was
   1080 		// unwritable for some reason then pretending to have written it is also
   1081 		// confusing - but it's probably better than not doing the mtime update.
   1082 		//
   1083 		// But don't do that for the special case where building an executable
   1084 		// with -linkshared implicitly installs all its dependent libraries.
   1085 		// We want to hide that awful detail as much as possible, so don't
   1086 		// advertise it by touching the mtimes (usually the libraries are up
   1087 		// to date).
   1088 		if !a.buggyInstall {
   1089 			now := time.Now()
   1090 			os.Chtimes(a.Target, now, now)
   1091 		}
   1092 		return nil
   1093 	}
   1094 	if b.ComputeStaleOnly {
   1095 		return nil
   1096 	}
   1097 
   1098 	if err := b.Mkdir(a.Objdir); err != nil {
   1099 		return err
   1100 	}
   1101 
   1102 	perm := os.FileMode(0666)
   1103 	if a1.Mode == "link" {
   1104 		switch cfg.BuildBuildmode {
   1105 		case "c-archive", "c-shared", "plugin":
   1106 		default:
   1107 			perm = 0777
   1108 		}
   1109 	}
   1110 
   1111 	// make target directory
   1112 	dir, _ := filepath.Split(a.Target)
   1113 	if dir != "" {
   1114 		if err := b.Mkdir(dir); err != nil {
   1115 			return err
   1116 		}
   1117 	}
   1118 
   1119 	defer b.cleanup(a1)
   1120 
   1121 	return b.moveOrCopyFile(a, a.Target, a1.built, perm, false)
   1122 }
   1123 
   1124 // cleanup removes a's object dir to keep the amount of
   1125 // on-disk garbage down in a large build. On an operating system
   1126 // with aggressive buffering, cleaning incrementally like
   1127 // this keeps the intermediate objects from hitting the disk.
   1128 func (b *Builder) cleanup(a *Action) {
   1129 	if !cfg.BuildWork {
   1130 		if cfg.BuildX {
   1131 			b.Showcmd("", "rm -r %s", a.Objdir)
   1132 		}
   1133 		os.RemoveAll(a.Objdir)
   1134 	}
   1135 }
   1136 
   1137 // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
   1138 func (b *Builder) moveOrCopyFile(a *Action, dst, src string, perm os.FileMode, force bool) error {
   1139 	if cfg.BuildN {
   1140 		b.Showcmd("", "mv %s %s", src, dst)
   1141 		return nil
   1142 	}
   1143 
   1144 	// If we can update the mode and rename to the dst, do it.
   1145 	// Otherwise fall back to standard copy.
   1146 
   1147 	// If the source is in the build cache, we need to copy it.
   1148 	if strings.HasPrefix(src, cache.DefaultDir()) {
   1149 		return b.copyFile(a, dst, src, perm, force)
   1150 	}
   1151 
   1152 	// On Windows, always copy the file, so that we respect the NTFS
   1153 	// permissions of the parent folder. https://golang.org/issue/22343.
   1154 	// What matters here is not cfg.Goos (the system we are building
   1155 	// for) but runtime.GOOS (the system we are building on).
   1156 	if runtime.GOOS == "windows" {
   1157 		return b.copyFile(a, dst, src, perm, force)
   1158 	}
   1159 
   1160 	// If the destination directory has the group sticky bit set,
   1161 	// we have to copy the file to retain the correct permissions.
   1162 	// https://golang.org/issue/18878
   1163 	if fi, err := os.Stat(filepath.Dir(dst)); err == nil {
   1164 		if fi.IsDir() && (fi.Mode()&os.ModeSetgid) != 0 {
   1165 			return b.copyFile(a, dst, src, perm, force)
   1166 		}
   1167 	}
   1168 
   1169 	// The perm argument is meant to be adjusted according to umask,
   1170 	// but we don't know what the umask is.
   1171 	// Create a dummy file to find out.
   1172 	// This avoids build tags and works even on systems like Plan 9
   1173 	// where the file mask computation incorporates other information.
   1174 	mode := perm
   1175 	f, err := os.OpenFile(filepath.Clean(dst)+"-go-tmp-umask", os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm)
   1176 	if err == nil {
   1177 		fi, err := f.Stat()
   1178 		if err == nil {
   1179 			mode = fi.Mode() & 0777
   1180 		}
   1181 		name := f.Name()
   1182 		f.Close()
   1183 		os.Remove(name)
   1184 	}
   1185 
   1186 	if err := os.Chmod(src, mode); err == nil {
   1187 		if err := os.Rename(src, dst); err == nil {
   1188 			if cfg.BuildX {
   1189 				b.Showcmd("", "mv %s %s", src, dst)
   1190 			}
   1191 			return nil
   1192 		}
   1193 	}
   1194 
   1195 	return b.copyFile(a, dst, src, perm, force)
   1196 }
   1197 
   1198 // copyFile is like 'cp src dst'.
   1199 func (b *Builder) copyFile(a *Action, dst, src string, perm os.FileMode, force bool) error {
   1200 	if cfg.BuildN || cfg.BuildX {
   1201 		b.Showcmd("", "cp %s %s", src, dst)
   1202 		if cfg.BuildN {
   1203 			return nil
   1204 		}
   1205 	}
   1206 
   1207 	sf, err := os.Open(src)
   1208 	if err != nil {
   1209 		return err
   1210 	}
   1211 	defer sf.Close()
   1212 
   1213 	// Be careful about removing/overwriting dst.
   1214 	// Do not remove/overwrite if dst exists and is a directory
   1215 	// or a non-object file.
   1216 	if fi, err := os.Stat(dst); err == nil {
   1217 		if fi.IsDir() {
   1218 			return fmt.Errorf("build output %q already exists and is a directory", dst)
   1219 		}
   1220 		if !force && fi.Mode().IsRegular() && !isObject(dst) {
   1221 			return fmt.Errorf("build output %q already exists and is not an object file", dst)
   1222 		}
   1223 	}
   1224 
   1225 	// On Windows, remove lingering ~ file from last attempt.
   1226 	if base.ToolIsWindows {
   1227 		if _, err := os.Stat(dst + "~"); err == nil {
   1228 			os.Remove(dst + "~")
   1229 		}
   1230 	}
   1231 
   1232 	mayberemovefile(dst)
   1233 	df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
   1234 	if err != nil && base.ToolIsWindows {
   1235 		// Windows does not allow deletion of a binary file
   1236 		// while it is executing. Try to move it out of the way.
   1237 		// If the move fails, which is likely, we'll try again the
   1238 		// next time we do an install of this binary.
   1239 		if err := os.Rename(dst, dst+"~"); err == nil {
   1240 			os.Remove(dst + "~")
   1241 		}
   1242 		df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
   1243 	}
   1244 	if err != nil {
   1245 		return err
   1246 	}
   1247 
   1248 	_, err = io.Copy(df, sf)
   1249 	df.Close()
   1250 	if err != nil {
   1251 		mayberemovefile(dst)
   1252 		return fmt.Errorf("copying %s to %s: %v", src, dst, err)
   1253 	}
   1254 	return nil
   1255 }
   1256 
   1257 // writeFile writes the text to file.
   1258 func (b *Builder) writeFile(file string, text []byte) error {
   1259 	if cfg.BuildN || cfg.BuildX {
   1260 		b.Showcmd("", "cat >%s << 'EOF' # internal\n%sEOF", file, text)
   1261 	}
   1262 	if cfg.BuildN {
   1263 		return nil
   1264 	}
   1265 	return ioutil.WriteFile(file, text, 0666)
   1266 }
   1267 
   1268 // Install the cgo export header file, if there is one.
   1269 func (b *Builder) installHeader(a *Action) error {
   1270 	src := a.Objdir + "_cgo_install.h"
   1271 	if _, err := os.Stat(src); os.IsNotExist(err) {
   1272 		// If the file does not exist, there are no exported
   1273 		// functions, and we do not install anything.
   1274 		// TODO(rsc): Once we know that caching is rebuilding
   1275 		// at the right times (not missing rebuilds), here we should
   1276 		// probably delete the installed header, if any.
   1277 		if cfg.BuildX {
   1278 			b.Showcmd("", "# %s not created", src)
   1279 		}
   1280 		return nil
   1281 	}
   1282 
   1283 	dir, _ := filepath.Split(a.Target)
   1284 	if dir != "" {
   1285 		if err := b.Mkdir(dir); err != nil {
   1286 			return err
   1287 		}
   1288 	}
   1289 
   1290 	return b.moveOrCopyFile(a, a.Target, src, 0666, true)
   1291 }
   1292 
   1293 // cover runs, in effect,
   1294 //	go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
   1295 func (b *Builder) cover(a *Action, dst, src string, perm os.FileMode, varName string) error {
   1296 	return b.run(a, a.Objdir, "cover "+a.Package.ImportPath, nil,
   1297 		cfg.BuildToolexec,
   1298 		base.Tool("cover"),
   1299 		"-mode", a.Package.Internal.CoverMode,
   1300 		"-var", varName,
   1301 		"-o", dst,
   1302 		src)
   1303 }
   1304 
   1305 var objectMagic = [][]byte{
   1306 	{'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive
   1307 	{'\x7F', 'E', 'L', 'F'},                   // ELF
   1308 	{0xFE, 0xED, 0xFA, 0xCE},                  // Mach-O big-endian 32-bit
   1309 	{0xFE, 0xED, 0xFA, 0xCF},                  // Mach-O big-endian 64-bit
   1310 	{0xCE, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 32-bit
   1311 	{0xCF, 0xFA, 0xED, 0xFE},                  // Mach-O little-endian 64-bit
   1312 	{0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00},      // PE (Windows) as generated by 6l/8l and gcc
   1313 	{0x00, 0x00, 0x01, 0xEB},                  // Plan 9 i386
   1314 	{0x00, 0x00, 0x8a, 0x97},                  // Plan 9 amd64
   1315 	{0x00, 0x00, 0x06, 0x47},                  // Plan 9 arm
   1316 }
   1317 
   1318 func isObject(s string) bool {
   1319 	f, err := os.Open(s)
   1320 	if err != nil {
   1321 		return false
   1322 	}
   1323 	defer f.Close()
   1324 	buf := make([]byte, 64)
   1325 	io.ReadFull(f, buf)
   1326 	for _, magic := range objectMagic {
   1327 		if bytes.HasPrefix(buf, magic) {
   1328 			return true
   1329 		}
   1330 	}
   1331 	return false
   1332 }
   1333 
   1334 // mayberemovefile removes a file only if it is a regular file
   1335 // When running as a user with sufficient privileges, we may delete
   1336 // even device files, for example, which is not intended.
   1337 func mayberemovefile(s string) {
   1338 	if fi, err := os.Lstat(s); err == nil && !fi.Mode().IsRegular() {
   1339 		return
   1340 	}
   1341 	os.Remove(s)
   1342 }
   1343 
   1344 // fmtcmd formats a command in the manner of fmt.Sprintf but also:
   1345 //
   1346 //	If dir is non-empty and the script is not in dir right now,
   1347 //	fmtcmd inserts "cd dir\n" before the command.
   1348 //
   1349 //	fmtcmd replaces the value of b.WorkDir with $WORK.
   1350 //	fmtcmd replaces the value of goroot with $GOROOT.
   1351 //	fmtcmd replaces the value of b.gobin with $GOBIN.
   1352 //
   1353 //	fmtcmd replaces the name of the current directory with dot (.)
   1354 //	but only when it is at the beginning of a space-separated token.
   1355 //
   1356 func (b *Builder) fmtcmd(dir string, format string, args ...interface{}) string {
   1357 	cmd := fmt.Sprintf(format, args...)
   1358 	if dir != "" && dir != "/" {
   1359 		cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
   1360 		if b.scriptDir != dir {
   1361 			b.scriptDir = dir
   1362 			cmd = "cd " + dir + "\n" + cmd
   1363 		}
   1364 	}
   1365 	if b.WorkDir != "" {
   1366 		cmd = strings.Replace(cmd, b.WorkDir, "$WORK", -1)
   1367 	}
   1368 	return cmd
   1369 }
   1370 
   1371 // showcmd prints the given command to standard output
   1372 // for the implementation of -n or -x.
   1373 func (b *Builder) Showcmd(dir string, format string, args ...interface{}) {
   1374 	b.output.Lock()
   1375 	defer b.output.Unlock()
   1376 	b.Print(b.fmtcmd(dir, format, args...) + "\n")
   1377 }
   1378 
   1379 // showOutput prints "# desc" followed by the given output.
   1380 // The output is expected to contain references to 'dir', usually
   1381 // the source directory for the package that has failed to build.
   1382 // showOutput rewrites mentions of dir with a relative path to dir
   1383 // when the relative path is shorter. This is usually more pleasant.
   1384 // For example, if fmt doesn't compile and we are in src/html,
   1385 // the output is
   1386 //
   1387 //	$ go build
   1388 //	# fmt
   1389 //	../fmt/print.go:1090: undefined: asdf
   1390 //	$
   1391 //
   1392 // instead of
   1393 //
   1394 //	$ go build
   1395 //	# fmt
   1396 //	/usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
   1397 //	$
   1398 //
   1399 // showOutput also replaces references to the work directory with $WORK.
   1400 //
   1401 // If a is not nil and a.output is not nil, showOutput appends to that slice instead of
   1402 // printing to b.Print.
   1403 //
   1404 func (b *Builder) showOutput(a *Action, dir, desc, out string) {
   1405 	prefix := "# " + desc
   1406 	suffix := "\n" + out
   1407 	if reldir := base.ShortPath(dir); reldir != dir {
   1408 		suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
   1409 		suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
   1410 	}
   1411 	suffix = strings.Replace(suffix, " "+b.WorkDir, " $WORK", -1)
   1412 
   1413 	if a != nil && a.output != nil {
   1414 		a.output = append(a.output, prefix...)
   1415 		a.output = append(a.output, suffix...)
   1416 		return
   1417 	}
   1418 
   1419 	b.output.Lock()
   1420 	defer b.output.Unlock()
   1421 	b.Print(prefix, suffix)
   1422 }
   1423 
   1424 // errPrintedOutput is a special error indicating that a command failed
   1425 // but that it generated output as well, and that output has already
   1426 // been printed, so there's no point showing 'exit status 1' or whatever
   1427 // the wait status was. The main executor, builder.do, knows not to
   1428 // print this error.
   1429 var errPrintedOutput = errors.New("already printed output - no need to show error")
   1430 
   1431 var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.(cgo1|cover)\.go:[0-9]+(:[0-9]+)?\]`)
   1432 var cgoTypeSigRe = regexp.MustCompile(`\b_C2?(type|func|var|macro)_\B`)
   1433 
   1434 // run runs the command given by cmdline in the directory dir.
   1435 // If the command fails, run prints information about the failure
   1436 // and returns a non-nil error.
   1437 func (b *Builder) run(a *Action, dir string, desc string, env []string, cmdargs ...interface{}) error {
   1438 	out, err := b.runOut(dir, desc, env, cmdargs...)
   1439 	if len(out) > 0 {
   1440 		if desc == "" {
   1441 			desc = b.fmtcmd(dir, "%s", strings.Join(str.StringList(cmdargs...), " "))
   1442 		}
   1443 		b.showOutput(a, dir, desc, b.processOutput(out))
   1444 		if err != nil {
   1445 			err = errPrintedOutput
   1446 		}
   1447 	}
   1448 	return err
   1449 }
   1450 
   1451 // processOutput prepares the output of runOut to be output to the console.
   1452 func (b *Builder) processOutput(out []byte) string {
   1453 	if out[len(out)-1] != '\n' {
   1454 		out = append(out, '\n')
   1455 	}
   1456 	messages := string(out)
   1457 	// Fix up output referring to cgo-generated code to be more readable.
   1458 	// Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
   1459 	// Replace *[100]_Ctype_foo with *[100]C.foo.
   1460 	// If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
   1461 	if !cfg.BuildX && cgoLine.MatchString(messages) {
   1462 		messages = cgoLine.ReplaceAllString(messages, "")
   1463 		messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
   1464 	}
   1465 	return messages
   1466 }
   1467 
   1468 // runOut runs the command given by cmdline in the directory dir.
   1469 // It returns the command output and any errors that occurred.
   1470 func (b *Builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
   1471 	cmdline := str.StringList(cmdargs...)
   1472 
   1473 	for _, arg := range cmdline {
   1474 		// GNU binutils commands, including gcc and gccgo, interpret an argument
   1475 		// @foo anywhere in the command line (even following --) as meaning
   1476 		// "read and insert arguments from the file named foo."
   1477 		// Don't say anything that might be misinterpreted that way.
   1478 		if strings.HasPrefix(arg, "@") {
   1479 			return nil, fmt.Errorf("invalid command-line argument %s in command: %s", arg, joinUnambiguously(cmdline))
   1480 		}
   1481 	}
   1482 
   1483 	if cfg.BuildN || cfg.BuildX {
   1484 		var envcmdline string
   1485 		for _, e := range env {
   1486 			if j := strings.IndexByte(e, '='); j != -1 {
   1487 				if strings.ContainsRune(e[j+1:], '\'') {
   1488 					envcmdline += fmt.Sprintf("%s=%q", e[:j], e[j+1:])
   1489 				} else {
   1490 					envcmdline += fmt.Sprintf("%s='%s'", e[:j], e[j+1:])
   1491 				}
   1492 				envcmdline += " "
   1493 			}
   1494 		}
   1495 		envcmdline += joinUnambiguously(cmdline)
   1496 		b.Showcmd(dir, "%s", envcmdline)
   1497 		if cfg.BuildN {
   1498 			return nil, nil
   1499 		}
   1500 	}
   1501 
   1502 	var buf bytes.Buffer
   1503 	cmd := exec.Command(cmdline[0], cmdline[1:]...)
   1504 	cmd.Stdout = &buf
   1505 	cmd.Stderr = &buf
   1506 	cmd.Dir = dir
   1507 	cmd.Env = base.MergeEnvLists(env, base.EnvForDir(cmd.Dir, os.Environ()))
   1508 	err := cmd.Run()
   1509 
   1510 	// err can be something like 'exit status 1'.
   1511 	// Add information about what program was running.
   1512 	// Note that if buf.Bytes() is non-empty, the caller usually
   1513 	// shows buf.Bytes() and does not print err at all, so the
   1514 	// prefix here does not make most output any more verbose.
   1515 	if err != nil {
   1516 		err = errors.New(cmdline[0] + ": " + err.Error())
   1517 	}
   1518 	return buf.Bytes(), err
   1519 }
   1520 
   1521 // joinUnambiguously prints the slice, quoting where necessary to make the
   1522 // output unambiguous.
   1523 // TODO: See issue 5279. The printing of commands needs a complete redo.
   1524 func joinUnambiguously(a []string) string {
   1525 	var buf bytes.Buffer
   1526 	for i, s := range a {
   1527 		if i > 0 {
   1528 			buf.WriteByte(' ')
   1529 		}
   1530 		q := strconv.Quote(s)
   1531 		if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
   1532 			buf.WriteString(q)
   1533 		} else {
   1534 			buf.WriteString(s)
   1535 		}
   1536 	}
   1537 	return buf.String()
   1538 }
   1539 
   1540 // mkdir makes the named directory.
   1541 func (b *Builder) Mkdir(dir string) error {
   1542 	// Make Mkdir(a.Objdir) a no-op instead of an error when a.Objdir == "".
   1543 	if dir == "" {
   1544 		return nil
   1545 	}
   1546 
   1547 	b.exec.Lock()
   1548 	defer b.exec.Unlock()
   1549 	// We can be a little aggressive about being
   1550 	// sure directories exist. Skip repeated calls.
   1551 	if b.mkdirCache[dir] {
   1552 		return nil
   1553 	}
   1554 	b.mkdirCache[dir] = true
   1555 
   1556 	if cfg.BuildN || cfg.BuildX {
   1557 		b.Showcmd("", "mkdir -p %s", dir)
   1558 		if cfg.BuildN {
   1559 			return nil
   1560 		}
   1561 	}
   1562 
   1563 	if err := os.MkdirAll(dir, 0777); err != nil {
   1564 		return err
   1565 	}
   1566 	return nil
   1567 }
   1568 
   1569 // symlink creates a symlink newname -> oldname.
   1570 func (b *Builder) Symlink(oldname, newname string) error {
   1571 	if cfg.BuildN || cfg.BuildX {
   1572 		b.Showcmd("", "ln -s %s %s", oldname, newname)
   1573 		if cfg.BuildN {
   1574 			return nil
   1575 		}
   1576 	}
   1577 	return os.Symlink(oldname, newname)
   1578 }
   1579 
   1580 // mkAbs returns an absolute path corresponding to
   1581 // evaluating f in the directory dir.
   1582 // We always pass absolute paths of source files so that
   1583 // the error messages will include the full path to a file
   1584 // in need of attention.
   1585 func mkAbs(dir, f string) string {
   1586 	// Leave absolute paths alone.
   1587 	// Also, during -n mode we use the pseudo-directory $WORK
   1588 	// instead of creating an actual work directory that won't be used.
   1589 	// Leave paths beginning with $WORK alone too.
   1590 	if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
   1591 		return f
   1592 	}
   1593 	return filepath.Join(dir, f)
   1594 }
   1595 
   1596 type toolchain interface {
   1597 	// gc runs the compiler in a specific directory on a set of files
   1598 	// and returns the name of the generated output file.
   1599 	gc(b *Builder, a *Action, archive string, importcfg []byte, asmhdr bool, gofiles []string) (ofile string, out []byte, err error)
   1600 	// cc runs the toolchain's C compiler in a directory on a C file
   1601 	// to produce an output file.
   1602 	cc(b *Builder, a *Action, ofile, cfile string) error
   1603 	// asm runs the assembler in a specific directory on specific files
   1604 	// and returns a list of named output files.
   1605 	asm(b *Builder, a *Action, sfiles []string) ([]string, error)
   1606 	// pack runs the archive packer in a specific directory to create
   1607 	// an archive from a set of object files.
   1608 	// typically it is run in the object directory.
   1609 	pack(b *Builder, a *Action, afile string, ofiles []string) error
   1610 	// ld runs the linker to create an executable starting at mainpkg.
   1611 	ld(b *Builder, root *Action, out, importcfg, mainpkg string) error
   1612 	// ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions
   1613 	ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error
   1614 
   1615 	compiler() string
   1616 	linker() string
   1617 }
   1618 
   1619 type noToolchain struct{}
   1620 
   1621 func noCompiler() error {
   1622 	log.Fatalf("unknown compiler %q", cfg.BuildContext.Compiler)
   1623 	return nil
   1624 }
   1625 
   1626 func (noToolchain) compiler() string {
   1627 	noCompiler()
   1628 	return ""
   1629 }
   1630 
   1631 func (noToolchain) linker() string {
   1632 	noCompiler()
   1633 	return ""
   1634 }
   1635 
   1636 func (noToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) {
   1637 	return "", nil, noCompiler()
   1638 }
   1639 
   1640 func (noToolchain) asm(b *Builder, a *Action, sfiles []string) ([]string, error) {
   1641 	return nil, noCompiler()
   1642 }
   1643 
   1644 func (noToolchain) pack(b *Builder, a *Action, afile string, ofiles []string) error {
   1645 	return noCompiler()
   1646 }
   1647 
   1648 func (noToolchain) ld(b *Builder, root *Action, out, importcfg, mainpkg string) error {
   1649 	return noCompiler()
   1650 }
   1651 
   1652 func (noToolchain) ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error {
   1653 	return noCompiler()
   1654 }
   1655 
   1656 func (noToolchain) cc(b *Builder, a *Action, ofile, cfile string) error {
   1657 	return noCompiler()
   1658 }
   1659 
   1660 // gcc runs the gcc C compiler to create an object from a single C file.
   1661 func (b *Builder) gcc(a *Action, p *load.Package, workdir, out string, flags []string, cfile string) error {
   1662 	return b.ccompile(a, p, out, flags, cfile, b.GccCmd(p.Dir, workdir))
   1663 }
   1664 
   1665 // gxx runs the g++ C++ compiler to create an object from a single C++ file.
   1666 func (b *Builder) gxx(a *Action, p *load.Package, workdir, out string, flags []string, cxxfile string) error {
   1667 	return b.ccompile(a, p, out, flags, cxxfile, b.GxxCmd(p.Dir, workdir))
   1668 }
   1669 
   1670 // gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file.
   1671 func (b *Builder) gfortran(a *Action, p *load.Package, workdir, out string, flags []string, ffile string) error {
   1672 	return b.ccompile(a, p, out, flags, ffile, b.gfortranCmd(p.Dir, workdir))
   1673 }
   1674 
   1675 // ccompile runs the given C or C++ compiler and creates an object from a single source file.
   1676 func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []string, file string, compiler []string) error {
   1677 	file = mkAbs(p.Dir, file)
   1678 	desc := p.ImportPath
   1679 	if !filepath.IsAbs(outfile) {
   1680 		outfile = filepath.Join(p.Dir, outfile)
   1681 	}
   1682 	output, err := b.runOut(filepath.Dir(file), desc, nil, compiler, flags, "-o", outfile, "-c", filepath.Base(file))
   1683 	if len(output) > 0 {
   1684 		// On FreeBSD 11, when we pass -g to clang 3.8 it
   1685 		// invokes its internal assembler with -dwarf-version=2.
   1686 		// When it sees .section .note.GNU-stack, it warns
   1687 		// "DWARF2 only supports one section per compilation unit".
   1688 		// This warning makes no sense, since the section is empty,
   1689 		// but it confuses people.
   1690 		// We work around the problem by detecting the warning
   1691 		// and dropping -g and trying again.
   1692 		if bytes.Contains(output, []byte("DWARF2 only supports one section per compilation unit")) {
   1693 			newFlags := make([]string, 0, len(flags))
   1694 			for _, f := range flags {
   1695 				if !strings.HasPrefix(f, "-g") {
   1696 					newFlags = append(newFlags, f)
   1697 				}
   1698 			}
   1699 			if len(newFlags) < len(flags) {
   1700 				return b.ccompile(a, p, outfile, newFlags, file, compiler)
   1701 			}
   1702 		}
   1703 
   1704 		b.showOutput(a, p.Dir, desc, b.processOutput(output))
   1705 		if err != nil {
   1706 			err = errPrintedOutput
   1707 		} else if os.Getenv("GO_BUILDER_NAME") != "" {
   1708 			return errors.New("C compiler warning promoted to error on Go builders")
   1709 		}
   1710 	}
   1711 	return err
   1712 }
   1713 
   1714 // gccld runs the gcc linker to create an executable from a set of object files.
   1715 func (b *Builder) gccld(p *load.Package, objdir, out string, flags []string, objs []string) error {
   1716 	var cmd []string
   1717 	if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 {
   1718 		cmd = b.GxxCmd(p.Dir, objdir)
   1719 	} else {
   1720 		cmd = b.GccCmd(p.Dir, objdir)
   1721 	}
   1722 	return b.run(nil, p.Dir, p.ImportPath, nil, cmd, "-o", out, objs, flags)
   1723 }
   1724 
   1725 // Grab these before main helpfully overwrites them.
   1726 var (
   1727 	origCC  = os.Getenv("CC")
   1728 	origCXX = os.Getenv("CXX")
   1729 )
   1730 
   1731 // gccCmd returns a gcc command line prefix
   1732 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
   1733 func (b *Builder) GccCmd(incdir, workdir string) []string {
   1734 	return b.compilerCmd(b.ccExe(), incdir, workdir)
   1735 }
   1736 
   1737 // gxxCmd returns a g++ command line prefix
   1738 // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
   1739 func (b *Builder) GxxCmd(incdir, workdir string) []string {
   1740 	return b.compilerCmd(b.cxxExe(), incdir, workdir)
   1741 }
   1742 
   1743 // gfortranCmd returns a gfortran command line prefix.
   1744 func (b *Builder) gfortranCmd(incdir, workdir string) []string {
   1745 	return b.compilerCmd(b.fcExe(), incdir, workdir)
   1746 }
   1747 
   1748 // ccExe returns the CC compiler setting without all the extra flags we add implicitly.
   1749 func (b *Builder) ccExe() []string {
   1750 	return b.compilerExe(origCC, cfg.DefaultCC(cfg.Goos, cfg.Goarch))
   1751 }
   1752 
   1753 // cxxExe returns the CXX compiler setting without all the extra flags we add implicitly.
   1754 func (b *Builder) cxxExe() []string {
   1755 	return b.compilerExe(origCXX, cfg.DefaultCXX(cfg.Goos, cfg.Goarch))
   1756 }
   1757 
   1758 // fcExe returns the FC compiler setting without all the extra flags we add implicitly.
   1759 func (b *Builder) fcExe() []string {
   1760 	return b.compilerExe(os.Getenv("FC"), "gfortran")
   1761 }
   1762 
   1763 // compilerExe returns the compiler to use given an
   1764 // environment variable setting (the value not the name)
   1765 // and a default. The resulting slice is usually just the name
   1766 // of the compiler but can have additional arguments if they
   1767 // were present in the environment value.
   1768 // For example if CC="gcc -DGOPHER" then the result is ["gcc", "-DGOPHER"].
   1769 func (b *Builder) compilerExe(envValue string, def string) []string {
   1770 	compiler := strings.Fields(envValue)
   1771 	if len(compiler) == 0 {
   1772 		compiler = []string{def}
   1773 	}
   1774 	return compiler
   1775 }
   1776 
   1777 // compilerCmd returns a command line prefix for the given environment
   1778 // variable and using the default command when the variable is empty.
   1779 func (b *Builder) compilerCmd(compiler []string, incdir, workdir string) []string {
   1780 	// NOTE: env.go's mkEnv knows that the first three
   1781 	// strings returned are "gcc", "-I", incdir (and cuts them off).
   1782 	a := []string{compiler[0], "-I", incdir}
   1783 	a = append(a, compiler[1:]...)
   1784 
   1785 	// Definitely want -fPIC but on Windows gcc complains
   1786 	// "-fPIC ignored for target (all code is position independent)"
   1787 	if cfg.Goos != "windows" {
   1788 		a = append(a, "-fPIC")
   1789 	}
   1790 	a = append(a, b.gccArchArgs()...)
   1791 	// gcc-4.5 and beyond require explicit "-pthread" flag
   1792 	// for multithreading with pthread library.
   1793 	if cfg.BuildContext.CgoEnabled {
   1794 		switch cfg.Goos {
   1795 		case "windows":
   1796 			a = append(a, "-mthreads")
   1797 		default:
   1798 			a = append(a, "-pthread")
   1799 		}
   1800 	}
   1801 
   1802 	// disable ASCII art in clang errors, if possible
   1803 	if b.gccSupportsFlag(compiler, "-fno-caret-diagnostics") {
   1804 		a = append(a, "-fno-caret-diagnostics")
   1805 	}
   1806 	// clang is too smart about command-line arguments
   1807 	if b.gccSupportsFlag(compiler, "-Qunused-arguments") {
   1808 		a = append(a, "-Qunused-arguments")
   1809 	}
   1810 
   1811 	// disable word wrapping in error messages
   1812 	a = append(a, "-fmessage-length=0")
   1813 
   1814 	// Tell gcc not to include the work directory in object files.
   1815 	if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") {
   1816 		if workdir == "" {
   1817 			workdir = b.WorkDir
   1818 		}
   1819 		workdir = strings.TrimSuffix(workdir, string(filepath.Separator))
   1820 		a = append(a, "-fdebug-prefix-map="+workdir+"=/tmp/go-build")
   1821 	}
   1822 
   1823 	// Tell gcc not to include flags in object files, which defeats the
   1824 	// point of -fdebug-prefix-map above.
   1825 	if b.gccSupportsFlag(compiler, "-gno-record-gcc-switches") {
   1826 		a = append(a, "-gno-record-gcc-switches")
   1827 	}
   1828 
   1829 	// On OS X, some of the compilers behave as if -fno-common
   1830 	// is always set, and the Mach-O linker in 6l/8l assumes this.
   1831 	// See https://golang.org/issue/3253.
   1832 	if cfg.Goos == "darwin" {
   1833 		a = append(a, "-fno-common")
   1834 	}
   1835 
   1836 	return a
   1837 }
   1838 
   1839 // gccNoPie returns the flag to use to request non-PIE. On systems
   1840 // with PIE (position independent executables) enabled by default,
   1841 // -no-pie must be passed when doing a partial link with -Wl,-r.
   1842 // But -no-pie is not supported by all compilers, and clang spells it -nopie.
   1843 func (b *Builder) gccNoPie(linker []string) string {
   1844 	if b.gccSupportsFlag(linker, "-no-pie") {
   1845 		return "-no-pie"
   1846 	}
   1847 	if b.gccSupportsFlag(linker, "-nopie") {
   1848 		return "-nopie"
   1849 	}
   1850 	return ""
   1851 }
   1852 
   1853 // gccSupportsFlag checks to see if the compiler supports a flag.
   1854 func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool {
   1855 	key := [2]string{compiler[0], flag}
   1856 
   1857 	b.exec.Lock()
   1858 	defer b.exec.Unlock()
   1859 	if b, ok := b.flagCache[key]; ok {
   1860 		return b
   1861 	}
   1862 	if b.flagCache == nil {
   1863 		b.flagCache = make(map[[2]string]bool)
   1864 	}
   1865 	// We used to write an empty C file, but that gets complicated with
   1866 	// go build -n. We tried using a file that does not exist, but that
   1867 	// fails on systems with GCC version 4.2.1; that is the last GPLv2
   1868 	// version of GCC, so some systems have frozen on it.
   1869 	// Now we pass an empty file on stdin, which should work at least for
   1870 	// GCC and clang.
   1871 	cmdArgs := str.StringList(compiler, flag, "-c", "-x", "c", "-")
   1872 	if cfg.BuildN || cfg.BuildX {
   1873 		b.Showcmd(b.WorkDir, "%s || true", joinUnambiguously(cmdArgs))
   1874 		if cfg.BuildN {
   1875 			return false
   1876 		}
   1877 	}
   1878 	cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
   1879 	cmd.Dir = b.WorkDir
   1880 	cmd.Env = base.MergeEnvLists([]string{"LC_ALL=C"}, base.EnvForDir(cmd.Dir, os.Environ()))
   1881 	out, _ := cmd.CombinedOutput()
   1882 	// GCC says "unrecognized command line option".
   1883 	// clang says "unknown argument".
   1884 	// Older versions of GCC say "unrecognised debug output level".
   1885 	// For -fsplit-stack GCC says "'-fsplit-stack' is not supported".
   1886 	supported := !bytes.Contains(out, []byte("unrecognized")) &&
   1887 		!bytes.Contains(out, []byte("unknown")) &&
   1888 		!bytes.Contains(out, []byte("unrecognised")) &&
   1889 		!bytes.Contains(out, []byte("is not supported"))
   1890 	b.flagCache[key] = supported
   1891 	return supported
   1892 }
   1893 
   1894 // gccArchArgs returns arguments to pass to gcc based on the architecture.
   1895 func (b *Builder) gccArchArgs() []string {
   1896 	switch cfg.Goarch {
   1897 	case "386":
   1898 		return []string{"-m32"}
   1899 	case "amd64", "amd64p32":
   1900 		return []string{"-m64"}
   1901 	case "arm":
   1902 		return []string{"-marm"} // not thumb
   1903 	case "s390x":
   1904 		return []string{"-m64", "-march=z196"}
   1905 	case "mips64", "mips64le":
   1906 		return []string{"-mabi=64"}
   1907 	case "mips", "mipsle":
   1908 		return []string{"-mabi=32", "-march=mips32"}
   1909 	}
   1910 	return nil
   1911 }
   1912 
   1913 // envList returns the value of the given environment variable broken
   1914 // into fields, using the default value when the variable is empty.
   1915 func envList(key, def string) []string {
   1916 	v := os.Getenv(key)
   1917 	if v == "" {
   1918 		v = def
   1919 	}
   1920 	return strings.Fields(v)
   1921 }
   1922 
   1923 // CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo.
   1924 func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, ldflags []string, err error) {
   1925 	defaults := "-g -O2"
   1926 
   1927 	if cppflags, err = buildFlags("CPPFLAGS", "", p.CgoCPPFLAGS, checkCompilerFlags); err != nil {
   1928 		return
   1929 	}
   1930 	if cflags, err = buildFlags("CFLAGS", defaults, p.CgoCFLAGS, checkCompilerFlags); err != nil {
   1931 		return
   1932 	}
   1933 	if cxxflags, err = buildFlags("CXXFLAGS", defaults, p.CgoCXXFLAGS, checkCompilerFlags); err != nil {
   1934 		return
   1935 	}
   1936 	if fflags, err = buildFlags("FFLAGS", defaults, p.CgoFFLAGS, checkCompilerFlags); err != nil {
   1937 		return
   1938 	}
   1939 	if ldflags, err = buildFlags("LDFLAGS", defaults, p.CgoLDFLAGS, checkLinkerFlags); err != nil {
   1940 		return
   1941 	}
   1942 
   1943 	return
   1944 }
   1945 
   1946 func buildFlags(name, defaults string, fromPackage []string, check func(string, string, []string) error) ([]string, error) {
   1947 	if err := check(name, "#cgo "+name, fromPackage); err != nil {
   1948 		return nil, err
   1949 	}
   1950 	return str.StringList(envList("CGO_"+name, defaults), fromPackage), nil
   1951 }
   1952 
   1953 var cgoRe = regexp.MustCompile(`[/\\:]`)
   1954 
   1955 func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) {
   1956 	p := a.Package
   1957 	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS, err := b.CFlags(p)
   1958 	if err != nil {
   1959 		return nil, nil, err
   1960 	}
   1961 
   1962 	cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
   1963 	cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
   1964 	// If we are compiling Objective-C code, then we need to link against libobjc
   1965 	if len(mfiles) > 0 {
   1966 		cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
   1967 	}
   1968 
   1969 	// Likewise for Fortran, except there are many Fortran compilers.
   1970 	// Support gfortran out of the box and let others pass the correct link options
   1971 	// via CGO_LDFLAGS
   1972 	if len(ffiles) > 0 {
   1973 		fc := os.Getenv("FC")
   1974 		if fc == "" {
   1975 			fc = "gfortran"
   1976 		}
   1977 		if strings.Contains(fc, "gfortran") {
   1978 			cgoLDFLAGS = append(cgoLDFLAGS, "-lgfortran")
   1979 		}
   1980 	}
   1981 
   1982 	if cfg.BuildMSan {
   1983 		cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...)
   1984 		cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...)
   1985 	}
   1986 
   1987 	// Allows including _cgo_export.h from .[ch] files in the package.
   1988 	cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", objdir)
   1989 
   1990 	// cgo
   1991 	// TODO: CGO_FLAGS?
   1992 	gofiles := []string{objdir + "_cgo_gotypes.go"}
   1993 	cfiles := []string{"_cgo_export.c"}
   1994 	for _, fn := range cgofiles {
   1995 		f := strings.TrimSuffix(filepath.Base(fn), ".go")
   1996 		gofiles = append(gofiles, objdir+f+".cgo1.go")
   1997 		cfiles = append(cfiles, f+".cgo2.c")
   1998 	}
   1999 
   2000 	// TODO: make cgo not depend on $GOARCH?
   2001 
   2002 	cgoflags := []string{}
   2003 	if p.Standard && p.ImportPath == "runtime/cgo" {
   2004 		cgoflags = append(cgoflags, "-import_runtime_cgo=false")
   2005 	}
   2006 	if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") {
   2007 		cgoflags = append(cgoflags, "-import_syscall=false")
   2008 	}
   2009 
   2010 	// Update $CGO_LDFLAGS with p.CgoLDFLAGS.
   2011 	// These flags are recorded in the generated _cgo_gotypes.go file
   2012 	// using //go:cgo_ldflag directives, the compiler records them in the
   2013 	// object file for the package, and then the Go linker passes them
   2014 	// along to the host linker. At this point in the code, cgoLDFLAGS
   2015 	// consists of the original $CGO_LDFLAGS (unchecked) and all the
   2016 	// flags put together from source code (checked).
   2017 	var cgoenv []string
   2018 	if len(cgoLDFLAGS) > 0 {
   2019 		flags := make([]string, len(cgoLDFLAGS))
   2020 		for i, f := range cgoLDFLAGS {
   2021 			flags[i] = strconv.Quote(f)
   2022 		}
   2023 		cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
   2024 	}
   2025 
   2026 	if cfg.BuildToolchainName == "gccgo" {
   2027 		switch cfg.Goarch {
   2028 		case "386", "amd64":
   2029 			cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack")
   2030 		}
   2031 		cgoflags = append(cgoflags, "-gccgo")
   2032 		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
   2033 			cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
   2034 		}
   2035 	}
   2036 
   2037 	switch cfg.BuildBuildmode {
   2038 	case "c-archive", "c-shared":
   2039 		// Tell cgo that if there are any exported functions
   2040 		// it should generate a header file that C code can
   2041 		// #include.
   2042 		cgoflags = append(cgoflags, "-exportheader="+objdir+"_cgo_install.h")
   2043 	}
   2044 
   2045 	if err := b.run(a, p.Dir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, "-objdir", objdir, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil {
   2046 		return nil, nil, err
   2047 	}
   2048 	outGo = append(outGo, gofiles...)
   2049 
   2050 	// Use sequential object file names to keep them distinct
   2051 	// and short enough to fit in the .a header file name slots.
   2052 	// We no longer collect them all into _all.o, and we'd like
   2053 	// tools to see both the .o suffix and unique names, so
   2054 	// we need to make them short enough not to be truncated
   2055 	// in the final archive.
   2056 	oseq := 0
   2057 	nextOfile := func() string {
   2058 		oseq++
   2059 		return objdir + fmt.Sprintf("_x%03d.o", oseq)
   2060 	}
   2061 
   2062 	// gcc
   2063 	cflags := str.StringList(cgoCPPFLAGS, cgoCFLAGS)
   2064 	for _, cfile := range cfiles {
   2065 		ofile := nextOfile()
   2066 		if err := b.gcc(a, p, a.Objdir, ofile, cflags, objdir+cfile); err != nil {
   2067 			return nil, nil, err
   2068 		}
   2069 		outObj = append(outObj, ofile)
   2070 	}
   2071 
   2072 	for _, file := range gccfiles {
   2073 		ofile := nextOfile()
   2074 		if err := b.gcc(a, p, a.Objdir, ofile, cflags, file); err != nil {
   2075 			return nil, nil, err
   2076 		}
   2077 		outObj = append(outObj, ofile)
   2078 	}
   2079 
   2080 	cxxflags := str.StringList(cgoCPPFLAGS, cgoCXXFLAGS)
   2081 	for _, file := range gxxfiles {
   2082 		ofile := nextOfile()
   2083 		if err := b.gxx(a, p, a.Objdir, ofile, cxxflags, file); err != nil {
   2084 			return nil, nil, err
   2085 		}
   2086 		outObj = append(outObj, ofile)
   2087 	}
   2088 
   2089 	for _, file := range mfiles {
   2090 		ofile := nextOfile()
   2091 		if err := b.gcc(a, p, a.Objdir, ofile, cflags, file); err != nil {
   2092 			return nil, nil, err
   2093 		}
   2094 		outObj = append(outObj, ofile)
   2095 	}
   2096 
   2097 	fflags := str.StringList(cgoCPPFLAGS, cgoFFLAGS)
   2098 	for _, file := range ffiles {
   2099 		ofile := nextOfile()
   2100 		if err := b.gfortran(a, p, a.Objdir, ofile, fflags, file); err != nil {
   2101 			return nil, nil, err
   2102 		}
   2103 		outObj = append(outObj, ofile)
   2104 	}
   2105 
   2106 	switch cfg.BuildToolchainName {
   2107 	case "gc":
   2108 		importGo := objdir + "_cgo_import.go"
   2109 		if err := b.dynimport(a, p, objdir, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil {
   2110 			return nil, nil, err
   2111 		}
   2112 		outGo = append(outGo, importGo)
   2113 
   2114 	case "gccgo":
   2115 		defunC := objdir + "_cgo_defun.c"
   2116 		defunObj := objdir + "_cgo_defun.o"
   2117 		if err := BuildToolchain.cc(b, a, defunObj, defunC); err != nil {
   2118 			return nil, nil, err
   2119 		}
   2120 		outObj = append(outObj, defunObj)
   2121 
   2122 	default:
   2123 		noCompiler()
   2124 	}
   2125 
   2126 	return outGo, outObj, nil
   2127 }
   2128 
   2129 // dynimport creates a Go source file named importGo containing
   2130 // //go:cgo_import_dynamic directives for each symbol or library
   2131 // dynamically imported by the object files outObj.
   2132 func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe string, cflags, cgoLDFLAGS, outObj []string) error {
   2133 	cfile := objdir + "_cgo_main.c"
   2134 	ofile := objdir + "_cgo_main.o"
   2135 	if err := b.gcc(a, p, objdir, ofile, cflags, cfile); err != nil {
   2136 		return err
   2137 	}
   2138 
   2139 	linkobj := str.StringList(ofile, outObj, p.SysoFiles)
   2140 	dynobj := objdir + "_cgo_.o"
   2141 
   2142 	// we need to use -pie for Linux/ARM to get accurate imported sym
   2143 	ldflags := cgoLDFLAGS
   2144 	if (cfg.Goarch == "arm" && cfg.Goos == "linux") || cfg.Goos == "android" {
   2145 		ldflags = append(ldflags, "-pie")
   2146 	}
   2147 	if err := b.gccld(p, objdir, dynobj, ldflags, linkobj); err != nil {
   2148 		return err
   2149 	}
   2150 
   2151 	// cgo -dynimport
   2152 	var cgoflags []string
   2153 	if p.Standard && p.ImportPath == "runtime/cgo" {
   2154 		cgoflags = []string{"-dynlinker"} // record path to dynamic linker
   2155 	}
   2156 	return b.run(a, p.Dir, p.ImportPath, nil, cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags)
   2157 }
   2158 
   2159 // Run SWIG on all SWIG input files.
   2160 // TODO: Don't build a shared library, once SWIG emits the necessary
   2161 // pragmas for external linking.
   2162 func (b *Builder) swig(a *Action, p *load.Package, objdir string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) {
   2163 	if err := b.swigVersionCheck(); err != nil {
   2164 		return nil, nil, nil, err
   2165 	}
   2166 
   2167 	intgosize, err := b.swigIntSize(objdir)
   2168 	if err != nil {
   2169 		return nil, nil, nil, err
   2170 	}
   2171 
   2172 	for _, f := range p.SwigFiles {
   2173 		goFile, cFile, err := b.swigOne(a, p, f, objdir, pcCFLAGS, false, intgosize)
   2174 		if err != nil {
   2175 			return nil, nil, nil, err
   2176 		}
   2177 		if goFile != "" {
   2178 			outGo = append(outGo, goFile)
   2179 		}
   2180 		if cFile != "" {
   2181 			outC = append(outC, cFile)
   2182 		}
   2183 	}
   2184 	for _, f := range p.SwigCXXFiles {
   2185 		goFile, cxxFile, err := b.swigOne(a, p, f, objdir, pcCFLAGS, true, intgosize)
   2186 		if err != nil {
   2187 			return nil, nil, nil, err
   2188 		}
   2189 		if goFile != "" {
   2190 			outGo = append(outGo, goFile)
   2191 		}
   2192 		if cxxFile != "" {
   2193 			outCXX = append(outCXX, cxxFile)
   2194 		}
   2195 	}
   2196 	return outGo, outC, outCXX, nil
   2197 }
   2198 
   2199 // Make sure SWIG is new enough.
   2200 var (
   2201 	swigCheckOnce sync.Once
   2202 	swigCheck     error
   2203 )
   2204 
   2205 func (b *Builder) swigDoVersionCheck() error {
   2206 	out, err := b.runOut("", "", nil, "swig", "-version")
   2207 	if err != nil {
   2208 		return err
   2209 	}
   2210 	re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`)
   2211 	matches := re.FindSubmatch(out)
   2212 	if matches == nil {
   2213 		// Can't find version number; hope for the best.
   2214 		return nil
   2215 	}
   2216 
   2217 	major, err := strconv.Atoi(string(matches[1]))
   2218 	if err != nil {
   2219 		// Can't find version number; hope for the best.
   2220 		return nil
   2221 	}
   2222 	const errmsg = "must have SWIG version >= 3.0.6"
   2223 	if major < 3 {
   2224 		return errors.New(errmsg)
   2225 	}
   2226 	if major > 3 {
   2227 		// 4.0 or later
   2228 		return nil
   2229 	}
   2230 
   2231 	// We have SWIG version 3.x.
   2232 	if len(matches[2]) > 0 {
   2233 		minor, err := strconv.Atoi(string(matches[2][1:]))
   2234 		if err != nil {
   2235 			return nil
   2236 		}
   2237 		if minor > 0 {
   2238 			// 3.1 or later
   2239 			return nil
   2240 		}
   2241 	}
   2242 
   2243 	// We have SWIG version 3.0.x.
   2244 	if len(matches[3]) > 0 {
   2245 		patch, err := strconv.Atoi(string(matches[3][1:]))
   2246 		if err != nil {
   2247 			return nil
   2248 		}
   2249 		if patch < 6 {
   2250 			// Before 3.0.6.
   2251 			return errors.New(errmsg)
   2252 		}
   2253 	}
   2254 
   2255 	return nil
   2256 }
   2257 
   2258 func (b *Builder) swigVersionCheck() error {
   2259 	swigCheckOnce.Do(func() {
   2260 		swigCheck = b.swigDoVersionCheck()
   2261 	})
   2262 	return swigCheck
   2263 }
   2264 
   2265 // Find the value to pass for the -intgosize option to swig.
   2266 var (
   2267 	swigIntSizeOnce  sync.Once
   2268 	swigIntSize      string
   2269 	swigIntSizeError error
   2270 )
   2271 
   2272 // This code fails to build if sizeof(int) <= 32
   2273 const swigIntSizeCode = `
   2274 package main
   2275 const i int = 1 << 32
   2276 `
   2277 
   2278 // Determine the size of int on the target system for the -intgosize option
   2279 // of swig >= 2.0.9. Run only once.
   2280 func (b *Builder) swigDoIntSize(objdir string) (intsize string, err error) {
   2281 	if cfg.BuildN {
   2282 		return "$INTBITS", nil
   2283 	}
   2284 	src := filepath.Join(b.WorkDir, "swig_intsize.go")
   2285 	if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil {
   2286 		return
   2287 	}
   2288 	srcs := []string{src}
   2289 
   2290 	p := load.GoFilesPackage(srcs)
   2291 
   2292 	if _, _, e := BuildToolchain.gc(b, &Action{Mode: "swigDoIntSize", Package: p, Objdir: objdir}, "", nil, false, srcs); e != nil {
   2293 		return "32", nil
   2294 	}
   2295 	return "64", nil
   2296 }
   2297 
   2298 // Determine the size of int on the target system for the -intgosize option
   2299 // of swig >= 2.0.9.
   2300 func (b *Builder) swigIntSize(objdir string) (intsize string, err error) {
   2301 	swigIntSizeOnce.Do(func() {
   2302 		swigIntSize, swigIntSizeError = b.swigDoIntSize(objdir)
   2303 	})
   2304 	return swigIntSize, swigIntSizeError
   2305 }
   2306 
   2307 // Run SWIG on one SWIG input file.
   2308 func (b *Builder) swigOne(a *Action, p *load.Package, file, objdir string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) {
   2309 	cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _, err := b.CFlags(p)
   2310 	if err != nil {
   2311 		return "", "", err
   2312 	}
   2313 
   2314 	var cflags []string
   2315 	if cxx {
   2316 		cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
   2317 	} else {
   2318 		cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
   2319 	}
   2320 
   2321 	n := 5 // length of ".swig"
   2322 	if cxx {
   2323 		n = 8 // length of ".swigcxx"
   2324 	}
   2325 	base := file[:len(file)-n]
   2326 	goFile := base + ".go"
   2327 	gccBase := base + "_wrap."
   2328 	gccExt := "c"
   2329 	if cxx {
   2330 		gccExt = "cxx"
   2331 	}
   2332 
   2333 	gccgo := cfg.BuildToolchainName == "gccgo"
   2334 
   2335 	// swig
   2336 	args := []string{
   2337 		"-go",
   2338 		"-cgo",
   2339 		"-intgosize", intgosize,
   2340 		"-module", base,
   2341 		"-o", objdir + gccBase + gccExt,
   2342 		"-outdir", objdir,
   2343 	}
   2344 
   2345 	for _, f := range cflags {
   2346 		if len(f) > 3 && f[:2] == "-I" {
   2347 			args = append(args, f)
   2348 		}
   2349 	}
   2350 
   2351 	if gccgo {
   2352 		args = append(args, "-gccgo")
   2353 		if pkgpath := gccgoPkgpath(p); pkgpath != "" {
   2354 			args = append(args, "-go-pkgpath", pkgpath)
   2355 		}
   2356 	}
   2357 	if cxx {
   2358 		args = append(args, "-c++")
   2359 	}
   2360 
   2361 	out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file)
   2362 	if err != nil {
   2363 		if len(out) > 0 {
   2364 			if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) {
   2365 				return "", "", errors.New("must have SWIG version >= 3.0.6")
   2366 			}
   2367 			b.showOutput(a, p.Dir, p.ImportPath, b.processOutput(out)) // swig error
   2368 			return "", "", errPrintedOutput
   2369 		}
   2370 		return "", "", err
   2371 	}
   2372 	if len(out) > 0 {
   2373 		b.showOutput(a, p.Dir, p.ImportPath, b.processOutput(out)) // swig warning
   2374 	}
   2375 
   2376 	// If the input was x.swig, the output is x.go in the objdir.
   2377 	// But there might be an x.go in the original dir too, and if it
   2378 	// uses cgo as well, cgo will be processing both and will
   2379 	// translate both into x.cgo1.go in the objdir, overwriting one.
   2380 	// Rename x.go to _x_swig.go to avoid this problem.
   2381 	// We ignore files in the original dir that begin with underscore
   2382 	// so _x_swig.go cannot conflict with an original file we were
   2383 	// going to compile.
   2384 	goFile = objdir + goFile
   2385 	newGoFile := objdir + "_" + base + "_swig.go"
   2386 	if err := os.Rename(goFile, newGoFile); err != nil {
   2387 		return "", "", err
   2388 	}
   2389 	return newGoFile, objdir + gccBase + gccExt, nil
   2390 }
   2391 
   2392 // disableBuildID adjusts a linker command line to avoid creating a
   2393 // build ID when creating an object file rather than an executable or
   2394 // shared library. Some systems, such as Ubuntu, always add
   2395 // --build-id to every link, but we don't want a build ID when we are
   2396 // producing an object file. On some of those system a plain -r (not
   2397 // -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a
   2398 // plain -r. I don't know how to turn off --build-id when using clang
   2399 // other than passing a trailing --build-id=none. So that is what we
   2400 // do, but only on systems likely to support it, which is to say,
   2401 // systems that normally use gold or the GNU linker.
   2402 func (b *Builder) disableBuildID(ldflags []string) []string {
   2403 	switch cfg.Goos {
   2404 	case "android", "dragonfly", "linux", "netbsd":
   2405 		ldflags = append(ldflags, "-Wl,--build-id=none")
   2406 	}
   2407 	return ldflags
   2408 }
   2409 
   2410 // mkAbsFiles converts files into a list of absolute files,
   2411 // assuming they were originally relative to dir,
   2412 // and returns that new list.
   2413 func mkAbsFiles(dir string, files []string) []string {
   2414 	abs := make([]string, len(files))
   2415 	for i, f := range files {
   2416 		if !filepath.IsAbs(f) {
   2417 			f = filepath.Join(dir, f)
   2418 		}
   2419 		abs[i] = f
   2420 	}
   2421 	return abs
   2422 }
   2423