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