]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/go/build.go
math/big: fix %b format so it matches strconf %b format for non-zero values
[gostls13.git] / src / cmd / go / build.go
1 // Copyright 2011 The Go Authors.  All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package main
6
7 import (
8         "bufio"
9         "bytes"
10         "container/heap"
11         "errors"
12         "flag"
13         "fmt"
14         "go/build"
15         "io"
16         "io/ioutil"
17         "log"
18         "os"
19         "os/exec"
20         "path"
21         "path/filepath"
22         "regexp"
23         "runtime"
24         "strconv"
25         "strings"
26         "sync"
27         "time"
28 )
29
30 var cmdBuild = &Command{
31         UsageLine: "build [-o output] [-i] [build flags] [packages]",
32         Short:     "compile packages and dependencies",
33         Long: `
34 Build compiles the packages named by the import paths,
35 along with their dependencies, but it does not install the results.
36
37 If the arguments are a list of .go files, build treats them as a list
38 of source files specifying a single package.
39
40 When the command line specifies a single main package,
41 build writes the resulting executable to output.
42 Otherwise build compiles the packages but discards the results,
43 serving only as a check that the packages can be built.
44
45 The -o flag specifies the output file name. If not specified, the
46 output file name depends on the arguments and derives from the name
47 of the package, such as p.a for package p, unless p is 'main'. If
48 the package is main and file names are provided, the file name
49 derives from the first file name mentioned, such as f1 for 'go build
50 f1.go f2.go'; with no files provided ('go build'), the output file
51 name is the base name of the containing directory.
52
53 The -i flag installs the packages that are dependencies of the target.
54
55 The build flags are shared by the build, clean, get, install, list, run,
56 and test commands:
57
58         -a
59                 force rebuilding of packages that are already up-to-date.
60                 In Go releases, does not apply to the standard library.
61         -n
62                 print the commands but do not run them.
63         -p n
64                 the number of builds that can be run in parallel.
65                 The default is the number of CPUs available.
66         -race
67                 enable data race detection.
68                 Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
69         -v
70                 print the names of packages as they are compiled.
71         -work
72                 print the name of the temporary work directory and
73                 do not delete it when exiting.
74         -x
75                 print the commands.
76
77         -compiler name
78                 name of compiler to use, as in runtime.Compiler (gccgo or gc).
79         -gccgoflags 'arg list'
80                 arguments to pass on each gccgo compiler/linker invocation.
81         -gcflags 'arg list'
82                 arguments to pass on each 5g, 6g, 8g, or 9g compiler invocation.
83         -installsuffix suffix
84                 a suffix to use in the name of the package installation directory,
85                 in order to keep output separate from default builds.
86                 If using the -race flag, the install suffix is automatically set to race
87                 or, if set explicitly, has _race appended to it.
88         -ldflags 'flag list'
89                 arguments to pass on each 5l, 6l, 8l, or 9l linker invocation.
90         -tags 'tag list'
91                 a list of build tags to consider satisfied during the build.
92                 For more information about build tags, see the description of
93                 build constraints in the documentation for the go/build package.
94         -toolexec 'cmd args'
95                 a program to use to invoke toolchain programs like 5a, 5g, and 5l.
96                 For example, instead of running 5g, the go command will run
97                 'cmd args /path/to/5g <arguments for 5g>'.
98
99 The list flags accept a space-separated list of strings. To embed spaces
100 in an element in the list, surround it with either single or double quotes.
101
102 For more about specifying packages, see 'go help packages'.
103 For more about where packages and binaries are installed,
104 run 'go help gopath'.  For more about calling between Go and C/C++,
105 run 'go help c'.
106
107 See also: go install, go get, go clean.
108         `,
109 }
110
111 func init() {
112         // break init cycle
113         cmdBuild.Run = runBuild
114         cmdInstall.Run = runInstall
115
116         cmdBuild.Flag.BoolVar(&buildI, "i", false, "")
117
118         addBuildFlags(cmdBuild)
119         addBuildFlags(cmdInstall)
120 }
121
122 // Flags set by multiple commands.
123 var buildA bool               // -a flag
124 var buildN bool               // -n flag
125 var buildP = runtime.NumCPU() // -p flag
126 var buildV bool               // -v flag
127 var buildX bool               // -x flag
128 var buildI bool               // -i flag
129 var buildO = cmdBuild.Flag.String("o", "", "output file")
130 var buildWork bool           // -work flag
131 var buildGcflags []string    // -gcflags flag
132 var buildLdflags []string    // -ldflags flag
133 var buildGccgoflags []string // -gccgoflags flag
134 var buildRace bool           // -race flag
135 var buildToolExec []string   // -toolexec flag
136
137 var buildContext = build.Default
138 var buildToolchain toolchain = noToolchain{}
139
140 // buildCompiler implements flag.Var.
141 // It implements Set by updating both
142 // buildToolchain and buildContext.Compiler.
143 type buildCompiler struct{}
144
145 func (c buildCompiler) Set(value string) error {
146         switch value {
147         case "gc":
148                 buildToolchain = gcToolchain{}
149         case "gccgo":
150                 buildToolchain = gccgoToolchain{}
151         default:
152                 return fmt.Errorf("unknown compiler %q", value)
153         }
154         buildContext.Compiler = value
155         return nil
156 }
157
158 func (c buildCompiler) String() string {
159         return buildContext.Compiler
160 }
161
162 func init() {
163         switch build.Default.Compiler {
164         case "gc":
165                 buildToolchain = gcToolchain{}
166         case "gccgo":
167                 buildToolchain = gccgoToolchain{}
168         }
169 }
170
171 // addBuildFlags adds the flags common to the build, clean, get,
172 // install, list, run, and test commands.
173 func addBuildFlags(cmd *Command) {
174         // NOTE: If you add flags here, also add them to testflag.go.
175         cmd.Flag.BoolVar(&buildA, "a", false, "")
176         cmd.Flag.BoolVar(&buildN, "n", false, "")
177         cmd.Flag.IntVar(&buildP, "p", buildP, "")
178         cmd.Flag.StringVar(&buildContext.InstallSuffix, "installsuffix", "", "")
179         cmd.Flag.BoolVar(&buildV, "v", false, "")
180         cmd.Flag.BoolVar(&buildX, "x", false, "")
181         cmd.Flag.BoolVar(&buildWork, "work", false, "")
182         cmd.Flag.Var((*stringsFlag)(&buildGcflags), "gcflags", "")
183         cmd.Flag.Var((*stringsFlag)(&buildLdflags), "ldflags", "")
184         cmd.Flag.Var((*stringsFlag)(&buildGccgoflags), "gccgoflags", "")
185         cmd.Flag.Var((*stringsFlag)(&buildContext.BuildTags), "tags", "")
186         cmd.Flag.Var(buildCompiler{}, "compiler", "")
187         cmd.Flag.BoolVar(&buildRace, "race", false, "")
188         cmd.Flag.Var((*stringsFlag)(&buildToolExec), "toolexec", "")
189 }
190
191 func addBuildFlagsNX(cmd *Command) {
192         cmd.Flag.BoolVar(&buildN, "n", false, "")
193         cmd.Flag.BoolVar(&buildX, "x", false, "")
194 }
195
196 func isSpaceByte(c byte) bool {
197         return c == ' ' || c == '\t' || c == '\n' || c == '\r'
198 }
199
200 // fileExtSplit expects a filename and returns the name
201 // and ext (without the dot). If the file has no
202 // extension, ext will be empty.
203 func fileExtSplit(file string) (name, ext string) {
204         dotExt := filepath.Ext(file)
205         name = file[:len(file)-len(dotExt)]
206         if dotExt != "" {
207                 ext = dotExt[1:]
208         }
209         return
210 }
211
212 type stringsFlag []string
213
214 func (v *stringsFlag) Set(s string) error {
215         var err error
216         *v, err = splitQuotedFields(s)
217         if *v == nil {
218                 *v = []string{}
219         }
220         return err
221 }
222
223 func splitQuotedFields(s string) ([]string, error) {
224         // Split fields allowing '' or "" around elements.
225         // Quotes further inside the string do not count.
226         var f []string
227         for len(s) > 0 {
228                 for len(s) > 0 && isSpaceByte(s[0]) {
229                         s = s[1:]
230                 }
231                 if len(s) == 0 {
232                         break
233                 }
234                 // Accepted quoted string. No unescaping inside.
235                 if s[0] == '"' || s[0] == '\'' {
236                         quote := s[0]
237                         s = s[1:]
238                         i := 0
239                         for i < len(s) && s[i] != quote {
240                                 i++
241                         }
242                         if i >= len(s) {
243                                 return nil, fmt.Errorf("unterminated %c string", quote)
244                         }
245                         f = append(f, s[:i])
246                         s = s[i+1:]
247                         continue
248                 }
249                 i := 0
250                 for i < len(s) && !isSpaceByte(s[i]) {
251                         i++
252                 }
253                 f = append(f, s[:i])
254                 s = s[i:]
255         }
256         return f, nil
257 }
258
259 func (v *stringsFlag) String() string {
260         return "<stringsFlag>"
261 }
262
263 func runBuild(cmd *Command, args []string) {
264         raceInit()
265         var b builder
266         b.init()
267
268         pkgs := packagesForBuild(args)
269
270         if len(pkgs) == 1 && pkgs[0].Name == "main" && *buildO == "" {
271                 _, *buildO = path.Split(pkgs[0].ImportPath)
272                 *buildO += exeSuffix
273         }
274
275         // sanity check some often mis-used options
276         switch buildContext.Compiler {
277         case "gccgo":
278                 if len(buildGcflags) != 0 {
279                         fmt.Println("go build: when using gccgo toolchain, please pass compiler flags using -gccgoflags, not -gcflags")
280                 }
281                 if len(buildLdflags) != 0 {
282                         fmt.Println("go build: when using gccgo toolchain, please pass linker flags using -gccgoflags, not -ldflags")
283                 }
284         case "gc":
285                 if len(buildGccgoflags) != 0 {
286                         fmt.Println("go build: when using gc toolchain, please pass compile flags using -gcflags, and linker flags using -ldflags")
287                 }
288         }
289
290         depMode := modeBuild
291         if buildI {
292                 depMode = modeInstall
293         }
294
295         if *buildO != "" {
296                 if len(pkgs) > 1 {
297                         fatalf("go build: cannot use -o with multiple packages")
298                 } else if len(pkgs) == 0 {
299                         fatalf("no packages to build")
300                 }
301                 p := pkgs[0]
302                 p.target = "" // must build - not up to date
303                 a := b.action(modeInstall, depMode, p)
304                 a.target = *buildO
305                 b.do(a)
306                 return
307         }
308
309         a := &action{}
310         for _, p := range packages(args) {
311                 a.deps = append(a.deps, b.action(modeBuild, depMode, p))
312         }
313         b.do(a)
314 }
315
316 var cmdInstall = &Command{
317         UsageLine: "install [build flags] [packages]",
318         Short:     "compile and install packages and dependencies",
319         Long: `
320 Install compiles and installs the packages named by the import paths,
321 along with their dependencies.
322
323 For more about the build flags, see 'go help build'.
324 For more about specifying packages, see 'go help packages'.
325
326 See also: go build, go get, go clean.
327         `,
328 }
329
330 func runInstall(cmd *Command, args []string) {
331         raceInit()
332         pkgs := packagesForBuild(args)
333
334         for _, p := range pkgs {
335                 if p.Target == "" && (!p.Standard || p.ImportPath != "unsafe") {
336                         if p.cmdline {
337                                 errorf("go install: no install location for .go files listed on command line (GOBIN not set)")
338                         } else if p.ConflictDir != "" {
339                                 errorf("go install: no install location for %s: hidden by %s", p.Dir, p.ConflictDir)
340                         } else {
341                                 errorf("go install: no install location for directory %s outside GOPATH", p.Dir)
342                         }
343                 }
344         }
345         exitIfErrors()
346
347         var b builder
348         b.init()
349         a := &action{}
350         for _, p := range pkgs {
351                 a.deps = append(a.deps, b.action(modeInstall, modeInstall, p))
352         }
353         b.do(a)
354 }
355
356 // Global build parameters (used during package load)
357 var (
358         goarch    string
359         goos      string
360         archChar  string
361         exeSuffix string
362 )
363
364 func init() {
365         goarch = buildContext.GOARCH
366         goos = buildContext.GOOS
367         if goos == "windows" {
368                 exeSuffix = ".exe"
369         }
370         var err error
371         archChar, err = build.ArchChar(goarch)
372         if err != nil {
373                 if _, isgc := buildToolchain.(gcToolchain); isgc {
374                         fatalf("%s", err)
375                 }
376                 // archChar is only required for gcToolchain, if we're using
377                 // another toolchain leave it blank.
378                 archChar = ""
379         }
380 }
381
382 // A builder holds global state about a build.
383 // It does not hold per-package state, because we
384 // build packages in parallel, and the builder is shared.
385 type builder struct {
386         work        string               // the temporary work directory (ends in filepath.Separator)
387         actionCache map[cacheKey]*action // a cache of already-constructed actions
388         mkdirCache  map[string]bool      // a cache of created directories
389         print       func(args ...interface{}) (int, error)
390
391         output    sync.Mutex
392         scriptDir string // current directory in printed script
393
394         exec      sync.Mutex
395         readySema chan bool
396         ready     actionQueue
397 }
398
399 // An action represents a single action in the action graph.
400 type action struct {
401         p          *Package      // the package this action works on
402         deps       []*action     // actions that must happen before this one
403         triggers   []*action     // inverse of deps
404         cgo        *action       // action for cgo binary if needed
405         args       []string      // additional args for runProgram
406         testOutput *bytes.Buffer // test output buffer
407
408         f          func(*builder, *action) error // the action itself (nil = no-op)
409         ignoreFail bool                          // whether to run f even if dependencies fail
410
411         // Generated files, directories.
412         link   bool   // target is executable, not just package
413         pkgdir string // the -I or -L argument to use when importing this package
414         objdir string // directory for intermediate objects
415         objpkg string // the intermediate package .a file created during the action
416         target string // goal of the action: the created package or executable
417
418         // Execution state.
419         pending  int  // number of deps yet to complete
420         priority int  // relative execution priority
421         failed   bool // whether the action failed
422 }
423
424 // cacheKey is the key for the action cache.
425 type cacheKey struct {
426         mode buildMode
427         p    *Package
428 }
429
430 // buildMode specifies the build mode:
431 // are we just building things or also installing the results?
432 type buildMode int
433
434 const (
435         modeBuild buildMode = iota
436         modeInstall
437 )
438
439 var (
440         goroot    = filepath.Clean(runtime.GOROOT())
441         gobin     = os.Getenv("GOBIN")
442         gorootBin = filepath.Join(goroot, "bin")
443         gorootPkg = filepath.Join(goroot, "pkg")
444         gorootSrc = filepath.Join(goroot, "src")
445 )
446
447 func (b *builder) init() {
448         var err error
449         b.print = func(a ...interface{}) (int, error) {
450                 return fmt.Fprint(os.Stderr, a...)
451         }
452         b.actionCache = make(map[cacheKey]*action)
453         b.mkdirCache = make(map[string]bool)
454
455         if buildN {
456                 b.work = "$WORK"
457         } else {
458                 b.work, err = ioutil.TempDir("", "go-build")
459                 if err != nil {
460                         fatalf("%s", err)
461                 }
462                 if buildX || buildWork {
463                         fmt.Fprintf(os.Stderr, "WORK=%s\n", b.work)
464                 }
465                 if !buildWork {
466                         workdir := b.work
467                         atexit(func() { os.RemoveAll(workdir) })
468                 }
469         }
470 }
471
472 // goFilesPackage creates a package for building a collection of Go files
473 // (typically named on the command line).  The target is named p.a for
474 // package p or named after the first Go file for package main.
475 func goFilesPackage(gofiles []string) *Package {
476         // TODO: Remove this restriction.
477         for _, f := range gofiles {
478                 if !strings.HasSuffix(f, ".go") {
479                         fatalf("named files must be .go files")
480                 }
481         }
482
483         var stk importStack
484         ctxt := buildContext
485         ctxt.UseAllFiles = true
486
487         // Synthesize fake "directory" that only shows the named files,
488         // to make it look like this is a standard package or
489         // command directory.  So that local imports resolve
490         // consistently, the files must all be in the same directory.
491         var dirent []os.FileInfo
492         var dir string
493         for _, file := range gofiles {
494                 fi, err := os.Stat(file)
495                 if err != nil {
496                         fatalf("%s", err)
497                 }
498                 if fi.IsDir() {
499                         fatalf("%s is a directory, should be a Go file", file)
500                 }
501                 dir1, _ := filepath.Split(file)
502                 if dir == "" {
503                         dir = dir1
504                 } else if dir != dir1 {
505                         fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
506                 }
507                 dirent = append(dirent, fi)
508         }
509         ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
510
511         var err error
512         if dir == "" {
513                 dir = cwd
514         }
515         dir, err = filepath.Abs(dir)
516         if err != nil {
517                 fatalf("%s", err)
518         }
519
520         bp, err := ctxt.ImportDir(dir, 0)
521         pkg := new(Package)
522         pkg.local = true
523         pkg.cmdline = true
524         pkg.load(&stk, bp, err)
525         pkg.localPrefix = dirToImportPath(dir)
526         pkg.ImportPath = "command-line-arguments"
527         pkg.target = ""
528
529         if pkg.Name == "main" {
530                 _, elem := filepath.Split(gofiles[0])
531                 exe := elem[:len(elem)-len(".go")] + exeSuffix
532                 if *buildO == "" {
533                         *buildO = exe
534                 }
535                 if gobin != "" {
536                         pkg.target = filepath.Join(gobin, exe)
537                 }
538         } else {
539                 if *buildO == "" {
540                         *buildO = pkg.Name + ".a"
541                 }
542         }
543         pkg.Target = pkg.target
544         pkg.Stale = true
545
546         computeStale(pkg)
547         return pkg
548 }
549
550 // action returns the action for applying the given operation (mode) to the package.
551 // depMode is the action to use when building dependencies.
552 func (b *builder) action(mode buildMode, depMode buildMode, p *Package) *action {
553         key := cacheKey{mode, p}
554         a := b.actionCache[key]
555         if a != nil {
556                 return a
557         }
558
559         a = &action{p: p, pkgdir: p.build.PkgRoot}
560         if p.pkgdir != "" { // overrides p.t
561                 a.pkgdir = p.pkgdir
562         }
563
564         b.actionCache[key] = a
565
566         for _, p1 := range p.imports {
567                 a.deps = append(a.deps, b.action(depMode, depMode, p1))
568         }
569
570         // If we are not doing a cross-build, then record the binary we'll
571         // generate for cgo as a dependency of the build of any package
572         // using cgo, to make sure we do not overwrite the binary while
573         // a package is using it.  If this is a cross-build, then the cgo we
574         // are writing is not the cgo we need to use.
575         if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace {
576                 if len(p.CgoFiles) > 0 || p.Standard && p.ImportPath == "runtime/cgo" {
577                         var stk importStack
578                         p1 := loadPackage("cmd/cgo", &stk)
579                         if p1.Error != nil {
580                                 fatalf("load cmd/cgo: %v", p1.Error)
581                         }
582                         a.cgo = b.action(depMode, depMode, p1)
583                         a.deps = append(a.deps, a.cgo)
584                 }
585         }
586
587         if p.Standard {
588                 switch p.ImportPath {
589                 case "builtin", "unsafe":
590                         // Fake packages - nothing to build.
591                         return a
592                 }
593                 // gccgo standard library is "fake" too.
594                 if _, ok := buildToolchain.(gccgoToolchain); ok {
595                         // the target name is needed for cgo.
596                         a.target = p.target
597                         return a
598                 }
599         }
600
601         if !p.Stale && p.target != "" {
602                 // p.Stale==false implies that p.target is up-to-date.
603                 // Record target name for use by actions depending on this one.
604                 a.target = p.target
605                 return a
606         }
607
608         if p.local && p.target == "" {
609                 // Imported via local path.  No permanent target.
610                 mode = modeBuild
611         }
612         work := p.pkgdir
613         if work == "" {
614                 work = b.work
615         }
616         a.objdir = filepath.Join(work, a.p.ImportPath, "_obj") + string(filepath.Separator)
617         a.objpkg = buildToolchain.pkgpath(work, a.p)
618         a.link = p.Name == "main"
619
620         switch mode {
621         case modeInstall:
622                 a.f = (*builder).install
623                 a.deps = []*action{b.action(modeBuild, depMode, p)}
624                 a.target = a.p.target
625         case modeBuild:
626                 a.f = (*builder).build
627                 a.target = a.objpkg
628                 if a.link {
629                         // An executable file. (This is the name of a temporary file.)
630                         // Because we run the temporary file in 'go run' and 'go test',
631                         // the name will show up in ps listings. If the caller has specified
632                         // a name, use that instead of a.out. The binary is generated
633                         // in an otherwise empty subdirectory named exe to avoid
634                         // naming conflicts.  The only possible conflict is if we were
635                         // to create a top-level package named exe.
636                         name := "a.out"
637                         if p.exeName != "" {
638                                 name = p.exeName
639                         }
640                         a.target = a.objdir + filepath.Join("exe", name) + exeSuffix
641                 }
642         }
643
644         return a
645 }
646
647 // actionList returns the list of actions in the dag rooted at root
648 // as visited in a depth-first post-order traversal.
649 func actionList(root *action) []*action {
650         seen := map[*action]bool{}
651         all := []*action{}
652         var walk func(*action)
653         walk = func(a *action) {
654                 if seen[a] {
655                         return
656                 }
657                 seen[a] = true
658                 for _, a1 := range a.deps {
659                         walk(a1)
660                 }
661                 all = append(all, a)
662         }
663         walk(root)
664         return all
665 }
666
667 // do runs the action graph rooted at root.
668 func (b *builder) do(root *action) {
669         // Build list of all actions, assigning depth-first post-order priority.
670         // The original implementation here was a true queue
671         // (using a channel) but it had the effect of getting
672         // distracted by low-level leaf actions to the detriment
673         // of completing higher-level actions.  The order of
674         // work does not matter much to overall execution time,
675         // but when running "go test std" it is nice to see each test
676         // results as soon as possible.  The priorities assigned
677         // ensure that, all else being equal, the execution prefers
678         // to do what it would have done first in a simple depth-first
679         // dependency order traversal.
680         all := actionList(root)
681         for i, a := range all {
682                 a.priority = i
683         }
684
685         b.readySema = make(chan bool, len(all))
686
687         // Initialize per-action execution state.
688         for _, a := range all {
689                 for _, a1 := range a.deps {
690                         a1.triggers = append(a1.triggers, a)
691                 }
692                 a.pending = len(a.deps)
693                 if a.pending == 0 {
694                         b.ready.push(a)
695                         b.readySema <- true
696                 }
697         }
698
699         // Handle runs a single action and takes care of triggering
700         // any actions that are runnable as a result.
701         handle := func(a *action) {
702                 var err error
703                 if a.f != nil && (!a.failed || a.ignoreFail) {
704                         err = a.f(b, a)
705                 }
706
707                 // The actions run in parallel but all the updates to the
708                 // shared work state are serialized through b.exec.
709                 b.exec.Lock()
710                 defer b.exec.Unlock()
711
712                 if err != nil {
713                         if err == errPrintedOutput {
714                                 setExitStatus(2)
715                         } else {
716                                 errorf("%s", err)
717                         }
718                         a.failed = true
719                 }
720
721                 for _, a0 := range a.triggers {
722                         if a.failed {
723                                 a0.failed = true
724                         }
725                         if a0.pending--; a0.pending == 0 {
726                                 b.ready.push(a0)
727                                 b.readySema <- true
728                         }
729                 }
730
731                 if a == root {
732                         close(b.readySema)
733                 }
734         }
735
736         var wg sync.WaitGroup
737
738         // Kick off goroutines according to parallelism.
739         // If we are using the -n flag (just printing commands)
740         // drop the parallelism to 1, both to make the output
741         // deterministic and because there is no real work anyway.
742         par := buildP
743         if buildN {
744                 par = 1
745         }
746         for i := 0; i < par; i++ {
747                 wg.Add(1)
748                 go func() {
749                         defer wg.Done()
750                         for {
751                                 select {
752                                 case _, ok := <-b.readySema:
753                                         if !ok {
754                                                 return
755                                         }
756                                         // Receiving a value from b.readySema entitles
757                                         // us to take from the ready queue.
758                                         b.exec.Lock()
759                                         a := b.ready.pop()
760                                         b.exec.Unlock()
761                                         handle(a)
762                                 case <-interrupted:
763                                         setExitStatus(1)
764                                         return
765                                 }
766                         }
767                 }()
768         }
769
770         wg.Wait()
771 }
772
773 // hasString reports whether s appears in the list of strings.
774 func hasString(strings []string, s string) bool {
775         for _, t := range strings {
776                 if s == t {
777                         return true
778                 }
779         }
780         return false
781 }
782
783 // build is the action for building a single package or command.
784 func (b *builder) build(a *action) (err error) {
785         // Return an error if the package has CXX files but it's not using
786         // cgo nor SWIG, since the CXX files can only be processed by cgo
787         // and SWIG (it's possible to have packages with C files without
788         // using cgo, they will get compiled with the plan9 C compiler and
789         // linked with the rest of the package).
790         if len(a.p.CXXFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
791                 return fmt.Errorf("can't build package %s because it contains C++ files (%s) but it's not using cgo nor SWIG",
792                         a.p.ImportPath, strings.Join(a.p.CXXFiles, ","))
793         }
794         // Same as above for Objective-C files
795         if len(a.p.MFiles) > 0 && !a.p.usesCgo() && !a.p.usesSwig() {
796                 return fmt.Errorf("can't build package %s because it contains Objective-C files (%s) but it's not using cgo nor SWIG",
797                         a.p.ImportPath, strings.Join(a.p.MFiles, ","))
798         }
799         defer func() {
800                 if err != nil && err != errPrintedOutput {
801                         err = fmt.Errorf("go build %s: %v", a.p.ImportPath, err)
802                 }
803         }()
804         if buildN {
805                 // In -n mode, print a banner between packages.
806                 // The banner is five lines so that when changes to
807                 // different sections of the bootstrap script have to
808                 // be merged, the banners give patch something
809                 // to use to find its context.
810                 fmt.Printf("\n#\n# %s\n#\n\n", a.p.ImportPath)
811         }
812
813         if buildV {
814                 fmt.Fprintf(os.Stderr, "%s\n", a.p.ImportPath)
815         }
816
817         if a.p.Standard && a.p.ImportPath == "runtime" && buildContext.Compiler == "gc" &&
818                 (!hasString(a.p.GoFiles, "zgoos_"+buildContext.GOOS+".go") ||
819                         !hasString(a.p.GoFiles, "zgoarch_"+buildContext.GOARCH+".go")) {
820                 return fmt.Errorf("%s/%s must be bootstrapped using make%v", buildContext.GOOS, buildContext.GOARCH, defaultSuffix())
821         }
822
823         // Make build directory.
824         obj := a.objdir
825         if err := b.mkdir(obj); err != nil {
826                 return err
827         }
828
829         // make target directory
830         dir, _ := filepath.Split(a.target)
831         if dir != "" {
832                 if err := b.mkdir(dir); err != nil {
833                         return err
834                 }
835         }
836
837         var gofiles, cfiles, sfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string
838
839         gofiles = append(gofiles, a.p.GoFiles...)
840         cfiles = append(cfiles, a.p.CFiles...)
841         sfiles = append(sfiles, a.p.SFiles...)
842
843         if a.p.usesCgo() || a.p.usesSwig() {
844                 if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.p); err != nil {
845                         return
846                 }
847         }
848         // Run cgo.
849         if a.p.usesCgo() {
850                 // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc.
851                 // There is one exception: runtime/cgo's job is to bridge the
852                 // cgo and non-cgo worlds, so it necessarily has files in both.
853                 // In that case gcc only gets the gcc_* files.
854                 var gccfiles []string
855                 if a.p.Standard && a.p.ImportPath == "runtime/cgo" {
856                         filter := func(files, nongcc, gcc []string) ([]string, []string) {
857                                 for _, f := range files {
858                                         if strings.HasPrefix(f, "gcc_") {
859                                                 gcc = append(gcc, f)
860                                         } else {
861                                                 nongcc = append(nongcc, f)
862                                         }
863                                 }
864                                 return nongcc, gcc
865                         }
866                         cfiles, gccfiles = filter(cfiles, cfiles[:0], gccfiles)
867                         sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles)
868                 } else {
869                         gccfiles = append(cfiles, sfiles...)
870                         cfiles = nil
871                         sfiles = nil
872                 }
873
874                 cgoExe := tool("cgo")
875                 if a.cgo != nil && a.cgo.target != "" {
876                         cgoExe = a.cgo.target
877                 }
878                 outGo, outObj, err := b.cgo(a.p, cgoExe, obj, pcCFLAGS, pcLDFLAGS, gccfiles, a.p.CXXFiles, a.p.MFiles)
879                 if err != nil {
880                         return err
881                 }
882                 cgoObjects = append(cgoObjects, outObj...)
883                 gofiles = append(gofiles, outGo...)
884         }
885
886         // Run SWIG.
887         if a.p.usesSwig() {
888                 // In a package using SWIG, any .c or .s files are
889                 // compiled with gcc.
890                 gccfiles := append(cfiles, sfiles...)
891                 cxxfiles, mfiles := a.p.CXXFiles, a.p.MFiles
892                 cfiles = nil
893                 sfiles = nil
894
895                 // Don't build c/c++ files twice if cgo is enabled (mainly for pkg-config).
896                 if a.p.usesCgo() {
897                         cxxfiles = nil
898                         gccfiles = nil
899                         mfiles = nil
900                 }
901
902                 outGo, outObj, err := b.swig(a.p, obj, pcCFLAGS, gccfiles, cxxfiles, mfiles)
903                 if err != nil {
904                         return err
905                 }
906                 cgoObjects = append(cgoObjects, outObj...)
907                 gofiles = append(gofiles, outGo...)
908         }
909
910         if len(gofiles) == 0 {
911                 return &build.NoGoError{Dir: a.p.Dir}
912         }
913
914         // If we're doing coverage, preprocess the .go files and put them in the work directory
915         if a.p.coverMode != "" {
916                 for i, file := range gofiles {
917                         var sourceFile string
918                         var coverFile string
919                         var key string
920                         if strings.HasSuffix(file, ".cgo1.go") {
921                                 // cgo files have absolute paths
922                                 base := filepath.Base(file)
923                                 sourceFile = file
924                                 coverFile = filepath.Join(obj, base)
925                                 key = strings.TrimSuffix(base, ".cgo1.go") + ".go"
926                         } else {
927                                 sourceFile = filepath.Join(a.p.Dir, file)
928                                 coverFile = filepath.Join(obj, file)
929                                 key = file
930                         }
931                         cover := a.p.coverVars[key]
932                         if cover == nil || isTestFile(file) {
933                                 // Not covering this file.
934                                 continue
935                         }
936                         if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil {
937                                 return err
938                         }
939                         gofiles[i] = coverFile
940                 }
941         }
942
943         // Prepare Go import path list.
944         inc := b.includeArgs("-I", a.deps)
945
946         // Compile Go.
947         ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, len(sfiles) > 0, inc, gofiles)
948         if len(out) > 0 {
949                 b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out))
950                 if err != nil {
951                         return errPrintedOutput
952                 }
953         }
954         if err != nil {
955                 return err
956         }
957         if ofile != a.objpkg {
958                 objects = append(objects, ofile)
959         }
960
961         // Copy .h files named for goos or goarch or goos_goarch
962         // to names using GOOS and GOARCH.
963         // For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h.
964         _goos_goarch := "_" + goos + "_" + goarch
965         _goos := "_" + goos
966         _goarch := "_" + goarch
967         for _, file := range a.p.HFiles {
968                 name, ext := fileExtSplit(file)
969                 switch {
970                 case strings.HasSuffix(name, _goos_goarch):
971                         targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext
972                         if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
973                                 return err
974                         }
975                 case strings.HasSuffix(name, _goarch):
976                         targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext
977                         if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
978                                 return err
979                         }
980                 case strings.HasSuffix(name, _goos):
981                         targ := file[:len(name)-len(_goos)] + "_GOOS." + ext
982                         if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644); err != nil {
983                                 return err
984                         }
985                 }
986         }
987
988         objExt := archChar
989         if _, ok := buildToolchain.(gccgoToolchain); ok {
990                 objExt = "o"
991         }
992
993         for _, file := range cfiles {
994                 out := file[:len(file)-len(".c")] + "." + objExt
995                 if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil {
996                         return err
997                 }
998                 objects = append(objects, out)
999         }
1000
1001         // Assemble .s files.
1002         for _, file := range sfiles {
1003                 out := file[:len(file)-len(".s")] + "." + objExt
1004                 if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil {
1005                         return err
1006                 }
1007                 objects = append(objects, out)
1008         }
1009
1010         // NOTE(rsc): On Windows, it is critically important that the
1011         // gcc-compiled objects (cgoObjects) be listed after the ordinary
1012         // objects in the archive.  I do not know why this is.
1013         // http://golang.org/issue/2601
1014         objects = append(objects, cgoObjects...)
1015
1016         // Add system object files.
1017         for _, syso := range a.p.SysoFiles {
1018                 objects = append(objects, filepath.Join(a.p.Dir, syso))
1019         }
1020
1021         // Pack into archive in obj directory.
1022         // If the Go compiler wrote an archive, we only need to add the
1023         // object files for non-Go sources to the archive.
1024         // If the Go compiler wrote an archive and the package is entirely
1025         // Go sources, there is no pack to execute at all.
1026         if len(objects) > 0 {
1027                 if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil {
1028                         return err
1029                 }
1030         }
1031
1032         // Link if needed.
1033         if a.link {
1034                 // The compiler only cares about direct imports, but the
1035                 // linker needs the whole dependency tree.
1036                 all := actionList(a)
1037                 all = all[:len(all)-1] // drop a
1038                 if err := buildToolchain.ld(b, a.p, a.target, all, a.objpkg, objects); err != nil {
1039                         return err
1040                 }
1041         }
1042
1043         return nil
1044 }
1045
1046 // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
1047 func (b *builder) getPkgConfigFlags(p *Package) (cflags, ldflags []string, err error) {
1048         if pkgs := p.CgoPkgConfig; len(pkgs) > 0 {
1049                 var out []byte
1050                 out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs)
1051                 if err != nil {
1052                         b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out))
1053                         b.print(err.Error() + "\n")
1054                         err = errPrintedOutput
1055                         return
1056                 }
1057                 if len(out) > 0 {
1058                         cflags = strings.Fields(string(out))
1059                 }
1060                 out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs)
1061                 if err != nil {
1062                         b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out))
1063                         b.print(err.Error() + "\n")
1064                         err = errPrintedOutput
1065                         return
1066                 }
1067                 if len(out) > 0 {
1068                         ldflags = strings.Fields(string(out))
1069                 }
1070         }
1071         return
1072 }
1073
1074 // install is the action for installing a single package or executable.
1075 func (b *builder) install(a *action) (err error) {
1076         defer func() {
1077                 if err != nil && err != errPrintedOutput {
1078                         err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err)
1079                 }
1080         }()
1081         a1 := a.deps[0]
1082         perm := os.FileMode(0644)
1083         if a1.link {
1084                 perm = 0755
1085         }
1086
1087         // make target directory
1088         dir, _ := filepath.Split(a.target)
1089         if dir != "" {
1090                 if err := b.mkdir(dir); err != nil {
1091                         return err
1092                 }
1093         }
1094
1095         // remove object dir to keep the amount of
1096         // garbage down in a large build.  On an operating system
1097         // with aggressive buffering, cleaning incrementally like
1098         // this keeps the intermediate objects from hitting the disk.
1099         if !buildWork {
1100                 defer os.RemoveAll(a1.objdir)
1101                 defer os.Remove(a1.target)
1102         }
1103
1104         return b.moveOrCopyFile(a, a.target, a1.target, perm)
1105 }
1106
1107 // includeArgs returns the -I or -L directory list for access
1108 // to the results of the list of actions.
1109 func (b *builder) includeArgs(flag string, all []*action) []string {
1110         inc := []string{}
1111         incMap := map[string]bool{
1112                 b.work:    true, // handled later
1113                 gorootPkg: true,
1114                 "":        true, // ignore empty strings
1115         }
1116
1117         // Look in the temporary space for results of test-specific actions.
1118         // This is the $WORK/my/package/_test directory for the
1119         // package being built, so there are few of these.
1120         for _, a1 := range all {
1121                 if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] {
1122                         incMap[dir] = true
1123                         inc = append(inc, flag, dir)
1124                 }
1125         }
1126
1127         // Also look in $WORK for any non-test packages that have
1128         // been built but not installed.
1129         inc = append(inc, flag, b.work)
1130
1131         // Finally, look in the installed package directories for each action.
1132         for _, a1 := range all {
1133                 if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] {
1134                         incMap[dir] = true
1135                         if _, ok := buildToolchain.(gccgoToolchain); ok {
1136                                 dir = filepath.Join(dir, "gccgo_"+goos+"_"+goarch)
1137                         } else {
1138                                 dir = filepath.Join(dir, goos+"_"+goarch)
1139                                 if buildContext.InstallSuffix != "" {
1140                                         dir += "_" + buildContext.InstallSuffix
1141                                 }
1142                         }
1143                         inc = append(inc, flag, dir)
1144                 }
1145         }
1146
1147         return inc
1148 }
1149
1150 // moveOrCopyFile is like 'mv src dst' or 'cp src dst'.
1151 func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode) error {
1152         if buildN {
1153                 b.showcmd("", "mv %s %s", src, dst)
1154                 return nil
1155         }
1156
1157         // If we can update the mode and rename to the dst, do it.
1158         // Otherwise fall back to standard copy.
1159         if err := os.Chmod(src, perm); err == nil {
1160                 if err := os.Rename(src, dst); err == nil {
1161                         if buildX {
1162                                 b.showcmd("", "mv %s %s", src, dst)
1163                         }
1164                         return nil
1165                 }
1166         }
1167
1168         return b.copyFile(a, dst, src, perm)
1169 }
1170
1171 // copyFile is like 'cp src dst'.
1172 func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode) error {
1173         if buildN || buildX {
1174                 b.showcmd("", "cp %s %s", src, dst)
1175                 if buildN {
1176                         return nil
1177                 }
1178         }
1179
1180         sf, err := os.Open(src)
1181         if err != nil {
1182                 return err
1183         }
1184         defer sf.Close()
1185
1186         // Be careful about removing/overwriting dst.
1187         // Do not remove/overwrite if dst exists and is a directory
1188         // or a non-object file.
1189         if fi, err := os.Stat(dst); err == nil {
1190                 if fi.IsDir() {
1191                         return fmt.Errorf("build output %q already exists and is a directory", dst)
1192                 }
1193                 if !isObject(dst) {
1194                         return fmt.Errorf("build output %q already exists and is not an object file", dst)
1195                 }
1196         }
1197
1198         // On Windows, remove lingering ~ file from last attempt.
1199         if toolIsWindows {
1200                 if _, err := os.Stat(dst + "~"); err == nil {
1201                         os.Remove(dst + "~")
1202                 }
1203         }
1204
1205         os.Remove(dst)
1206         df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1207         if err != nil && toolIsWindows {
1208                 // Windows does not allow deletion of a binary file
1209                 // while it is executing.  Try to move it out of the way.
1210                 // If the move fails, which is likely, we'll try again the
1211                 // next time we do an install of this binary.
1212                 if err := os.Rename(dst, dst+"~"); err == nil {
1213                         os.Remove(dst + "~")
1214                 }
1215                 df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
1216         }
1217         if err != nil {
1218                 return err
1219         }
1220
1221         _, err = io.Copy(df, sf)
1222         df.Close()
1223         if err != nil {
1224                 os.Remove(dst)
1225                 return fmt.Errorf("copying %s to %s: %v", src, dst, err)
1226         }
1227         return nil
1228 }
1229
1230 // cover runs, in effect,
1231 //      go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go
1232 func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error {
1233         return b.run(a.objdir, "cover "+a.p.ImportPath, nil,
1234                 buildToolExec,
1235                 tool("cover"),
1236                 "-mode", a.p.coverMode,
1237                 "-var", varName,
1238                 "-o", dst,
1239                 src)
1240 }
1241
1242 var objectMagic = [][]byte{
1243         {'!', '<', 'a', 'r', 'c', 'h', '>', '\n'},        // Package archive
1244         {'\x7F', 'E', 'L', 'F'},                          // ELF
1245         {0xFE, 0xED, 0xFA, 0xCE},                         // Mach-O big-endian 32-bit
1246         {0xFE, 0xED, 0xFA, 0xCF},                         // Mach-O big-endian 64-bit
1247         {0xCE, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 32-bit
1248         {0xCF, 0xFA, 0xED, 0xFE},                         // Mach-O little-endian 64-bit
1249         {0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x04, 0x00}, // PE (Windows) as generated by 6l/8l
1250         {0x00, 0x00, 0x01, 0xEB},                         // Plan 9 i386
1251         {0x00, 0x00, 0x8a, 0x97},                         // Plan 9 amd64
1252 }
1253
1254 func isObject(s string) bool {
1255         f, err := os.Open(s)
1256         if err != nil {
1257                 return false
1258         }
1259         defer f.Close()
1260         buf := make([]byte, 64)
1261         io.ReadFull(f, buf)
1262         for _, magic := range objectMagic {
1263                 if bytes.HasPrefix(buf, magic) {
1264                         return true
1265                 }
1266         }
1267         return false
1268 }
1269
1270 // fmtcmd formats a command in the manner of fmt.Sprintf but also:
1271 //
1272 //      If dir is non-empty and the script is not in dir right now,
1273 //      fmtcmd inserts "cd dir\n" before the command.
1274 //
1275 //      fmtcmd replaces the value of b.work with $WORK.
1276 //      fmtcmd replaces the value of goroot with $GOROOT.
1277 //      fmtcmd replaces the value of b.gobin with $GOBIN.
1278 //
1279 //      fmtcmd replaces the name of the current directory with dot (.)
1280 //      but only when it is at the beginning of a space-separated token.
1281 //
1282 func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string {
1283         cmd := fmt.Sprintf(format, args...)
1284         if dir != "" && dir != "/" {
1285                 cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:]
1286                 if b.scriptDir != dir {
1287                         b.scriptDir = dir
1288                         cmd = "cd " + dir + "\n" + cmd
1289                 }
1290         }
1291         if b.work != "" {
1292                 cmd = strings.Replace(cmd, b.work, "$WORK", -1)
1293         }
1294         return cmd
1295 }
1296
1297 // showcmd prints the given command to standard output
1298 // for the implementation of -n or -x.
1299 func (b *builder) showcmd(dir string, format string, args ...interface{}) {
1300         b.output.Lock()
1301         defer b.output.Unlock()
1302         b.print(b.fmtcmd(dir, format, args...) + "\n")
1303 }
1304
1305 // showOutput prints "# desc" followed by the given output.
1306 // The output is expected to contain references to 'dir', usually
1307 // the source directory for the package that has failed to build.
1308 // showOutput rewrites mentions of dir with a relative path to dir
1309 // when the relative path is shorter.  This is usually more pleasant.
1310 // For example, if fmt doesn't compile and we are in src/html,
1311 // the output is
1312 //
1313 //      $ go build
1314 //      # fmt
1315 //      ../fmt/print.go:1090: undefined: asdf
1316 //      $
1317 //
1318 // instead of
1319 //
1320 //      $ go build
1321 //      # fmt
1322 //      /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf
1323 //      $
1324 //
1325 // showOutput also replaces references to the work directory with $WORK.
1326 //
1327 func (b *builder) showOutput(dir, desc, out string) {
1328         prefix := "# " + desc
1329         suffix := "\n" + out
1330         if reldir := shortPath(dir); reldir != dir {
1331                 suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1)
1332                 suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1)
1333         }
1334         suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1)
1335
1336         b.output.Lock()
1337         defer b.output.Unlock()
1338         b.print(prefix, suffix)
1339 }
1340
1341 // shortPath returns an absolute or relative name for path, whatever is shorter.
1342 func shortPath(path string) string {
1343         if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) {
1344                 return rel
1345         }
1346         return path
1347 }
1348
1349 // relPaths returns a copy of paths with absolute paths
1350 // made relative to the current directory if they would be shorter.
1351 func relPaths(paths []string) []string {
1352         var out []string
1353         pwd, _ := os.Getwd()
1354         for _, p := range paths {
1355                 rel, err := filepath.Rel(pwd, p)
1356                 if err == nil && len(rel) < len(p) {
1357                         p = rel
1358                 }
1359                 out = append(out, p)
1360         }
1361         return out
1362 }
1363
1364 // errPrintedOutput is a special error indicating that a command failed
1365 // but that it generated output as well, and that output has already
1366 // been printed, so there's no point showing 'exit status 1' or whatever
1367 // the wait status was.  The main executor, builder.do, knows not to
1368 // print this error.
1369 var errPrintedOutput = errors.New("already printed output - no need to show error")
1370
1371 var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`)
1372 var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`)
1373
1374 // run runs the command given by cmdline in the directory dir.
1375 // If the command fails, run prints information about the failure
1376 // and returns a non-nil error.
1377 func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error {
1378         out, err := b.runOut(dir, desc, env, cmdargs...)
1379         if len(out) > 0 {
1380                 if desc == "" {
1381                         desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " "))
1382                 }
1383                 b.showOutput(dir, desc, b.processOutput(out))
1384                 if err != nil {
1385                         err = errPrintedOutput
1386                 }
1387         }
1388         return err
1389 }
1390
1391 // processOutput prepares the output of runOut to be output to the console.
1392 func (b *builder) processOutput(out []byte) string {
1393         if out[len(out)-1] != '\n' {
1394                 out = append(out, '\n')
1395         }
1396         messages := string(out)
1397         // Fix up output referring to cgo-generated code to be more readable.
1398         // Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19.
1399         // Replace *[100]_Ctype_foo with *[100]C.foo.
1400         // If we're using -x, assume we're debugging and want the full dump, so disable the rewrite.
1401         if !buildX && cgoLine.MatchString(messages) {
1402                 messages = cgoLine.ReplaceAllString(messages, "")
1403                 messages = cgoTypeSigRe.ReplaceAllString(messages, "C.")
1404         }
1405         return messages
1406 }
1407
1408 // runOut runs the command given by cmdline in the directory dir.
1409 // It returns the command output and any errors that occurred.
1410 func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) {
1411         cmdline := stringList(cmdargs...)
1412         if buildN || buildX {
1413                 var envcmdline string
1414                 for i := range env {
1415                         envcmdline += env[i]
1416                         envcmdline += " "
1417                 }
1418                 envcmdline += joinUnambiguously(cmdline)
1419                 b.showcmd(dir, "%s", envcmdline)
1420                 if buildN {
1421                         return nil, nil
1422                 }
1423         }
1424
1425         nbusy := 0
1426         for {
1427                 var buf bytes.Buffer
1428                 cmd := exec.Command(cmdline[0], cmdline[1:]...)
1429                 cmd.Stdout = &buf
1430                 cmd.Stderr = &buf
1431                 cmd.Dir = dir
1432                 cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir))
1433                 err := cmd.Run()
1434
1435                 // cmd.Run will fail on Unix if some other process has the binary
1436                 // we want to run open for writing.  This can happen here because
1437                 // we build and install the cgo command and then run it.
1438                 // If another command was kicked off while we were writing the
1439                 // cgo binary, the child process for that command may be holding
1440                 // a reference to the fd, keeping us from running exec.
1441                 //
1442                 // But, you might reasonably wonder, how can this happen?
1443                 // The cgo fd, like all our fds, is close-on-exec, so that we need
1444                 // not worry about other processes inheriting the fd accidentally.
1445                 // The answer is that running a command is fork and exec.
1446                 // A child forked while the cgo fd is open inherits that fd.
1447                 // Until the child has called exec, it holds the fd open and the
1448                 // kernel will not let us run cgo.  Even if the child were to close
1449                 // the fd explicitly, it would still be open from the time of the fork
1450                 // until the time of the explicit close, and the race would remain.
1451                 //
1452                 // On Unix systems, this results in ETXTBSY, which formats
1453                 // as "text file busy".  Rather than hard-code specific error cases,
1454                 // we just look for that string.  If this happens, sleep a little
1455                 // and try again.  We let this happen three times, with increasing
1456                 // sleep lengths: 100+200+400 ms = 0.7 seconds.
1457                 //
1458                 // An alternate solution might be to split the cmd.Run into
1459                 // separate cmd.Start and cmd.Wait, and then use an RWLock
1460                 // to make sure that copyFile only executes when no cmd.Start
1461                 // call is in progress.  However, cmd.Start (really syscall.forkExec)
1462                 // only guarantees that when it returns, the exec is committed to
1463                 // happen and succeed.  It uses a close-on-exec file descriptor
1464                 // itself to determine this, so we know that when cmd.Start returns,
1465                 // at least one close-on-exec file descriptor has been closed.
1466                 // However, we cannot be sure that all of them have been closed,
1467                 // so the program might still encounter ETXTBSY even with such
1468                 // an RWLock.  The race window would be smaller, perhaps, but not
1469                 // guaranteed to be gone.
1470                 //
1471                 // Sleeping when we observe the race seems to be the most reliable
1472                 // option we have.
1473                 //
1474                 // http://golang.org/issue/3001
1475                 //
1476                 if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") {
1477                         time.Sleep(100 * time.Millisecond << uint(nbusy))
1478                         nbusy++
1479                         continue
1480                 }
1481
1482                 // err can be something like 'exit status 1'.
1483                 // Add information about what program was running.
1484                 // Note that if buf.Bytes() is non-empty, the caller usually
1485                 // shows buf.Bytes() and does not print err at all, so the
1486                 // prefix here does not make most output any more verbose.
1487                 if err != nil {
1488                         err = errors.New(cmdline[0] + ": " + err.Error())
1489                 }
1490                 return buf.Bytes(), err
1491         }
1492 }
1493
1494 // joinUnambiguously prints the slice, quoting where necessary to make the
1495 // output unambiguous.
1496 // TODO: See issue 5279. The printing of commands needs a complete redo.
1497 func joinUnambiguously(a []string) string {
1498         var buf bytes.Buffer
1499         for i, s := range a {
1500                 if i > 0 {
1501                         buf.WriteByte(' ')
1502                 }
1503                 q := strconv.Quote(s)
1504                 if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 {
1505                         buf.WriteString(q)
1506                 } else {
1507                         buf.WriteString(s)
1508                 }
1509         }
1510         return buf.String()
1511 }
1512
1513 // mkdir makes the named directory.
1514 func (b *builder) mkdir(dir string) error {
1515         b.exec.Lock()
1516         defer b.exec.Unlock()
1517         // We can be a little aggressive about being
1518         // sure directories exist.  Skip repeated calls.
1519         if b.mkdirCache[dir] {
1520                 return nil
1521         }
1522         b.mkdirCache[dir] = true
1523
1524         if buildN || buildX {
1525                 b.showcmd("", "mkdir -p %s", dir)
1526                 if buildN {
1527                         return nil
1528                 }
1529         }
1530
1531         if err := os.MkdirAll(dir, 0777); err != nil {
1532                 return err
1533         }
1534         return nil
1535 }
1536
1537 // mkAbs returns an absolute path corresponding to
1538 // evaluating f in the directory dir.
1539 // We always pass absolute paths of source files so that
1540 // the error messages will include the full path to a file
1541 // in need of attention.
1542 func mkAbs(dir, f string) string {
1543         // Leave absolute paths alone.
1544         // Also, during -n mode we use the pseudo-directory $WORK
1545         // instead of creating an actual work directory that won't be used.
1546         // Leave paths beginning with $WORK alone too.
1547         if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") {
1548                 return f
1549         }
1550         return filepath.Join(dir, f)
1551 }
1552
1553 type toolchain interface {
1554         // gc runs the compiler in a specific directory on a set of files
1555         // and returns the name of the generated output file.
1556         // The compiler runs in the directory dir.
1557         gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error)
1558         // cc runs the toolchain's C compiler in a directory on a C file
1559         // to produce an output file.
1560         cc(b *builder, p *Package, objdir, ofile, cfile string) error
1561         // asm runs the assembler in a specific directory on a specific file
1562         // to generate the named output file.
1563         asm(b *builder, p *Package, obj, ofile, sfile string) error
1564         // pkgpath builds an appropriate path for a temporary package file.
1565         pkgpath(basedir string, p *Package) string
1566         // pack runs the archive packer in a specific directory to create
1567         // an archive from a set of object files.
1568         // typically it is run in the object directory.
1569         pack(b *builder, p *Package, objDir, afile string, ofiles []string) error
1570         // ld runs the linker to create a package starting at mainpkg.
1571         ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error
1572
1573         compiler() string
1574         linker() string
1575 }
1576
1577 type noToolchain struct{}
1578
1579 func noCompiler() error {
1580         log.Fatalf("unknown compiler %q", buildContext.Compiler)
1581         return nil
1582 }
1583
1584 func (noToolchain) compiler() string {
1585         noCompiler()
1586         return ""
1587 }
1588
1589 func (noToolchain) linker() string {
1590         noCompiler()
1591         return ""
1592 }
1593
1594 func (noToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) {
1595         return "", nil, noCompiler()
1596 }
1597
1598 func (noToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
1599         return noCompiler()
1600 }
1601
1602 func (noToolchain) pkgpath(basedir string, p *Package) string {
1603         noCompiler()
1604         return ""
1605 }
1606
1607 func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
1608         return noCompiler()
1609 }
1610
1611 func (noToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
1612         return noCompiler()
1613 }
1614
1615 func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
1616         return noCompiler()
1617 }
1618
1619 // The Go toolchain.
1620 type gcToolchain struct{}
1621
1622 func (gcToolchain) compiler() string {
1623         return tool(archChar + "g")
1624 }
1625
1626 func (gcToolchain) linker() string {
1627         return tool(archChar + "l")
1628 }
1629
1630 func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
1631         if archive != "" {
1632                 ofile = archive
1633         } else {
1634                 out := "_go_." + archChar
1635                 ofile = obj + out
1636         }
1637
1638         gcargs := []string{"-p", p.ImportPath}
1639         if p.Standard && p.ImportPath == "runtime" {
1640                 // runtime compiles with a special 6g flag to emit
1641                 // additional reflect type data.
1642                 gcargs = append(gcargs, "-+")
1643         }
1644
1645         // If we're giving the compiler the entire package (no C etc files), tell it that,
1646         // so that it can give good error messages about forward declarations.
1647         // Exceptions: a few standard packages have forward declarations for
1648         // pieces supplied behind-the-scenes by package runtime.
1649         extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
1650         if p.Standard {
1651                 switch p.ImportPath {
1652                 case "bytes", "net", "os", "runtime/pprof", "sync", "time":
1653                         extFiles++
1654                 }
1655         }
1656         if extFiles == 0 {
1657                 gcargs = append(gcargs, "-complete")
1658         }
1659         if buildContext.InstallSuffix != "" {
1660                 gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix)
1661         }
1662
1663         args := stringList(buildToolExec, tool(archChar+"g"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs)
1664         if ofile == archive {
1665                 args = append(args, "-pack")
1666         }
1667         if asmhdr {
1668                 args = append(args, "-asmhdr", obj+"go_asm.h")
1669         }
1670         for _, f := range gofiles {
1671                 args = append(args, mkAbs(p.Dir, f))
1672         }
1673
1674         output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
1675         return ofile, output, err
1676 }
1677
1678 func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
1679         // Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files.
1680         inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
1681         sfile = mkAbs(p.Dir, sfile)
1682         return b.run(p.Dir, p.ImportPath, nil, stringList(buildToolExec, tool(archChar+"a"), "-trimpath", b.work, "-I", obj, "-I", inc, "-o", ofile, "-D", "GOOS_"+goos, "-D", "GOARCH_"+goarch, sfile))
1683 }
1684
1685 func (gcToolchain) pkgpath(basedir string, p *Package) string {
1686         end := filepath.FromSlash(p.ImportPath + ".a")
1687         return filepath.Join(basedir, end)
1688 }
1689
1690 func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
1691         var absOfiles []string
1692         for _, f := range ofiles {
1693                 absOfiles = append(absOfiles, mkAbs(objDir, f))
1694         }
1695         cmd := "c"
1696         absAfile := mkAbs(objDir, afile)
1697         appending := false
1698         if _, err := os.Stat(absAfile); err == nil {
1699                 appending = true
1700                 cmd = "r"
1701         }
1702
1703         cmdline := stringList("pack", cmd, absAfile, absOfiles)
1704
1705         if appending {
1706                 if buildN || buildX {
1707                         b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline))
1708                 }
1709                 if buildN {
1710                         return nil
1711                 }
1712                 if err := packInternal(b, absAfile, absOfiles); err != nil {
1713                         b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n")
1714                         return errPrintedOutput
1715                 }
1716                 return nil
1717         }
1718
1719         // Need actual pack.
1720         cmdline[0] = tool("pack")
1721         return b.run(p.Dir, p.ImportPath, nil, buildToolExec, cmdline)
1722 }
1723
1724 func packInternal(b *builder, afile string, ofiles []string) error {
1725         dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0)
1726         if err != nil {
1727                 return err
1728         }
1729         defer dst.Close() // only for error returns or panics
1730         w := bufio.NewWriter(dst)
1731
1732         for _, ofile := range ofiles {
1733                 src, err := os.Open(ofile)
1734                 if err != nil {
1735                         return err
1736                 }
1737                 fi, err := src.Stat()
1738                 if err != nil {
1739                         src.Close()
1740                         return err
1741                 }
1742                 // Note: Not using %-16.16s format because we care
1743                 // about bytes, not runes.
1744                 name := fi.Name()
1745                 if len(name) > 16 {
1746                         name = name[:16]
1747                 } else {
1748                         name += strings.Repeat(" ", 16-len(name))
1749                 }
1750                 size := fi.Size()
1751                 fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n",
1752                         name, 0, 0, 0, 0644, size)
1753                 n, err := io.Copy(w, src)
1754                 src.Close()
1755                 if err == nil && n < size {
1756                         err = io.ErrUnexpectedEOF
1757                 } else if err == nil && n > size {
1758                         err = fmt.Errorf("file larger than size reported by stat")
1759                 }
1760                 if err != nil {
1761                         return fmt.Errorf("copying %s to %s: %v", ofile, afile, err)
1762                 }
1763                 if size&1 != 0 {
1764                         w.WriteByte(0)
1765                 }
1766         }
1767
1768         if err := w.Flush(); err != nil {
1769                 return err
1770         }
1771         return dst.Close()
1772 }
1773
1774 func (gcToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
1775         importArgs := b.includeArgs("-L", allactions)
1776         cxx := len(p.CXXFiles) > 0
1777         for _, a := range allactions {
1778                 if a.p != nil && len(a.p.CXXFiles) > 0 {
1779                         cxx = true
1780                 }
1781         }
1782         var ldflags []string
1783         if buildContext.InstallSuffix != "" {
1784                 ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix)
1785         }
1786         if p.omitDWARF {
1787                 ldflags = append(ldflags, "-w")
1788         }
1789
1790         // If the user has not specified the -extld option, then specify the
1791         // appropriate linker. In case of C++ code, use the compiler named
1792         // by the CXX environment variable or defaultCXX if CXX is not set.
1793         // Else, use the CC environment variable and defaultCC as fallback.
1794         extld := false
1795         for _, f := range ldflags {
1796                 if f == "-extld" || strings.HasPrefix(f, "-extld=") {
1797                         extld = true
1798                         break
1799                 }
1800         }
1801         if !extld {
1802                 var compiler []string
1803                 if cxx {
1804                         compiler = envList("CXX", defaultCXX)
1805                 } else {
1806                         compiler = envList("CC", defaultCC)
1807                 }
1808                 ldflags = append(ldflags, "-extld="+compiler[0])
1809                 if len(compiler) > 1 {
1810                         extldflags := false
1811                         add := strings.Join(compiler[1:], " ")
1812                         for i, f := range ldflags {
1813                                 if f == "-extldflags" && i+1 < len(ldflags) {
1814                                         ldflags[i+1] = add + " " + ldflags[i+1]
1815                                         extldflags = true
1816                                         break
1817                                 } else if strings.HasPrefix(f, "-extldflags=") {
1818                                         ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):]
1819                                         extldflags = true
1820                                         break
1821                                 }
1822                         }
1823                         if !extldflags {
1824                                 ldflags = append(ldflags, "-extldflags="+add)
1825                         }
1826                 }
1827         }
1828         ldflags = append(ldflags, buildLdflags...)
1829         return b.run(".", p.ImportPath, nil, stringList(buildToolExec, tool(archChar+"l"), "-o", out, importArgs, ldflags, mainpkg))
1830 }
1831
1832 func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
1833         return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile))
1834 }
1835
1836 // The Gccgo toolchain.
1837 type gccgoToolchain struct{}
1838
1839 var gccgoName, gccgoBin string
1840
1841 func init() {
1842         gccgoName = os.Getenv("GCCGO")
1843         if gccgoName == "" {
1844                 gccgoName = "gccgo"
1845         }
1846         gccgoBin, _ = exec.LookPath(gccgoName)
1847 }
1848
1849 func (gccgoToolchain) compiler() string {
1850         return gccgoBin
1851 }
1852
1853 func (gccgoToolchain) linker() string {
1854         return gccgoBin
1855 }
1856
1857 func (gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) {
1858         out := "_go_.o"
1859         ofile = obj + out
1860         gcargs := []string{"-g"}
1861         gcargs = append(gcargs, b.gccArchArgs()...)
1862         if pkgpath := gccgoPkgpath(p); pkgpath != "" {
1863                 gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath)
1864         }
1865         if p.localPrefix != "" {
1866                 gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix)
1867         }
1868         args := stringList(gccgoName, importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags)
1869         for _, f := range gofiles {
1870                 args = append(args, mkAbs(p.Dir, f))
1871         }
1872
1873         output, err = b.runOut(p.Dir, p.ImportPath, nil, args)
1874         return ofile, output, err
1875 }
1876
1877 func (gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error {
1878         sfile = mkAbs(p.Dir, sfile)
1879         defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
1880         if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
1881                 defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
1882         }
1883         defs = append(defs, b.gccArchArgs()...)
1884         return b.run(p.Dir, p.ImportPath, nil, gccgoName, "-I", obj, "-o", ofile, defs, sfile)
1885 }
1886
1887 func (gccgoToolchain) pkgpath(basedir string, p *Package) string {
1888         end := filepath.FromSlash(p.ImportPath + ".a")
1889         afile := filepath.Join(basedir, end)
1890         // add "lib" to the final element
1891         return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile))
1892 }
1893
1894 func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error {
1895         var absOfiles []string
1896         for _, f := range ofiles {
1897                 absOfiles = append(absOfiles, mkAbs(objDir, f))
1898         }
1899         return b.run(p.Dir, p.ImportPath, nil, "ar", "cru", mkAbs(objDir, afile), absOfiles)
1900 }
1901
1902 func (tools gccgoToolchain) ld(b *builder, p *Package, out string, allactions []*action, mainpkg string, ofiles []string) error {
1903         // gccgo needs explicit linking with all package dependencies,
1904         // and all LDFLAGS from cgo dependencies.
1905         afiles := []string{}
1906         ldflags := b.gccArchArgs()
1907         cgoldflags := []string{}
1908         usesCgo := false
1909         cxx := len(p.CXXFiles) > 0
1910         objc := len(p.MFiles) > 0
1911
1912         // For a given package import path:
1913         //   1) prefer a test package (created by (*builder).test) to a non-test package
1914         //   2) prefer the output of an install action to the output of a build action
1915         //      because the install action will delete the output of the build
1916         //      action
1917         // Iterating over the list backwards (reverse dependency order) ensures that we
1918         // always see an install before a build.
1919         importPathsSeen := make(map[string]bool)
1920         for i := len(allactions) - 1; i >= 0; i-- {
1921                 a := allactions[i]
1922                 if a.p.fake && !importPathsSeen[a.p.ImportPath] {
1923                         importPathsSeen[a.p.ImportPath] = true
1924                         afiles = append(afiles, a.target)
1925                 }
1926         }
1927         for i := len(allactions) - 1; i >= 0; i-- {
1928                 a := allactions[i]
1929                 if !a.p.Standard && !importPathsSeen[a.p.ImportPath] {
1930                         importPathsSeen[a.p.ImportPath] = true
1931                         afiles = append(afiles, a.target)
1932                 }
1933         }
1934
1935         for _, a := range allactions {
1936                 cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...)
1937                 if len(a.p.CgoFiles) > 0 {
1938                         usesCgo = true
1939                 }
1940                 if a.p.usesSwig() {
1941                         usesCgo = true
1942                 }
1943                 if len(a.p.CXXFiles) > 0 {
1944                         cxx = true
1945                 }
1946                 if len(a.p.MFiles) > 0 {
1947                         objc = true
1948                 }
1949         }
1950         ldflags = append(ldflags, afiles...)
1951         ldflags = append(ldflags, cgoldflags...)
1952         ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...)
1953         ldflags = append(ldflags, p.CgoLDFLAGS...)
1954         if usesCgo && goos == "linux" {
1955                 ldflags = append(ldflags, "-Wl,-E")
1956         }
1957         if cxx {
1958                 ldflags = append(ldflags, "-lstdc++")
1959         }
1960         if objc {
1961                 ldflags = append(ldflags, "-lobjc")
1962         }
1963         return b.run(".", p.ImportPath, nil, gccgoName, "-o", out, ofiles, "-Wl,-(", ldflags, "-Wl,-)", buildGccgoflags)
1964 }
1965
1966 func (gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error {
1967         inc := filepath.Join(goroot, "pkg", fmt.Sprintf("%s_%s", goos, goarch))
1968         cfile = mkAbs(p.Dir, cfile)
1969         defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch}
1970         defs = append(defs, b.gccArchArgs()...)
1971         if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" {
1972                 defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`)
1973         }
1974         return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g",
1975                 "-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile)
1976 }
1977
1978 func gccgoPkgpath(p *Package) string {
1979         if p.build.IsCommand() && !p.forceLibrary {
1980                 return ""
1981         }
1982         return p.ImportPath
1983 }
1984
1985 func gccgoCleanPkgpath(p *Package) string {
1986         clean := func(r rune) rune {
1987                 switch {
1988                 case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z',
1989                         '0' <= r && r <= '9':
1990                         return r
1991                 }
1992                 return '_'
1993         }
1994         return strings.Map(clean, gccgoPkgpath(p))
1995 }
1996
1997 // libgcc returns the filename for libgcc, as determined by invoking gcc with
1998 // the -print-libgcc-file-name option.
1999 func (b *builder) libgcc(p *Package) (string, error) {
2000         var buf bytes.Buffer
2001
2002         gccCmd := b.gccCmd(p.Dir)
2003
2004         prev := b.print
2005         if buildN {
2006                 // In -n mode we temporarily swap out the builder's
2007                 // print function to capture the command-line. This
2008                 // let's us assign it to $LIBGCC and produce a valid
2009                 // buildscript for cgo packages.
2010                 b.print = func(a ...interface{}) (int, error) {
2011                         return fmt.Fprint(&buf, a...)
2012                 }
2013         }
2014         f, err := b.runOut(p.Dir, p.ImportPath, nil, gccCmd, "-print-libgcc-file-name")
2015         if err != nil {
2016                 return "", fmt.Errorf("gcc -print-libgcc-file-name: %v (%s)", err, f)
2017         }
2018         if buildN {
2019                 s := fmt.Sprintf("LIBGCC=$(%s)\n", buf.Next(buf.Len()-1))
2020                 b.print = prev
2021                 b.print(s)
2022                 return "$LIBGCC", nil
2023         }
2024
2025         // The compiler might not be able to find libgcc, and in that case,
2026         // it will simply return "libgcc.a", which is of no use to us.
2027         if !filepath.IsAbs(string(f)) {
2028                 return "", nil
2029         }
2030
2031         return strings.Trim(string(f), "\r\n"), nil
2032 }
2033
2034 // gcc runs the gcc C compiler to create an object from a single C file.
2035 func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error {
2036         return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir))
2037 }
2038
2039 // gxx runs the g++ C++ compiler to create an object from a single C++ file.
2040 func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error {
2041         return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir))
2042 }
2043
2044 // ccompile runs the given C or C++ compiler and creates an object from a single source file.
2045 func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error {
2046         file = mkAbs(p.Dir, file)
2047         return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file)
2048 }
2049
2050 // gccld runs the gcc linker to create an executable from a set of object files.
2051 func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error {
2052         var cmd []string
2053         if len(p.CXXFiles) > 0 {
2054                 cmd = b.gxxCmd(p.Dir)
2055         } else {
2056                 cmd = b.gccCmd(p.Dir)
2057         }
2058         return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags)
2059 }
2060
2061 // gccCmd returns a gcc command line prefix
2062 // defaultCC is defined in zdefaultcc.go, written by cmd/dist.
2063 func (b *builder) gccCmd(objdir string) []string {
2064         return b.ccompilerCmd("CC", defaultCC, objdir)
2065 }
2066
2067 // gxxCmd returns a g++ command line prefix
2068 // defaultCXX is defined in zdefaultcc.go, written by cmd/dist.
2069 func (b *builder) gxxCmd(objdir string) []string {
2070         return b.ccompilerCmd("CXX", defaultCXX, objdir)
2071 }
2072
2073 // ccompilerCmd returns a command line prefix for the given environment
2074 // variable and using the default command when the variable is empty.
2075 func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string {
2076         // NOTE: env.go's mkEnv knows that the first three
2077         // strings returned are "gcc", "-I", objdir (and cuts them off).
2078
2079         compiler := envList(envvar, defcmd)
2080         a := []string{compiler[0], "-I", objdir}
2081         a = append(a, compiler[1:]...)
2082
2083         // Definitely want -fPIC but on Windows gcc complains
2084         // "-fPIC ignored for target (all code is position independent)"
2085         if goos != "windows" {
2086                 a = append(a, "-fPIC")
2087         }
2088         a = append(a, b.gccArchArgs()...)
2089         // gcc-4.5 and beyond require explicit "-pthread" flag
2090         // for multithreading with pthread library.
2091         if buildContext.CgoEnabled {
2092                 switch goos {
2093                 case "windows":
2094                         a = append(a, "-mthreads")
2095                 default:
2096                         a = append(a, "-pthread")
2097                 }
2098         }
2099
2100         if strings.Contains(a[0], "clang") {
2101                 // disable ASCII art in clang errors, if possible
2102                 a = append(a, "-fno-caret-diagnostics")
2103                 // clang is too smart about command-line arguments
2104                 a = append(a, "-Qunused-arguments")
2105         }
2106
2107         // disable word wrapping in error messages
2108         a = append(a, "-fmessage-length=0")
2109
2110         // On OS X, some of the compilers behave as if -fno-common
2111         // is always set, and the Mach-O linker in 6l/8l assumes this.
2112         // See http://golang.org/issue/3253.
2113         if goos == "darwin" {
2114                 a = append(a, "-fno-common")
2115         }
2116
2117         return a
2118 }
2119
2120 // gccArchArgs returns arguments to pass to gcc based on the architecture.
2121 func (b *builder) gccArchArgs() []string {
2122         switch archChar {
2123         case "8":
2124                 return []string{"-m32"}
2125         case "6":
2126                 return []string{"-m64"}
2127         case "5":
2128                 return []string{"-marm"} // not thumb
2129         }
2130         return nil
2131 }
2132
2133 // envList returns the value of the given environment variable broken
2134 // into fields, using the default value when the variable is empty.
2135 func envList(key, def string) []string {
2136         v := os.Getenv(key)
2137         if v == "" {
2138                 v = def
2139         }
2140         return strings.Fields(v)
2141 }
2142
2143 // Return the flags to use when invoking the C or C++ compilers, or cgo.
2144 func (b *builder) cflags(p *Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) {
2145         var defaults string
2146         if def {
2147                 defaults = "-g -O2"
2148         }
2149
2150         cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS)
2151         cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS)
2152         cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS)
2153         ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS)
2154         return
2155 }
2156
2157 var cgoRe = regexp.MustCompile(`[/\\:]`)
2158
2159 var (
2160         cgoLibGccFile     string
2161         cgoLibGccErr      error
2162         cgoLibGccFileOnce sync.Once
2163 )
2164
2165 func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
2166         cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true)
2167         _, cgoexeCFLAGS, _, _ := b.cflags(p, false)
2168         cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...)
2169         cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...)
2170         // If we are compiling Objective-C code, then we need to link against libobjc
2171         if len(mfiles) > 0 {
2172                 cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc")
2173         }
2174
2175         // Allows including _cgo_export.h from .[ch] files in the package.
2176         cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj)
2177
2178         // cgo
2179         // TODO: CGOPKGPATH, CGO_FLAGS?
2180         gofiles := []string{obj + "_cgo_gotypes.go"}
2181         cfiles := []string{"_cgo_main.c", "_cgo_export.c"}
2182         for _, fn := range p.CgoFiles {
2183                 f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
2184                 gofiles = append(gofiles, obj+f+"cgo1.go")
2185                 cfiles = append(cfiles, f+"cgo2.c")
2186         }
2187         defunC := obj + "_cgo_defun.c"
2188
2189         cgoflags := []string{}
2190         // TODO: make cgo not depend on $GOARCH?
2191
2192         objExt := archChar
2193
2194         if p.Standard && p.ImportPath == "runtime/cgo" {
2195                 cgoflags = append(cgoflags, "-import_runtime_cgo=false")
2196         }
2197         if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/cgo") {
2198                 cgoflags = append(cgoflags, "-import_syscall=false")
2199         }
2200
2201         // Update $CGO_LDFLAGS with p.CgoLDFLAGS.
2202         var cgoenv []string
2203         if len(cgoLDFLAGS) > 0 {
2204                 flags := make([]string, len(cgoLDFLAGS))
2205                 for i, f := range cgoLDFLAGS {
2206                         flags[i] = strconv.Quote(f)
2207                 }
2208                 cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")}
2209         }
2210
2211         if _, ok := buildToolchain.(gccgoToolchain); ok {
2212                 cgoflags = append(cgoflags, "-gccgo")
2213                 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
2214                         cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath)
2215                 }
2216                 objExt = "o"
2217         }
2218         if err := b.run(p.Dir, p.ImportPath, cgoenv, buildToolExec, cgoExe, "-objdir", obj, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, p.CgoFiles); err != nil {
2219                 return nil, nil, err
2220         }
2221         outGo = append(outGo, gofiles...)
2222
2223         // cc _cgo_defun.c
2224         _, gccgo := buildToolchain.(gccgoToolchain)
2225         if gccgo {
2226                 defunObj := obj + "_cgo_defun." + objExt
2227                 if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil {
2228                         return nil, nil, err
2229                 }
2230                 outObj = append(outObj, defunObj)
2231         }
2232
2233         // gcc
2234         var linkobj []string
2235
2236         var bareLDFLAGS []string
2237         // filter out -lsomelib, -l somelib, *.{so,dll,dylib}, and (on Darwin) -framework X
2238         for i := 0; i < len(cgoLDFLAGS); i++ {
2239                 f := cgoLDFLAGS[i]
2240                 switch {
2241                 // skip "-lc" or "-l somelib"
2242                 case strings.HasPrefix(f, "-l"):
2243                         if f == "-l" {
2244                                 i++
2245                         }
2246                 // skip "-framework X" on Darwin
2247                 case goos == "darwin" && f == "-framework":
2248                         i++
2249                 // skip "*.{dylib,so,dll}"
2250                 case strings.HasSuffix(f, ".dylib"),
2251                         strings.HasSuffix(f, ".so"),
2252                         strings.HasSuffix(f, ".dll"):
2253                         continue
2254                 // Remove any -fsanitize=foo flags.
2255                 // Otherwise the compiler driver thinks that we are doing final link
2256                 // and links sanitizer runtime into the object file. But we are not doing
2257                 // the final link, we will link the resulting object file again. And
2258                 // so the program ends up with two copies of sanitizer runtime.
2259                 // See issue 8788 for details.
2260                 case strings.HasPrefix(f, "-fsanitize="):
2261                         continue
2262                 default:
2263                         bareLDFLAGS = append(bareLDFLAGS, f)
2264                 }
2265         }
2266
2267         cgoLibGccFileOnce.Do(func() {
2268                 cgoLibGccFile, cgoLibGccErr = b.libgcc(p)
2269         })
2270         if cgoLibGccFile == "" && cgoLibGccErr != nil {
2271                 return nil, nil, err
2272         }
2273
2274         var staticLibs []string
2275         if goos == "windows" {
2276                 // libmingw32 and libmingwex might also use libgcc, so libgcc must come last,
2277                 // and they also have some inter-dependencies, so must use linker groups.
2278                 staticLibs = []string{"-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group"}
2279         }
2280         if cgoLibGccFile != "" {
2281                 staticLibs = append(staticLibs, cgoLibGccFile)
2282         }
2283
2284         cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
2285         for _, cfile := range cfiles {
2286                 ofile := obj + cfile[:len(cfile)-1] + "o"
2287                 if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil {
2288                         return nil, nil, err
2289                 }
2290                 linkobj = append(linkobj, ofile)
2291                 if !strings.HasSuffix(ofile, "_cgo_main.o") {
2292                         outObj = append(outObj, ofile)
2293                 }
2294         }
2295
2296         for _, file := range gccfiles {
2297                 ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
2298                 if err := b.gcc(p, ofile, cflags, file); err != nil {
2299                         return nil, nil, err
2300                 }
2301                 linkobj = append(linkobj, ofile)
2302                 outObj = append(outObj, ofile)
2303         }
2304
2305         cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
2306         for _, file := range gxxfiles {
2307                 // Append .o to the file, just in case the pkg has file.c and file.cpp
2308                 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
2309                 if err := b.gxx(p, ofile, cxxflags, file); err != nil {
2310                         return nil, nil, err
2311                 }
2312                 linkobj = append(linkobj, ofile)
2313                 outObj = append(outObj, ofile)
2314         }
2315
2316         for _, file := range mfiles {
2317                 // Append .o to the file, just in case the pkg has file.c and file.m
2318                 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
2319                 if err := b.gcc(p, ofile, cflags, file); err != nil {
2320                         return nil, nil, err
2321                 }
2322                 linkobj = append(linkobj, ofile)
2323                 outObj = append(outObj, ofile)
2324         }
2325
2326         linkobj = append(linkobj, p.SysoFiles...)
2327         dynobj := obj + "_cgo_.o"
2328         pie := goarch == "arm" && (goos == "linux" || goos == "android")
2329         if pie { // we need to use -pie for Linux/ARM to get accurate imported sym
2330                 cgoLDFLAGS = append(cgoLDFLAGS, "-pie")
2331         }
2332         if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil {
2333                 return nil, nil, err
2334         }
2335         if pie { // but we don't need -pie for normal cgo programs
2336                 cgoLDFLAGS = cgoLDFLAGS[0 : len(cgoLDFLAGS)-1]
2337         }
2338
2339         if _, ok := buildToolchain.(gccgoToolchain); ok {
2340                 // we don't use dynimport when using gccgo.
2341                 return outGo, outObj, nil
2342         }
2343
2344         // cgo -dynimport
2345         importGo := obj + "_cgo_import.go"
2346         cgoflags = []string{}
2347         if p.Standard && p.ImportPath == "runtime/cgo" {
2348                 cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker
2349         }
2350         if err := b.run(p.Dir, p.ImportPath, nil, buildToolExec, cgoExe, "-objdir", obj, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags); err != nil {
2351                 return nil, nil, err
2352         }
2353         outGo = append(outGo, importGo)
2354
2355         ofile := obj + "_all.o"
2356         var gccObjs, nonGccObjs []string
2357         for _, f := range outObj {
2358                 if strings.HasSuffix(f, ".o") {
2359                         gccObjs = append(gccObjs, f)
2360                 } else {
2361                         nonGccObjs = append(nonGccObjs, f)
2362                 }
2363         }
2364         ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs)
2365
2366         // Some systems, such as Ubuntu, always add --build-id to
2367         // every link, but we don't want a build ID since we are
2368         // producing an object file.  On some of those system a plain
2369         // -r (not -Wl,-r) will turn off --build-id, but clang 3.0
2370         // doesn't support a plain -r.  I don't know how to turn off
2371         // --build-id when using clang other than passing a trailing
2372         // --build-id=none.  So that is what we do, but only on
2373         // systems likely to support it, which is to say, systems that
2374         // normally use gold or the GNU linker.
2375         switch goos {
2376         case "android", "dragonfly", "linux", "netbsd":
2377                 ldflags = append(ldflags, "-Wl,--build-id=none")
2378         }
2379
2380         if err := b.gccld(p, ofile, ldflags, gccObjs); err != nil {
2381                 return nil, nil, err
2382         }
2383
2384         // NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows
2385         // must be processed before the gcc-generated objects.
2386         // Put it first.  http://golang.org/issue/2601
2387         outObj = stringList(nonGccObjs, ofile)
2388
2389         return outGo, outObj, nil
2390 }
2391
2392 // Run SWIG on all SWIG input files.
2393 // TODO: Don't build a shared library, once SWIG emits the necessary
2394 // pragmas for external linking.
2395 func (b *builder) swig(p *Package, obj string, pcCFLAGS, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) {
2396         cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
2397         cflags := stringList(cgoCPPFLAGS, cgoCFLAGS)
2398         cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS)
2399
2400         for _, file := range gccfiles {
2401                 ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o"
2402                 if err := b.gcc(p, ofile, cflags, file); err != nil {
2403                         return nil, nil, err
2404                 }
2405                 outObj = append(outObj, ofile)
2406         }
2407
2408         for _, file := range gxxfiles {
2409                 // Append .o to the file, just in case the pkg has file.c and file.cpp
2410                 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
2411                 if err := b.gxx(p, ofile, cxxflags, file); err != nil {
2412                         return nil, nil, err
2413                 }
2414                 outObj = append(outObj, ofile)
2415         }
2416
2417         for _, file := range mfiles {
2418                 // Append .o to the file, just in case the pkg has file.c and file.cpp
2419                 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o"
2420                 if err := b.gcc(p, ofile, cflags, file); err != nil {
2421                         return nil, nil, err
2422                 }
2423                 outObj = append(outObj, ofile)
2424         }
2425
2426         if err := b.swigVersionCheck(); err != nil {
2427                 return nil, nil, err
2428         }
2429
2430         intgosize, err := b.swigIntSize(obj)
2431         if err != nil {
2432                 return nil, nil, err
2433         }
2434
2435         for _, f := range p.SwigFiles {
2436                 goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize)
2437                 if err != nil {
2438                         return nil, nil, err
2439                 }
2440                 if goFile != "" {
2441                         outGo = append(outGo, goFile)
2442                 }
2443                 if objFile != "" {
2444                         outObj = append(outObj, objFile)
2445                 }
2446                 if gccObjFile != "" {
2447                         outObj = append(outObj, gccObjFile)
2448                 }
2449         }
2450         for _, f := range p.SwigCXXFiles {
2451                 goFile, objFile, gccObjFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize)
2452                 if err != nil {
2453                         return nil, nil, err
2454                 }
2455                 if goFile != "" {
2456                         outGo = append(outGo, goFile)
2457                 }
2458                 if objFile != "" {
2459                         outObj = append(outObj, objFile)
2460                 }
2461                 if gccObjFile != "" {
2462                         outObj = append(outObj, gccObjFile)
2463                 }
2464         }
2465         return outGo, outObj, nil
2466 }
2467
2468 // Make sure SWIG is new enough.
2469 var (
2470         swigCheckOnce sync.Once
2471         swigCheck     error
2472 )
2473
2474 func (b *builder) swigDoVersionCheck() error {
2475         out, err := b.runOut("", "", nil, "swig", "-version")
2476         if err != nil {
2477                 return err
2478         }
2479         re := regexp.MustCompile(`[vV]ersion +([\d])`)
2480         matches := re.FindSubmatch(out)
2481         if matches == nil {
2482                 // Can't find version number; hope for the best.
2483                 return nil
2484         }
2485         major, err := strconv.Atoi(string(matches[1]))
2486         if err != nil {
2487                 // Can't find version number; hope for the best.
2488                 return nil
2489         }
2490         if major < 3 {
2491                 return errors.New("must have SWIG version >= 3.0")
2492         }
2493         return nil
2494 }
2495
2496 func (b *builder) swigVersionCheck() error {
2497         swigCheckOnce.Do(func() {
2498                 swigCheck = b.swigDoVersionCheck()
2499         })
2500         return swigCheck
2501 }
2502
2503 // This code fails to build if sizeof(int) <= 32
2504 const swigIntSizeCode = `
2505 package main
2506 const i int = 1 << 32
2507 `
2508
2509 // Determine the size of int on the target system for the -intgosize option
2510 // of swig >= 2.0.9
2511 func (b *builder) swigIntSize(obj string) (intsize string, err error) {
2512         if buildN {
2513                 return "$INTBITS", nil
2514         }
2515         src := filepath.Join(b.work, "swig_intsize.go")
2516         if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0644); err != nil {
2517                 return
2518         }
2519         srcs := []string{src}
2520
2521         p := goFilesPackage(srcs)
2522
2523         if _, _, e := buildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil {
2524                 return "32", nil
2525         }
2526         return "64", nil
2527 }
2528
2529 // Run SWIG on one SWIG input file.
2530 func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outObj, objGccObj string, err error) {
2531         cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true)
2532         var cflags []string
2533         if cxx {
2534                 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS)
2535         } else {
2536                 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS)
2537         }
2538
2539         n := 5 // length of ".swig"
2540         if cxx {
2541                 n = 8 // length of ".swigcxx"
2542         }
2543         base := file[:len(file)-n]
2544         goFile := base + ".go"
2545         cBase := base + "_gc."
2546         gccBase := base + "_wrap."
2547         gccExt := "c"
2548         if cxx {
2549                 gccExt = "cxx"
2550         }
2551
2552         _, gccgo := buildToolchain.(gccgoToolchain)
2553
2554         // swig
2555         args := []string{
2556                 "-go",
2557                 "-intgosize", intgosize,
2558                 "-module", base,
2559                 "-o", obj + gccBase + gccExt,
2560                 "-outdir", obj,
2561         }
2562
2563         for _, f := range cflags {
2564                 if len(f) > 3 && f[:2] == "-I" {
2565                         args = append(args, f)
2566                 }
2567         }
2568
2569         if gccgo {
2570                 args = append(args, "-gccgo")
2571                 if pkgpath := gccgoPkgpath(p); pkgpath != "" {
2572                         args = append(args, "-go-pkgpath", pkgpath)
2573                 }
2574         }
2575         if cxx {
2576                 args = append(args, "-c++")
2577         }
2578
2579         if out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file); err != nil {
2580                 if len(out) > 0 {
2581                         if bytes.Contains(out, []byte("Unrecognized option -intgosize")) {
2582                                 return "", "", "", errors.New("must have SWIG version >= 3.0")
2583                         }
2584                         b.showOutput(p.Dir, p.ImportPath, b.processOutput(out))
2585                         return "", "", "", errPrintedOutput
2586                 }
2587                 return "", "", "", err
2588         }
2589
2590         var cObj string
2591         if !gccgo {
2592                 // cc
2593                 cObj = obj + cBase + archChar
2594                 if err := buildToolchain.cc(b, p, obj, cObj, obj+cBase+"c"); err != nil {
2595                         return "", "", "", err
2596                 }
2597         }
2598
2599         // gcc
2600         gccObj := obj + gccBase + "o"
2601         if !cxx {
2602                 if err := b.gcc(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
2603                         return "", "", "", err
2604                 }
2605         } else {
2606                 if err := b.gxx(p, gccObj, cflags, obj+gccBase+gccExt); err != nil {
2607                         return "", "", "", err
2608                 }
2609         }
2610
2611         return obj + goFile, cObj, gccObj, nil
2612 }
2613
2614 // An actionQueue is a priority queue of actions.
2615 type actionQueue []*action
2616
2617 // Implement heap.Interface
2618 func (q *actionQueue) Len() int           { return len(*q) }
2619 func (q *actionQueue) Swap(i, j int)      { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] }
2620 func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority }
2621 func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) }
2622 func (q *actionQueue) Pop() interface{} {
2623         n := len(*q) - 1
2624         x := (*q)[n]
2625         *q = (*q)[:n]
2626         return x
2627 }
2628
2629 func (q *actionQueue) push(a *action) {
2630         heap.Push(q, a)
2631 }
2632
2633 func (q *actionQueue) pop() *action {
2634         return heap.Pop(q).(*action)
2635 }
2636
2637 func raceInit() {
2638         if !buildRace {
2639                 return
2640         }
2641         if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" {
2642                 fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0])
2643                 os.Exit(2)
2644         }
2645         buildGcflags = append(buildGcflags, "-race")
2646         buildLdflags = append(buildLdflags, "-race")
2647         if buildContext.InstallSuffix != "" {
2648                 buildContext.InstallSuffix += "_"
2649         }
2650         buildContext.InstallSuffix += "race"
2651         buildContext.BuildTags = append(buildContext.BuildTags, "race")
2652 }
2653
2654 // defaultSuffix returns file extension used for command files in
2655 // current os environment.
2656 func defaultSuffix() string {
2657         switch runtime.GOOS {
2658         case "windows":
2659                 return ".bat"
2660         case "plan9":
2661                 return ".rc"
2662         default:
2663                 return ".bash"
2664         }
2665 }