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