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