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