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