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