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