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