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