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