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