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