github.com/jonasi/go@v0.0.0-20150930005915-e78e654c1de0/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 if a.p.Standard && a.p.ImportPath == "runtime" && buildContext.Compiler == "gc" && 1239 (!hasString(a.p.GoFiles, "zgoos_"+buildContext.GOOS+".go") || 1240 !hasString(a.p.GoFiles, "zgoarch_"+buildContext.GOARCH+".go")) { 1241 return fmt.Errorf("%s/%s must be bootstrapped using make%v", buildContext.GOOS, buildContext.GOARCH, defaultSuffix()) 1242 } 1243 1244 // Make build directory. 1245 obj := a.objdir 1246 if err := b.mkdir(obj); err != nil { 1247 return err 1248 } 1249 1250 // make target directory 1251 dir, _ := filepath.Split(a.target) 1252 if dir != "" { 1253 if err := b.mkdir(dir); err != nil { 1254 return err 1255 } 1256 } 1257 1258 var gofiles, cgofiles, cfiles, sfiles, cxxfiles, objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string 1259 1260 gofiles = append(gofiles, a.p.GoFiles...) 1261 cgofiles = append(cgofiles, a.p.CgoFiles...) 1262 cfiles = append(cfiles, a.p.CFiles...) 1263 sfiles = append(sfiles, a.p.SFiles...) 1264 cxxfiles = append(cxxfiles, a.p.CXXFiles...) 1265 1266 if a.p.usesCgo() || a.p.usesSwig() { 1267 if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.p); err != nil { 1268 return 1269 } 1270 } 1271 1272 // Run SWIG on each .swig and .swigcxx file. 1273 // Each run will generate two files, a .go file and a .c or .cxx file. 1274 // The .go file will use import "C" and is to be processed by cgo. 1275 if a.p.usesSwig() { 1276 outGo, outC, outCXX, err := b.swig(a.p, obj, pcCFLAGS) 1277 if err != nil { 1278 return err 1279 } 1280 cgofiles = append(cgofiles, outGo...) 1281 cfiles = append(cfiles, outC...) 1282 cxxfiles = append(cxxfiles, outCXX...) 1283 } 1284 1285 // Run cgo. 1286 if a.p.usesCgo() || a.p.usesSwig() { 1287 // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc. 1288 // There is one exception: runtime/cgo's job is to bridge the 1289 // cgo and non-cgo worlds, so it necessarily has files in both. 1290 // In that case gcc only gets the gcc_* files. 1291 var gccfiles []string 1292 if a.p.Standard && a.p.ImportPath == "runtime/cgo" { 1293 filter := func(files, nongcc, gcc []string) ([]string, []string) { 1294 for _, f := range files { 1295 if strings.HasPrefix(f, "gcc_") { 1296 gcc = append(gcc, f) 1297 } else { 1298 nongcc = append(nongcc, f) 1299 } 1300 } 1301 return nongcc, gcc 1302 } 1303 cfiles, gccfiles = filter(cfiles, cfiles[:0], gccfiles) 1304 sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles) 1305 } else { 1306 gccfiles = append(cfiles, sfiles...) 1307 cfiles = nil 1308 sfiles = nil 1309 } 1310 1311 cgoExe := tool("cgo") 1312 if a.cgo != nil && a.cgo.target != "" { 1313 cgoExe = a.cgo.target 1314 } 1315 outGo, outObj, err := b.cgo(a.p, cgoExe, obj, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, cxxfiles, a.p.MFiles) 1316 if err != nil { 1317 return err 1318 } 1319 cgoObjects = append(cgoObjects, outObj...) 1320 gofiles = append(gofiles, outGo...) 1321 } 1322 1323 if len(gofiles) == 0 { 1324 return &build.NoGoError{Dir: a.p.Dir} 1325 } 1326 1327 // If we're doing coverage, preprocess the .go files and put them in the work directory 1328 if a.p.coverMode != "" { 1329 for i, file := range gofiles { 1330 var sourceFile string 1331 var coverFile string 1332 var key string 1333 if strings.HasSuffix(file, ".cgo1.go") { 1334 // cgo files have absolute paths 1335 base := filepath.Base(file) 1336 sourceFile = file 1337 coverFile = filepath.Join(obj, base) 1338 key = strings.TrimSuffix(base, ".cgo1.go") + ".go" 1339 } else { 1340 sourceFile = filepath.Join(a.p.Dir, file) 1341 coverFile = filepath.Join(obj, file) 1342 key = file 1343 } 1344 cover := a.p.coverVars[key] 1345 if cover == nil || isTestFile(file) { 1346 // Not covering this file. 1347 continue 1348 } 1349 if err := b.cover(a, coverFile, sourceFile, 0666, cover.Var); err != nil { 1350 return err 1351 } 1352 gofiles[i] = coverFile 1353 } 1354 } 1355 1356 // Prepare Go import path list. 1357 inc := b.includeArgs("-I", allArchiveActions(a)) 1358 1359 // Compile Go. 1360 ofile, out, err := buildToolchain.gc(b, a.p, a.objpkg, obj, len(sfiles) > 0, inc, gofiles) 1361 if len(out) > 0 { 1362 b.showOutput(a.p.Dir, a.p.ImportPath, b.processOutput(out)) 1363 if err != nil { 1364 return errPrintedOutput 1365 } 1366 } 1367 if err != nil { 1368 return err 1369 } 1370 if ofile != a.objpkg { 1371 objects = append(objects, ofile) 1372 } 1373 1374 // Copy .h files named for goos or goarch or goos_goarch 1375 // to names using GOOS and GOARCH. 1376 // For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h. 1377 _goos_goarch := "_" + goos + "_" + goarch 1378 _goos := "_" + goos 1379 _goarch := "_" + goarch 1380 for _, file := range a.p.HFiles { 1381 name, ext := fileExtSplit(file) 1382 switch { 1383 case strings.HasSuffix(name, _goos_goarch): 1384 targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext 1385 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644, true); err != nil { 1386 return err 1387 } 1388 case strings.HasSuffix(name, _goarch): 1389 targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext 1390 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644, true); err != nil { 1391 return err 1392 } 1393 case strings.HasSuffix(name, _goos): 1394 targ := file[:len(name)-len(_goos)] + "_GOOS." + ext 1395 if err := b.copyFile(a, obj+targ, filepath.Join(a.p.Dir, file), 0644, true); err != nil { 1396 return err 1397 } 1398 } 1399 } 1400 1401 for _, file := range cfiles { 1402 out := file[:len(file)-len(".c")] + ".o" 1403 if err := buildToolchain.cc(b, a.p, obj, obj+out, file); err != nil { 1404 return err 1405 } 1406 objects = append(objects, out) 1407 } 1408 1409 // Assemble .s files. 1410 for _, file := range sfiles { 1411 out := file[:len(file)-len(".s")] + ".o" 1412 if err := buildToolchain.asm(b, a.p, obj, obj+out, file); err != nil { 1413 return err 1414 } 1415 objects = append(objects, out) 1416 } 1417 1418 // NOTE(rsc): On Windows, it is critically important that the 1419 // gcc-compiled objects (cgoObjects) be listed after the ordinary 1420 // objects in the archive. I do not know why this is. 1421 // https://golang.org/issue/2601 1422 objects = append(objects, cgoObjects...) 1423 1424 // Add system object files. 1425 for _, syso := range a.p.SysoFiles { 1426 objects = append(objects, filepath.Join(a.p.Dir, syso)) 1427 } 1428 1429 // Pack into archive in obj directory. 1430 // If the Go compiler wrote an archive, we only need to add the 1431 // object files for non-Go sources to the archive. 1432 // If the Go compiler wrote an archive and the package is entirely 1433 // Go sources, there is no pack to execute at all. 1434 if len(objects) > 0 { 1435 if err := buildToolchain.pack(b, a.p, obj, a.objpkg, objects); err != nil { 1436 return err 1437 } 1438 } 1439 1440 // Link if needed. 1441 if a.link { 1442 // The compiler only cares about direct imports, but the 1443 // linker needs the whole dependency tree. 1444 all := actionList(a) 1445 all = all[:len(all)-1] // drop a 1446 if err := buildToolchain.ld(b, a, a.target, all, a.objpkg, objects); err != nil { 1447 return err 1448 } 1449 } 1450 1451 return nil 1452 } 1453 1454 // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package. 1455 func (b *builder) getPkgConfigFlags(p *Package) (cflags, ldflags []string, err error) { 1456 if pkgs := p.CgoPkgConfig; len(pkgs) > 0 { 1457 var out []byte 1458 out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--cflags", pkgs) 1459 if err != nil { 1460 b.showOutput(p.Dir, "pkg-config --cflags "+strings.Join(pkgs, " "), string(out)) 1461 b.print(err.Error() + "\n") 1462 err = errPrintedOutput 1463 return 1464 } 1465 if len(out) > 0 { 1466 cflags = strings.Fields(string(out)) 1467 } 1468 out, err = b.runOut(p.Dir, p.ImportPath, nil, "pkg-config", "--libs", pkgs) 1469 if err != nil { 1470 b.showOutput(p.Dir, "pkg-config --libs "+strings.Join(pkgs, " "), string(out)) 1471 b.print(err.Error() + "\n") 1472 err = errPrintedOutput 1473 return 1474 } 1475 if len(out) > 0 { 1476 ldflags = strings.Fields(string(out)) 1477 } 1478 } 1479 return 1480 } 1481 1482 func (b *builder) installShlibname(a *action) error { 1483 a1 := a.deps[0] 1484 err := ioutil.WriteFile(a.target, []byte(filepath.Base(a1.target)+"\n"), 0644) 1485 if err != nil { 1486 return err 1487 } 1488 if buildX { 1489 b.showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.target), a.target) 1490 } 1491 return nil 1492 } 1493 1494 func (b *builder) linkShared(a *action) (err error) { 1495 allactions := actionList(a) 1496 allactions = allactions[:len(allactions)-1] 1497 return buildToolchain.ldShared(b, a.deps, a.target, allactions) 1498 } 1499 1500 // install is the action for installing a single package or executable. 1501 func (b *builder) install(a *action) (err error) { 1502 defer func() { 1503 if err != nil && err != errPrintedOutput { 1504 err = fmt.Errorf("go install %s: %v", a.p.ImportPath, err) 1505 } 1506 }() 1507 a1 := a.deps[0] 1508 perm := os.FileMode(0644) 1509 if a1.link { 1510 switch buildBuildmode { 1511 case "c-archive", "c-shared": 1512 default: 1513 perm = 0755 1514 } 1515 } 1516 1517 // make target directory 1518 dir, _ := filepath.Split(a.target) 1519 if dir != "" { 1520 if err := b.mkdir(dir); err != nil { 1521 return err 1522 } 1523 } 1524 1525 // remove object dir to keep the amount of 1526 // garbage down in a large build. On an operating system 1527 // with aggressive buffering, cleaning incrementally like 1528 // this keeps the intermediate objects from hitting the disk. 1529 if !buildWork { 1530 defer os.RemoveAll(a1.objdir) 1531 defer os.Remove(a1.target) 1532 } 1533 1534 return b.moveOrCopyFile(a, a.target, a1.target, perm, false) 1535 } 1536 1537 // includeArgs returns the -I or -L directory list for access 1538 // to the results of the list of actions. 1539 func (b *builder) includeArgs(flag string, all []*action) []string { 1540 inc := []string{} 1541 incMap := map[string]bool{ 1542 b.work: true, // handled later 1543 gorootPkg: true, 1544 "": true, // ignore empty strings 1545 } 1546 1547 // Look in the temporary space for results of test-specific actions. 1548 // This is the $WORK/my/package/_test directory for the 1549 // package being built, so there are few of these. 1550 for _, a1 := range all { 1551 if a1.p == nil { 1552 continue 1553 } 1554 if dir := a1.pkgdir; dir != a1.p.build.PkgRoot && !incMap[dir] { 1555 incMap[dir] = true 1556 inc = append(inc, flag, dir) 1557 } 1558 } 1559 1560 // Also look in $WORK for any non-test packages that have 1561 // been built but not installed. 1562 inc = append(inc, flag, b.work) 1563 1564 // Finally, look in the installed package directories for each action. 1565 for _, a1 := range all { 1566 if a1.p == nil { 1567 continue 1568 } 1569 if dir := a1.pkgdir; dir == a1.p.build.PkgRoot && !incMap[dir] { 1570 incMap[dir] = true 1571 inc = append(inc, flag, a1.p.build.PkgTargetRoot) 1572 } 1573 } 1574 1575 return inc 1576 } 1577 1578 // moveOrCopyFile is like 'mv src dst' or 'cp src dst'. 1579 func (b *builder) moveOrCopyFile(a *action, dst, src string, perm os.FileMode, force bool) error { 1580 if buildN { 1581 b.showcmd("", "mv %s %s", src, dst) 1582 return nil 1583 } 1584 1585 // If we can update the mode and rename to the dst, do it. 1586 // Otherwise fall back to standard copy. 1587 if err := os.Chmod(src, perm); err == nil { 1588 if err := os.Rename(src, dst); err == nil { 1589 if buildX { 1590 b.showcmd("", "mv %s %s", src, dst) 1591 } 1592 return nil 1593 } 1594 } 1595 1596 return b.copyFile(a, dst, src, perm, force) 1597 } 1598 1599 // copyFile is like 'cp src dst'. 1600 func (b *builder) copyFile(a *action, dst, src string, perm os.FileMode, force bool) error { 1601 if buildN || buildX { 1602 b.showcmd("", "cp %s %s", src, dst) 1603 if buildN { 1604 return nil 1605 } 1606 } 1607 1608 sf, err := os.Open(src) 1609 if err != nil { 1610 return err 1611 } 1612 defer sf.Close() 1613 1614 // Be careful about removing/overwriting dst. 1615 // Do not remove/overwrite if dst exists and is a directory 1616 // or a non-object file. 1617 if fi, err := os.Stat(dst); err == nil { 1618 if fi.IsDir() { 1619 return fmt.Errorf("build output %q already exists and is a directory", dst) 1620 } 1621 if !force && !isObject(dst) { 1622 return fmt.Errorf("build output %q already exists and is not an object file", dst) 1623 } 1624 } 1625 1626 // On Windows, remove lingering ~ file from last attempt. 1627 if toolIsWindows { 1628 if _, err := os.Stat(dst + "~"); err == nil { 1629 os.Remove(dst + "~") 1630 } 1631 } 1632 1633 os.Remove(dst) 1634 df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) 1635 if err != nil && toolIsWindows { 1636 // Windows does not allow deletion of a binary file 1637 // while it is executing. Try to move it out of the way. 1638 // If the move fails, which is likely, we'll try again the 1639 // next time we do an install of this binary. 1640 if err := os.Rename(dst, dst+"~"); err == nil { 1641 os.Remove(dst + "~") 1642 } 1643 df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) 1644 } 1645 if err != nil { 1646 return err 1647 } 1648 1649 _, err = io.Copy(df, sf) 1650 df.Close() 1651 if err != nil { 1652 os.Remove(dst) 1653 return fmt.Errorf("copying %s to %s: %v", src, dst, err) 1654 } 1655 return nil 1656 } 1657 1658 // Install the cgo export header file, if there is one. 1659 func (b *builder) installHeader(a *action) error { 1660 src := a.objdir + "_cgo_install.h" 1661 if _, err := os.Stat(src); os.IsNotExist(err) { 1662 // If the file does not exist, there are no exported 1663 // functions, and we do not install anything. 1664 return nil 1665 } 1666 1667 dir, _ := filepath.Split(a.target) 1668 if dir != "" { 1669 if err := b.mkdir(dir); err != nil { 1670 return err 1671 } 1672 } 1673 1674 return b.moveOrCopyFile(a, a.target, src, 0644, true) 1675 } 1676 1677 // cover runs, in effect, 1678 // go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go 1679 func (b *builder) cover(a *action, dst, src string, perm os.FileMode, varName string) error { 1680 return b.run(a.objdir, "cover "+a.p.ImportPath, nil, 1681 buildToolExec, 1682 tool("cover"), 1683 "-mode", a.p.coverMode, 1684 "-var", varName, 1685 "-o", dst, 1686 src) 1687 } 1688 1689 var objectMagic = [][]byte{ 1690 {'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive 1691 {'\x7F', 'E', 'L', 'F'}, // ELF 1692 {0xFE, 0xED, 0xFA, 0xCE}, // Mach-O big-endian 32-bit 1693 {0xFE, 0xED, 0xFA, 0xCF}, // Mach-O big-endian 64-bit 1694 {0xCE, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 32-bit 1695 {0xCF, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 64-bit 1696 {0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00}, // PE (Windows) as generated by 6l/8l and gcc 1697 {0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386 1698 {0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64 1699 } 1700 1701 func isObject(s string) bool { 1702 f, err := os.Open(s) 1703 if err != nil { 1704 return false 1705 } 1706 defer f.Close() 1707 buf := make([]byte, 64) 1708 io.ReadFull(f, buf) 1709 for _, magic := range objectMagic { 1710 if bytes.HasPrefix(buf, magic) { 1711 return true 1712 } 1713 } 1714 return false 1715 } 1716 1717 // fmtcmd formats a command in the manner of fmt.Sprintf but also: 1718 // 1719 // If dir is non-empty and the script is not in dir right now, 1720 // fmtcmd inserts "cd dir\n" before the command. 1721 // 1722 // fmtcmd replaces the value of b.work with $WORK. 1723 // fmtcmd replaces the value of goroot with $GOROOT. 1724 // fmtcmd replaces the value of b.gobin with $GOBIN. 1725 // 1726 // fmtcmd replaces the name of the current directory with dot (.) 1727 // but only when it is at the beginning of a space-separated token. 1728 // 1729 func (b *builder) fmtcmd(dir string, format string, args ...interface{}) string { 1730 cmd := fmt.Sprintf(format, args...) 1731 if dir != "" && dir != "/" { 1732 cmd = strings.Replace(" "+cmd, " "+dir, " .", -1)[1:] 1733 if b.scriptDir != dir { 1734 b.scriptDir = dir 1735 cmd = "cd " + dir + "\n" + cmd 1736 } 1737 } 1738 if b.work != "" { 1739 cmd = strings.Replace(cmd, b.work, "$WORK", -1) 1740 } 1741 return cmd 1742 } 1743 1744 // showcmd prints the given command to standard output 1745 // for the implementation of -n or -x. 1746 func (b *builder) showcmd(dir string, format string, args ...interface{}) { 1747 b.output.Lock() 1748 defer b.output.Unlock() 1749 b.print(b.fmtcmd(dir, format, args...) + "\n") 1750 } 1751 1752 // showOutput prints "# desc" followed by the given output. 1753 // The output is expected to contain references to 'dir', usually 1754 // the source directory for the package that has failed to build. 1755 // showOutput rewrites mentions of dir with a relative path to dir 1756 // when the relative path is shorter. This is usually more pleasant. 1757 // For example, if fmt doesn't compile and we are in src/html, 1758 // the output is 1759 // 1760 // $ go build 1761 // # fmt 1762 // ../fmt/print.go:1090: undefined: asdf 1763 // $ 1764 // 1765 // instead of 1766 // 1767 // $ go build 1768 // # fmt 1769 // /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf 1770 // $ 1771 // 1772 // showOutput also replaces references to the work directory with $WORK. 1773 // 1774 func (b *builder) showOutput(dir, desc, out string) { 1775 prefix := "# " + desc 1776 suffix := "\n" + out 1777 if reldir := shortPath(dir); reldir != dir { 1778 suffix = strings.Replace(suffix, " "+dir, " "+reldir, -1) 1779 suffix = strings.Replace(suffix, "\n"+dir, "\n"+reldir, -1) 1780 } 1781 suffix = strings.Replace(suffix, " "+b.work, " $WORK", -1) 1782 1783 b.output.Lock() 1784 defer b.output.Unlock() 1785 b.print(prefix, suffix) 1786 } 1787 1788 // shortPath returns an absolute or relative name for path, whatever is shorter. 1789 func shortPath(path string) string { 1790 if rel, err := filepath.Rel(cwd, path); err == nil && len(rel) < len(path) { 1791 return rel 1792 } 1793 return path 1794 } 1795 1796 // relPaths returns a copy of paths with absolute paths 1797 // made relative to the current directory if they would be shorter. 1798 func relPaths(paths []string) []string { 1799 var out []string 1800 pwd, _ := os.Getwd() 1801 for _, p := range paths { 1802 rel, err := filepath.Rel(pwd, p) 1803 if err == nil && len(rel) < len(p) { 1804 p = rel 1805 } 1806 out = append(out, p) 1807 } 1808 return out 1809 } 1810 1811 // errPrintedOutput is a special error indicating that a command failed 1812 // but that it generated output as well, and that output has already 1813 // been printed, so there's no point showing 'exit status 1' or whatever 1814 // the wait status was. The main executor, builder.do, knows not to 1815 // print this error. 1816 var errPrintedOutput = errors.New("already printed output - no need to show error") 1817 1818 var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.cgo1\.go:[0-9]+\]`) 1819 var cgoTypeSigRe = regexp.MustCompile(`\b_Ctype_\B`) 1820 1821 // run runs the command given by cmdline in the directory dir. 1822 // If the command fails, run prints information about the failure 1823 // and returns a non-nil error. 1824 func (b *builder) run(dir string, desc string, env []string, cmdargs ...interface{}) error { 1825 out, err := b.runOut(dir, desc, env, cmdargs...) 1826 if len(out) > 0 { 1827 if desc == "" { 1828 desc = b.fmtcmd(dir, "%s", strings.Join(stringList(cmdargs...), " ")) 1829 } 1830 b.showOutput(dir, desc, b.processOutput(out)) 1831 if err != nil { 1832 err = errPrintedOutput 1833 } 1834 } 1835 return err 1836 } 1837 1838 // processOutput prepares the output of runOut to be output to the console. 1839 func (b *builder) processOutput(out []byte) string { 1840 if out[len(out)-1] != '\n' { 1841 out = append(out, '\n') 1842 } 1843 messages := string(out) 1844 // Fix up output referring to cgo-generated code to be more readable. 1845 // Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19. 1846 // Replace *[100]_Ctype_foo with *[100]C.foo. 1847 // If we're using -x, assume we're debugging and want the full dump, so disable the rewrite. 1848 if !buildX && cgoLine.MatchString(messages) { 1849 messages = cgoLine.ReplaceAllString(messages, "") 1850 messages = cgoTypeSigRe.ReplaceAllString(messages, "C.") 1851 } 1852 return messages 1853 } 1854 1855 // runOut runs the command given by cmdline in the directory dir. 1856 // It returns the command output and any errors that occurred. 1857 func (b *builder) runOut(dir string, desc string, env []string, cmdargs ...interface{}) ([]byte, error) { 1858 cmdline := stringList(cmdargs...) 1859 if buildN || buildX { 1860 var envcmdline string 1861 for i := range env { 1862 envcmdline += env[i] 1863 envcmdline += " " 1864 } 1865 envcmdline += joinUnambiguously(cmdline) 1866 b.showcmd(dir, "%s", envcmdline) 1867 if buildN { 1868 return nil, nil 1869 } 1870 } 1871 1872 nbusy := 0 1873 for { 1874 var buf bytes.Buffer 1875 cmd := exec.Command(cmdline[0], cmdline[1:]...) 1876 cmd.Stdout = &buf 1877 cmd.Stderr = &buf 1878 cmd.Dir = dir 1879 cmd.Env = mergeEnvLists(env, envForDir(cmd.Dir, os.Environ())) 1880 err := cmd.Run() 1881 1882 // cmd.Run will fail on Unix if some other process has the binary 1883 // we want to run open for writing. This can happen here because 1884 // we build and install the cgo command and then run it. 1885 // If another command was kicked off while we were writing the 1886 // cgo binary, the child process for that command may be holding 1887 // a reference to the fd, keeping us from running exec. 1888 // 1889 // But, you might reasonably wonder, how can this happen? 1890 // The cgo fd, like all our fds, is close-on-exec, so that we need 1891 // not worry about other processes inheriting the fd accidentally. 1892 // The answer is that running a command is fork and exec. 1893 // A child forked while the cgo fd is open inherits that fd. 1894 // Until the child has called exec, it holds the fd open and the 1895 // kernel will not let us run cgo. Even if the child were to close 1896 // the fd explicitly, it would still be open from the time of the fork 1897 // until the time of the explicit close, and the race would remain. 1898 // 1899 // On Unix systems, this results in ETXTBSY, which formats 1900 // as "text file busy". Rather than hard-code specific error cases, 1901 // we just look for that string. If this happens, sleep a little 1902 // and try again. We let this happen three times, with increasing 1903 // sleep lengths: 100+200+400 ms = 0.7 seconds. 1904 // 1905 // An alternate solution might be to split the cmd.Run into 1906 // separate cmd.Start and cmd.Wait, and then use an RWLock 1907 // to make sure that copyFile only executes when no cmd.Start 1908 // call is in progress. However, cmd.Start (really syscall.forkExec) 1909 // only guarantees that when it returns, the exec is committed to 1910 // happen and succeed. It uses a close-on-exec file descriptor 1911 // itself to determine this, so we know that when cmd.Start returns, 1912 // at least one close-on-exec file descriptor has been closed. 1913 // However, we cannot be sure that all of them have been closed, 1914 // so the program might still encounter ETXTBSY even with such 1915 // an RWLock. The race window would be smaller, perhaps, but not 1916 // guaranteed to be gone. 1917 // 1918 // Sleeping when we observe the race seems to be the most reliable 1919 // option we have. 1920 // 1921 // https://golang.org/issue/3001 1922 // 1923 if err != nil && nbusy < 3 && strings.Contains(err.Error(), "text file busy") { 1924 time.Sleep(100 * time.Millisecond << uint(nbusy)) 1925 nbusy++ 1926 continue 1927 } 1928 1929 // err can be something like 'exit status 1'. 1930 // Add information about what program was running. 1931 // Note that if buf.Bytes() is non-empty, the caller usually 1932 // shows buf.Bytes() and does not print err at all, so the 1933 // prefix here does not make most output any more verbose. 1934 if err != nil { 1935 err = errors.New(cmdline[0] + ": " + err.Error()) 1936 } 1937 return buf.Bytes(), err 1938 } 1939 } 1940 1941 // joinUnambiguously prints the slice, quoting where necessary to make the 1942 // output unambiguous. 1943 // TODO: See issue 5279. The printing of commands needs a complete redo. 1944 func joinUnambiguously(a []string) string { 1945 var buf bytes.Buffer 1946 for i, s := range a { 1947 if i > 0 { 1948 buf.WriteByte(' ') 1949 } 1950 q := strconv.Quote(s) 1951 if s == "" || strings.Contains(s, " ") || len(q) > len(s)+2 { 1952 buf.WriteString(q) 1953 } else { 1954 buf.WriteString(s) 1955 } 1956 } 1957 return buf.String() 1958 } 1959 1960 // mkdir makes the named directory. 1961 func (b *builder) mkdir(dir string) error { 1962 b.exec.Lock() 1963 defer b.exec.Unlock() 1964 // We can be a little aggressive about being 1965 // sure directories exist. Skip repeated calls. 1966 if b.mkdirCache[dir] { 1967 return nil 1968 } 1969 b.mkdirCache[dir] = true 1970 1971 if buildN || buildX { 1972 b.showcmd("", "mkdir -p %s", dir) 1973 if buildN { 1974 return nil 1975 } 1976 } 1977 1978 if err := os.MkdirAll(dir, 0777); err != nil { 1979 return err 1980 } 1981 return nil 1982 } 1983 1984 // mkAbs returns an absolute path corresponding to 1985 // evaluating f in the directory dir. 1986 // We always pass absolute paths of source files so that 1987 // the error messages will include the full path to a file 1988 // in need of attention. 1989 func mkAbs(dir, f string) string { 1990 // Leave absolute paths alone. 1991 // Also, during -n mode we use the pseudo-directory $WORK 1992 // instead of creating an actual work directory that won't be used. 1993 // Leave paths beginning with $WORK alone too. 1994 if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") { 1995 return f 1996 } 1997 return filepath.Join(dir, f) 1998 } 1999 2000 type toolchain interface { 2001 // gc runs the compiler in a specific directory on a set of files 2002 // and returns the name of the generated output file. 2003 // The compiler runs in the directory dir. 2004 gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) 2005 // cc runs the toolchain's C compiler in a directory on a C file 2006 // to produce an output file. 2007 cc(b *builder, p *Package, objdir, ofile, cfile string) error 2008 // asm runs the assembler in a specific directory on a specific file 2009 // to generate the named output file. 2010 asm(b *builder, p *Package, obj, ofile, sfile string) error 2011 // pkgpath builds an appropriate path for a temporary package file. 2012 pkgpath(basedir string, p *Package) string 2013 // pack runs the archive packer in a specific directory to create 2014 // an archive from a set of object files. 2015 // typically it is run in the object directory. 2016 pack(b *builder, p *Package, objDir, afile string, ofiles []string) error 2017 // ld runs the linker to create an executable starting at mainpkg. 2018 ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error 2019 // ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions 2020 ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error 2021 2022 compiler() string 2023 linker() string 2024 } 2025 2026 type noToolchain struct{} 2027 2028 func noCompiler() error { 2029 log.Fatalf("unknown compiler %q", buildContext.Compiler) 2030 return nil 2031 } 2032 2033 func (noToolchain) compiler() string { 2034 noCompiler() 2035 return "" 2036 } 2037 2038 func (noToolchain) linker() string { 2039 noCompiler() 2040 return "" 2041 } 2042 2043 func (noToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, out []byte, err error) { 2044 return "", nil, noCompiler() 2045 } 2046 2047 func (noToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error { 2048 return noCompiler() 2049 } 2050 2051 func (noToolchain) pkgpath(basedir string, p *Package) string { 2052 noCompiler() 2053 return "" 2054 } 2055 2056 func (noToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error { 2057 return noCompiler() 2058 } 2059 2060 func (noToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error { 2061 return noCompiler() 2062 } 2063 2064 func (noToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error { 2065 return noCompiler() 2066 } 2067 2068 func (noToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error { 2069 return noCompiler() 2070 } 2071 2072 // The Go toolchain. 2073 type gcToolchain struct{} 2074 2075 func (gcToolchain) compiler() string { 2076 return tool("compile") 2077 } 2078 2079 func (gcToolchain) linker() string { 2080 return tool("link") 2081 } 2082 2083 func (gcToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) { 2084 if archive != "" { 2085 ofile = archive 2086 } else { 2087 out := "_go_.o" 2088 ofile = obj + out 2089 } 2090 2091 gcargs := []string{"-p", p.ImportPath} 2092 if p.Name == "main" { 2093 gcargs[1] = "main" 2094 } 2095 if p.Standard && p.ImportPath == "runtime" { 2096 // runtime compiles with a special gc flag to emit 2097 // additional reflect type data. 2098 gcargs = append(gcargs, "-+") 2099 } 2100 2101 // If we're giving the compiler the entire package (no C etc files), tell it that, 2102 // so that it can give good error messages about forward declarations. 2103 // Exceptions: a few standard packages have forward declarations for 2104 // pieces supplied behind-the-scenes by package runtime. 2105 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) 2106 if p.Standard { 2107 switch p.ImportPath { 2108 case "bytes", "net", "os", "runtime/pprof", "sync", "time": 2109 extFiles++ 2110 } 2111 } 2112 if extFiles == 0 { 2113 gcargs = append(gcargs, "-complete") 2114 } 2115 if buildContext.InstallSuffix != "" { 2116 gcargs = append(gcargs, "-installsuffix", buildContext.InstallSuffix) 2117 } 2118 if p.buildID != "" { 2119 gcargs = append(gcargs, "-buildid", p.buildID) 2120 } 2121 2122 for _, path := range p.Imports { 2123 if i := strings.LastIndex(path, "/vendor/"); i >= 0 { 2124 gcargs = append(gcargs, "-importmap", path[i+len("/vendor/"):]+"="+path) 2125 } else if strings.HasPrefix(path, "vendor/") { 2126 gcargs = append(gcargs, "-importmap", path[len("vendor/"):]+"="+path) 2127 } 2128 } 2129 2130 args := []interface{}{buildToolExec, tool("compile"), "-o", ofile, "-trimpath", b.work, buildGcflags, gcargs, "-D", p.localPrefix, importArgs} 2131 if ofile == archive { 2132 args = append(args, "-pack") 2133 } 2134 if asmhdr { 2135 args = append(args, "-asmhdr", obj+"go_asm.h") 2136 } 2137 for _, f := range gofiles { 2138 args = append(args, mkAbs(p.Dir, f)) 2139 } 2140 2141 output, err = b.runOut(p.Dir, p.ImportPath, nil, args...) 2142 return ofile, output, err 2143 } 2144 2145 func (gcToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error { 2146 // Add -I pkg/GOOS_GOARCH so #include "textflag.h" works in .s files. 2147 inc := filepath.Join(goroot, "pkg", "include") 2148 sfile = mkAbs(p.Dir, sfile) 2149 args := []interface{}{buildToolExec, tool("asm"), "-o", ofile, "-trimpath", b.work, "-I", obj, "-I", inc, "-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch, buildAsmflags, sfile} 2150 if err := b.run(p.Dir, p.ImportPath, nil, args...); err != nil { 2151 return err 2152 } 2153 return nil 2154 } 2155 2156 // toolVerify checks that the command line args writes the same output file 2157 // if run using newTool instead. 2158 // Unused now but kept around for future use. 2159 func toolVerify(b *builder, p *Package, newTool string, ofile string, args []interface{}) error { 2160 newArgs := make([]interface{}, len(args)) 2161 copy(newArgs, args) 2162 newArgs[1] = tool(newTool) 2163 newArgs[3] = ofile + ".new" // x.6 becomes x.6.new 2164 if err := b.run(p.Dir, p.ImportPath, nil, newArgs...); err != nil { 2165 return err 2166 } 2167 data1, err := ioutil.ReadFile(ofile) 2168 if err != nil { 2169 return err 2170 } 2171 data2, err := ioutil.ReadFile(ofile + ".new") 2172 if err != nil { 2173 return err 2174 } 2175 if !bytes.Equal(data1, data2) { 2176 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...), " ")) 2177 } 2178 os.Remove(ofile + ".new") 2179 return nil 2180 } 2181 2182 func (gcToolchain) pkgpath(basedir string, p *Package) string { 2183 end := filepath.FromSlash(p.ImportPath + ".a") 2184 return filepath.Join(basedir, end) 2185 } 2186 2187 func (gcToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error { 2188 var absOfiles []string 2189 for _, f := range ofiles { 2190 absOfiles = append(absOfiles, mkAbs(objDir, f)) 2191 } 2192 cmd := "c" 2193 absAfile := mkAbs(objDir, afile) 2194 appending := false 2195 if _, err := os.Stat(absAfile); err == nil { 2196 appending = true 2197 cmd = "r" 2198 } 2199 2200 cmdline := stringList("pack", cmd, absAfile, absOfiles) 2201 2202 if appending { 2203 if buildN || buildX { 2204 b.showcmd(p.Dir, "%s # internal", joinUnambiguously(cmdline)) 2205 } 2206 if buildN { 2207 return nil 2208 } 2209 if err := packInternal(b, absAfile, absOfiles); err != nil { 2210 b.showOutput(p.Dir, p.ImportPath, err.Error()+"\n") 2211 return errPrintedOutput 2212 } 2213 return nil 2214 } 2215 2216 // Need actual pack. 2217 cmdline[0] = tool("pack") 2218 return b.run(p.Dir, p.ImportPath, nil, buildToolExec, cmdline) 2219 } 2220 2221 func packInternal(b *builder, afile string, ofiles []string) error { 2222 dst, err := os.OpenFile(afile, os.O_WRONLY|os.O_APPEND, 0) 2223 if err != nil { 2224 return err 2225 } 2226 defer dst.Close() // only for error returns or panics 2227 w := bufio.NewWriter(dst) 2228 2229 for _, ofile := range ofiles { 2230 src, err := os.Open(ofile) 2231 if err != nil { 2232 return err 2233 } 2234 fi, err := src.Stat() 2235 if err != nil { 2236 src.Close() 2237 return err 2238 } 2239 // Note: Not using %-16.16s format because we care 2240 // about bytes, not runes. 2241 name := fi.Name() 2242 if len(name) > 16 { 2243 name = name[:16] 2244 } else { 2245 name += strings.Repeat(" ", 16-len(name)) 2246 } 2247 size := fi.Size() 2248 fmt.Fprintf(w, "%s%-12d%-6d%-6d%-8o%-10d`\n", 2249 name, 0, 0, 0, 0644, size) 2250 n, err := io.Copy(w, src) 2251 src.Close() 2252 if err == nil && n < size { 2253 err = io.ErrUnexpectedEOF 2254 } else if err == nil && n > size { 2255 err = fmt.Errorf("file larger than size reported by stat") 2256 } 2257 if err != nil { 2258 return fmt.Errorf("copying %s to %s: %v", ofile, afile, err) 2259 } 2260 if size&1 != 0 { 2261 w.WriteByte(0) 2262 } 2263 } 2264 2265 if err := w.Flush(); err != nil { 2266 return err 2267 } 2268 return dst.Close() 2269 } 2270 2271 // setextld sets the appropriate linker flags for the specified compiler. 2272 func setextld(ldflags []string, compiler []string) []string { 2273 for _, f := range ldflags { 2274 if f == "-extld" || strings.HasPrefix(f, "-extld=") { 2275 // don't override -extld if supplied 2276 return ldflags 2277 } 2278 } 2279 ldflags = append(ldflags, "-extld="+compiler[0]) 2280 if len(compiler) > 1 { 2281 extldflags := false 2282 add := strings.Join(compiler[1:], " ") 2283 for i, f := range ldflags { 2284 if f == "-extldflags" && i+1 < len(ldflags) { 2285 ldflags[i+1] = add + " " + ldflags[i+1] 2286 extldflags = true 2287 break 2288 } else if strings.HasPrefix(f, "-extldflags=") { 2289 ldflags[i] = "-extldflags=" + add + " " + ldflags[i][len("-extldflags="):] 2290 extldflags = true 2291 break 2292 } 2293 } 2294 if !extldflags { 2295 ldflags = append(ldflags, "-extldflags="+add) 2296 } 2297 } 2298 return ldflags 2299 } 2300 2301 func (gcToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error { 2302 importArgs := b.includeArgs("-L", allactions) 2303 cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0 2304 for _, a := range allactions { 2305 if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) { 2306 cxx = true 2307 } 2308 } 2309 var ldflags []string 2310 if buildContext.InstallSuffix != "" { 2311 ldflags = append(ldflags, "-installsuffix", buildContext.InstallSuffix) 2312 } 2313 if root.p.omitDWARF { 2314 ldflags = append(ldflags, "-w") 2315 } 2316 2317 // If the user has not specified the -extld option, then specify the 2318 // appropriate linker. In case of C++ code, use the compiler named 2319 // by the CXX environment variable or defaultCXX if CXX is not set. 2320 // Else, use the CC environment variable and defaultCC as fallback. 2321 var compiler []string 2322 if cxx { 2323 compiler = envList("CXX", defaultCXX) 2324 } else { 2325 compiler = envList("CC", defaultCC) 2326 } 2327 ldflags = setextld(ldflags, compiler) 2328 ldflags = append(ldflags, "-buildmode="+ldBuildmode) 2329 if root.p.buildID != "" { 2330 ldflags = append(ldflags, "-buildid="+root.p.buildID) 2331 } 2332 ldflags = append(ldflags, buildLdflags...) 2333 2334 // On OS X when using external linking to build a shared library, 2335 // the argument passed here to -o ends up recorded in the final 2336 // shared library in the LC_ID_DYLIB load command. 2337 // To avoid putting the temporary output directory name there 2338 // (and making the resulting shared library useless), 2339 // run the link in the output directory so that -o can name 2340 // just the final path element. 2341 dir := "." 2342 if goos == "darwin" && buildBuildmode == "c-shared" { 2343 dir, out = filepath.Split(out) 2344 } 2345 2346 return b.run(dir, root.p.ImportPath, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags, mainpkg) 2347 } 2348 2349 func (gcToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error { 2350 importArgs := b.includeArgs("-L", allactions) 2351 ldflags := []string{"-installsuffix", buildContext.InstallSuffix} 2352 ldflags = append(ldflags, "-buildmode=shared") 2353 ldflags = append(ldflags, buildLdflags...) 2354 cxx := false 2355 for _, a := range allactions { 2356 if a.p != nil && (len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0) { 2357 cxx = true 2358 } 2359 } 2360 // If the user has not specified the -extld option, then specify the 2361 // appropriate linker. In case of C++ code, use the compiler named 2362 // by the CXX environment variable or defaultCXX if CXX is not set. 2363 // Else, use the CC environment variable and defaultCC as fallback. 2364 var compiler []string 2365 if cxx { 2366 compiler = envList("CXX", defaultCXX) 2367 } else { 2368 compiler = envList("CC", defaultCC) 2369 } 2370 ldflags = setextld(ldflags, compiler) 2371 for _, d := range toplevelactions { 2372 if !strings.HasSuffix(d.target, ".a") { // omit unsafe etc and actions for other shared libraries 2373 continue 2374 } 2375 ldflags = append(ldflags, d.p.ImportPath+"="+d.target) 2376 } 2377 return b.run(".", out, nil, buildToolExec, tool("link"), "-o", out, importArgs, ldflags) 2378 } 2379 2380 func (gcToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error { 2381 return fmt.Errorf("%s: C source files not supported without cgo", mkAbs(p.Dir, cfile)) 2382 } 2383 2384 // The Gccgo toolchain. 2385 type gccgoToolchain struct{} 2386 2387 var gccgoName, gccgoBin string 2388 2389 func init() { 2390 gccgoName = os.Getenv("GCCGO") 2391 if gccgoName == "" { 2392 gccgoName = "gccgo" 2393 } 2394 gccgoBin, _ = exec.LookPath(gccgoName) 2395 } 2396 2397 func (gccgoToolchain) compiler() string { 2398 return gccgoBin 2399 } 2400 2401 func (gccgoToolchain) linker() string { 2402 return gccgoBin 2403 } 2404 2405 func (tools gccgoToolchain) gc(b *builder, p *Package, archive, obj string, asmhdr bool, importArgs []string, gofiles []string) (ofile string, output []byte, err error) { 2406 out := "_go_.o" 2407 ofile = obj + out 2408 gcargs := []string{"-g"} 2409 gcargs = append(gcargs, b.gccArchArgs()...) 2410 if pkgpath := gccgoPkgpath(p); pkgpath != "" { 2411 gcargs = append(gcargs, "-fgo-pkgpath="+pkgpath) 2412 } 2413 if p.localPrefix != "" { 2414 gcargs = append(gcargs, "-fgo-relative-import-path="+p.localPrefix) 2415 } 2416 args := stringList(tools.compiler(), importArgs, "-c", gcargs, "-o", ofile, buildGccgoflags) 2417 for _, f := range gofiles { 2418 args = append(args, mkAbs(p.Dir, f)) 2419 } 2420 2421 output, err = b.runOut(p.Dir, p.ImportPath, nil, args) 2422 return ofile, output, err 2423 } 2424 2425 func (tools gccgoToolchain) asm(b *builder, p *Package, obj, ofile, sfile string) error { 2426 sfile = mkAbs(p.Dir, sfile) 2427 defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch} 2428 if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" { 2429 defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`) 2430 } 2431 defs = tools.maybePIC(defs) 2432 defs = append(defs, b.gccArchArgs()...) 2433 return b.run(p.Dir, p.ImportPath, nil, tools.compiler(), "-I", obj, "-o", ofile, defs, sfile) 2434 } 2435 2436 func (gccgoToolchain) pkgpath(basedir string, p *Package) string { 2437 end := filepath.FromSlash(p.ImportPath + ".a") 2438 afile := filepath.Join(basedir, end) 2439 // add "lib" to the final element 2440 return filepath.Join(filepath.Dir(afile), "lib"+filepath.Base(afile)) 2441 } 2442 2443 func (gccgoToolchain) pack(b *builder, p *Package, objDir, afile string, ofiles []string) error { 2444 var absOfiles []string 2445 for _, f := range ofiles { 2446 absOfiles = append(absOfiles, mkAbs(objDir, f)) 2447 } 2448 return b.run(p.Dir, p.ImportPath, nil, "ar", "cru", mkAbs(objDir, afile), absOfiles) 2449 } 2450 2451 func (tools gccgoToolchain) ld(b *builder, root *action, out string, allactions []*action, mainpkg string, ofiles []string) error { 2452 // gccgo needs explicit linking with all package dependencies, 2453 // and all LDFLAGS from cgo dependencies. 2454 apackagesSeen := make(map[*Package]bool) 2455 afiles := []string{} 2456 shlibs := []string{} 2457 xfiles := []string{} 2458 ldflags := b.gccArchArgs() 2459 cgoldflags := []string{} 2460 usesCgo := false 2461 cxx := len(root.p.CXXFiles) > 0 || len(root.p.SwigCXXFiles) > 0 2462 objc := len(root.p.MFiles) > 0 2463 2464 actionsSeen := make(map[*action]bool) 2465 // Make a pre-order depth-first traversal of the action graph, taking note of 2466 // whether a shared library action has been seen on the way to an action (the 2467 // construction of the graph means that if any path to a node passes through 2468 // a shared library action, they all do). 2469 var walk func(a *action, seenShlib bool) 2470 walk = func(a *action, seenShlib bool) { 2471 if actionsSeen[a] { 2472 return 2473 } 2474 actionsSeen[a] = true 2475 if a.p != nil && !seenShlib { 2476 if a.p.Standard { 2477 return 2478 } 2479 // We record the target of the first time we see a .a file 2480 // for a package to make sure that we prefer the 'install' 2481 // rather than the 'build' location (which may not exist any 2482 // more). We still need to traverse the dependencies of the 2483 // build action though so saying 2484 // if apackagesSeen[a.p] { return } 2485 // doesn't work. 2486 if !apackagesSeen[a.p] { 2487 apackagesSeen[a.p] = true 2488 if a.p.fake && a.p.external { 2489 // external _tests, if present must come before 2490 // internal _tests. Store these on a separate list 2491 // and place them at the head after this loop. 2492 xfiles = append(xfiles, a.target) 2493 } else if a.p.fake { 2494 // move _test files to the top of the link order 2495 afiles = append([]string{a.target}, afiles...) 2496 } else { 2497 afiles = append(afiles, a.target) 2498 } 2499 } 2500 } 2501 if strings.HasSuffix(a.target, ".so") { 2502 shlibs = append(shlibs, a.target) 2503 seenShlib = true 2504 } 2505 for _, a1 := range a.deps { 2506 walk(a1, seenShlib) 2507 } 2508 } 2509 for _, a1 := range root.deps { 2510 walk(a1, false) 2511 } 2512 afiles = append(xfiles, afiles...) 2513 2514 for _, a := range allactions { 2515 // Gather CgoLDFLAGS, but not from standard packages. 2516 // The go tool can dig up runtime/cgo from GOROOT and 2517 // think that it should use its CgoLDFLAGS, but gccgo 2518 // doesn't use runtime/cgo. 2519 if a.p == nil { 2520 continue 2521 } 2522 if !a.p.Standard { 2523 cgoldflags = append(cgoldflags, a.p.CgoLDFLAGS...) 2524 } 2525 if len(a.p.CgoFiles) > 0 { 2526 usesCgo = true 2527 } 2528 if a.p.usesSwig() { 2529 usesCgo = true 2530 } 2531 if len(a.p.CXXFiles) > 0 || len(a.p.SwigCXXFiles) > 0 { 2532 cxx = true 2533 } 2534 if len(a.p.MFiles) > 0 { 2535 objc = true 2536 } 2537 } 2538 2539 switch ldBuildmode { 2540 case "c-archive", "c-shared": 2541 ldflags = append(ldflags, "-Wl,--whole-archive") 2542 } 2543 2544 ldflags = append(ldflags, afiles...) 2545 2546 switch ldBuildmode { 2547 case "c-archive", "c-shared": 2548 ldflags = append(ldflags, "-Wl,--no-whole-archive") 2549 } 2550 2551 ldflags = append(ldflags, cgoldflags...) 2552 ldflags = append(ldflags, envList("CGO_LDFLAGS", "")...) 2553 ldflags = append(ldflags, root.p.CgoLDFLAGS...) 2554 2555 ldflags = stringList("-Wl,-(", ldflags, "-Wl,-)") 2556 2557 for _, shlib := range shlibs { 2558 ldflags = append( 2559 ldflags, 2560 "-L"+filepath.Dir(shlib), 2561 "-Wl,-rpath="+filepath.Dir(shlib), 2562 "-l"+strings.TrimSuffix( 2563 strings.TrimPrefix(filepath.Base(shlib), "lib"), 2564 ".so")) 2565 } 2566 2567 var realOut string 2568 switch ldBuildmode { 2569 case "exe": 2570 if usesCgo && goos == "linux" { 2571 ldflags = append(ldflags, "-Wl,-E") 2572 } 2573 2574 case "c-archive": 2575 // Link the Go files into a single .o, and also link 2576 // in -lgolibbegin. 2577 // 2578 // We need to use --whole-archive with -lgolibbegin 2579 // because it doesn't define any symbols that will 2580 // cause the contents to be pulled in; it's just 2581 // initialization code. 2582 // 2583 // The user remains responsible for linking against 2584 // -lgo -lpthread -lm in the final link. We can't use 2585 // -r to pick them up because we can't combine 2586 // split-stack and non-split-stack code in a single -r 2587 // link, and libgo picks up non-split-stack code from 2588 // libffi. 2589 ldflags = append(ldflags, "-Wl,-r", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive") 2590 2591 // We are creating an object file, so we don't want a build ID. 2592 ldflags = b.disableBuildID(ldflags) 2593 2594 realOut = out 2595 out = out + ".o" 2596 2597 case "c-shared": 2598 ldflags = append(ldflags, "-shared", "-nostdlib", "-Wl,--whole-archive", "-lgolibbegin", "-Wl,--no-whole-archive", "-lgo", "-lgcc_s", "-lgcc") 2599 2600 default: 2601 fatalf("-buildmode=%s not supported for gccgo", ldBuildmode) 2602 } 2603 2604 switch ldBuildmode { 2605 case "exe", "c-shared": 2606 if cxx { 2607 ldflags = append(ldflags, "-lstdc++") 2608 } 2609 if objc { 2610 ldflags = append(ldflags, "-lobjc") 2611 } 2612 } 2613 2614 if err := b.run(".", root.p.ImportPath, nil, tools.linker(), "-o", out, ofiles, ldflags, buildGccgoflags); err != nil { 2615 return err 2616 } 2617 2618 switch ldBuildmode { 2619 case "c-archive": 2620 if err := b.run(".", root.p.ImportPath, nil, "ar", "rc", realOut, out); err != nil { 2621 return err 2622 } 2623 } 2624 return nil 2625 } 2626 2627 func (tools gccgoToolchain) ldShared(b *builder, toplevelactions []*action, out string, allactions []*action) error { 2628 args := []string{"-o", out, "-shared", "-nostdlib", "-zdefs", "-Wl,--whole-archive"} 2629 for _, a := range toplevelactions { 2630 args = append(args, a.target) 2631 } 2632 args = append(args, "-Wl,--no-whole-archive", "-shared", "-nostdlib", "-lgo", "-lgcc_s", "-lgcc", "-lc") 2633 shlibs := []string{} 2634 for _, a := range allactions { 2635 if strings.HasSuffix(a.target, ".so") { 2636 shlibs = append(shlibs, a.target) 2637 } 2638 } 2639 for _, shlib := range shlibs { 2640 args = append( 2641 args, 2642 "-L"+filepath.Dir(shlib), 2643 "-Wl,-rpath="+filepath.Dir(shlib), 2644 "-l"+strings.TrimSuffix( 2645 strings.TrimPrefix(filepath.Base(shlib), "lib"), 2646 ".so")) 2647 } 2648 return b.run(".", out, nil, tools.linker(), args, buildGccgoflags) 2649 } 2650 2651 func (tools gccgoToolchain) cc(b *builder, p *Package, objdir, ofile, cfile string) error { 2652 inc := filepath.Join(goroot, "pkg", "include") 2653 cfile = mkAbs(p.Dir, cfile) 2654 defs := []string{"-D", "GOOS_" + goos, "-D", "GOARCH_" + goarch} 2655 defs = append(defs, b.gccArchArgs()...) 2656 if pkgpath := gccgoCleanPkgpath(p); pkgpath != "" { 2657 defs = append(defs, `-D`, `GOPKGPATH="`+pkgpath+`"`) 2658 } 2659 switch goarch { 2660 case "386", "amd64": 2661 defs = append(defs, "-fsplit-stack") 2662 } 2663 defs = tools.maybePIC(defs) 2664 return b.run(p.Dir, p.ImportPath, nil, envList("CC", defaultCC), "-Wall", "-g", 2665 "-I", objdir, "-I", inc, "-o", ofile, defs, "-c", cfile) 2666 } 2667 2668 // maybePIC adds -fPIC to the list of arguments if needed. 2669 func (tools gccgoToolchain) maybePIC(args []string) []string { 2670 switch buildBuildmode { 2671 case "c-shared", "shared": 2672 args = append(args, "-fPIC") 2673 } 2674 return args 2675 } 2676 2677 func gccgoPkgpath(p *Package) string { 2678 if p.build.IsCommand() && !p.forceLibrary { 2679 return "" 2680 } 2681 return p.ImportPath 2682 } 2683 2684 func gccgoCleanPkgpath(p *Package) string { 2685 clean := func(r rune) rune { 2686 switch { 2687 case 'A' <= r && r <= 'Z', 'a' <= r && r <= 'z', 2688 '0' <= r && r <= '9': 2689 return r 2690 } 2691 return '_' 2692 } 2693 return strings.Map(clean, gccgoPkgpath(p)) 2694 } 2695 2696 // libgcc returns the filename for libgcc, as determined by invoking gcc with 2697 // the -print-libgcc-file-name option. 2698 func (b *builder) libgcc(p *Package) (string, error) { 2699 var buf bytes.Buffer 2700 2701 gccCmd := b.gccCmd(p.Dir) 2702 2703 prev := b.print 2704 if buildN { 2705 // In -n mode we temporarily swap out the builder's 2706 // print function to capture the command-line. This 2707 // let's us assign it to $LIBGCC and produce a valid 2708 // buildscript for cgo packages. 2709 b.print = func(a ...interface{}) (int, error) { 2710 return fmt.Fprint(&buf, a...) 2711 } 2712 } 2713 f, err := b.runOut(p.Dir, p.ImportPath, nil, gccCmd, "-print-libgcc-file-name") 2714 if err != nil { 2715 return "", fmt.Errorf("gcc -print-libgcc-file-name: %v (%s)", err, f) 2716 } 2717 if buildN { 2718 s := fmt.Sprintf("LIBGCC=$(%s)\n", buf.Next(buf.Len()-1)) 2719 b.print = prev 2720 b.print(s) 2721 return "$LIBGCC", nil 2722 } 2723 2724 // The compiler might not be able to find libgcc, and in that case, 2725 // it will simply return "libgcc.a", which is of no use to us. 2726 if !filepath.IsAbs(string(f)) { 2727 return "", nil 2728 } 2729 2730 return strings.Trim(string(f), "\r\n"), nil 2731 } 2732 2733 // gcc runs the gcc C compiler to create an object from a single C file. 2734 func (b *builder) gcc(p *Package, out string, flags []string, cfile string) error { 2735 return b.ccompile(p, out, flags, cfile, b.gccCmd(p.Dir)) 2736 } 2737 2738 // gxx runs the g++ C++ compiler to create an object from a single C++ file. 2739 func (b *builder) gxx(p *Package, out string, flags []string, cxxfile string) error { 2740 return b.ccompile(p, out, flags, cxxfile, b.gxxCmd(p.Dir)) 2741 } 2742 2743 // ccompile runs the given C or C++ compiler and creates an object from a single source file. 2744 func (b *builder) ccompile(p *Package, out string, flags []string, file string, compiler []string) error { 2745 file = mkAbs(p.Dir, file) 2746 return b.run(p.Dir, p.ImportPath, nil, compiler, flags, "-o", out, "-c", file) 2747 } 2748 2749 // gccld runs the gcc linker to create an executable from a set of object files. 2750 func (b *builder) gccld(p *Package, out string, flags []string, obj []string) error { 2751 var cmd []string 2752 if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 { 2753 cmd = b.gxxCmd(p.Dir) 2754 } else { 2755 cmd = b.gccCmd(p.Dir) 2756 } 2757 return b.run(p.Dir, p.ImportPath, nil, cmd, "-o", out, obj, flags) 2758 } 2759 2760 // gccCmd returns a gcc command line prefix 2761 // defaultCC is defined in zdefaultcc.go, written by cmd/dist. 2762 func (b *builder) gccCmd(objdir string) []string { 2763 return b.ccompilerCmd("CC", defaultCC, objdir) 2764 } 2765 2766 // gxxCmd returns a g++ command line prefix 2767 // defaultCXX is defined in zdefaultcc.go, written by cmd/dist. 2768 func (b *builder) gxxCmd(objdir string) []string { 2769 return b.ccompilerCmd("CXX", defaultCXX, objdir) 2770 } 2771 2772 // ccompilerCmd returns a command line prefix for the given environment 2773 // variable and using the default command when the variable is empty. 2774 func (b *builder) ccompilerCmd(envvar, defcmd, objdir string) []string { 2775 // NOTE: env.go's mkEnv knows that the first three 2776 // strings returned are "gcc", "-I", objdir (and cuts them off). 2777 2778 compiler := envList(envvar, defcmd) 2779 a := []string{compiler[0], "-I", objdir} 2780 a = append(a, compiler[1:]...) 2781 2782 // Definitely want -fPIC but on Windows gcc complains 2783 // "-fPIC ignored for target (all code is position independent)" 2784 if goos != "windows" { 2785 a = append(a, "-fPIC") 2786 } 2787 a = append(a, b.gccArchArgs()...) 2788 // gcc-4.5 and beyond require explicit "-pthread" flag 2789 // for multithreading with pthread library. 2790 if buildContext.CgoEnabled { 2791 switch goos { 2792 case "windows": 2793 a = append(a, "-mthreads") 2794 default: 2795 a = append(a, "-pthread") 2796 } 2797 } 2798 2799 if strings.Contains(a[0], "clang") { 2800 // disable ASCII art in clang errors, if possible 2801 a = append(a, "-fno-caret-diagnostics") 2802 // clang is too smart about command-line arguments 2803 a = append(a, "-Qunused-arguments") 2804 } 2805 2806 // disable word wrapping in error messages 2807 a = append(a, "-fmessage-length=0") 2808 2809 // On OS X, some of the compilers behave as if -fno-common 2810 // is always set, and the Mach-O linker in 6l/8l assumes this. 2811 // See https://golang.org/issue/3253. 2812 if goos == "darwin" { 2813 a = append(a, "-fno-common") 2814 } 2815 2816 return a 2817 } 2818 2819 // gccArchArgs returns arguments to pass to gcc based on the architecture. 2820 func (b *builder) gccArchArgs() []string { 2821 switch goarch { 2822 case "386": 2823 return []string{"-m32"} 2824 case "amd64", "amd64p32": 2825 return []string{"-m64"} 2826 case "arm": 2827 return []string{"-marm"} // not thumb 2828 } 2829 return nil 2830 } 2831 2832 // envList returns the value of the given environment variable broken 2833 // into fields, using the default value when the variable is empty. 2834 func envList(key, def string) []string { 2835 v := os.Getenv(key) 2836 if v == "" { 2837 v = def 2838 } 2839 return strings.Fields(v) 2840 } 2841 2842 // Return the flags to use when invoking the C or C++ compilers, or cgo. 2843 func (b *builder) cflags(p *Package, def bool) (cppflags, cflags, cxxflags, ldflags []string) { 2844 var defaults string 2845 if def { 2846 defaults = "-g -O2" 2847 } 2848 2849 cppflags = stringList(envList("CGO_CPPFLAGS", ""), p.CgoCPPFLAGS) 2850 cflags = stringList(envList("CGO_CFLAGS", defaults), p.CgoCFLAGS) 2851 cxxflags = stringList(envList("CGO_CXXFLAGS", defaults), p.CgoCXXFLAGS) 2852 ldflags = stringList(envList("CGO_LDFLAGS", defaults), p.CgoLDFLAGS) 2853 return 2854 } 2855 2856 var cgoRe = regexp.MustCompile(`[/\\:]`) 2857 2858 var ( 2859 cgoLibGccFile string 2860 cgoLibGccErr error 2861 cgoLibGccFileOnce sync.Once 2862 ) 2863 2864 func (b *builder) cgo(p *Package, cgoExe, obj string, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, gxxfiles, mfiles []string) (outGo, outObj []string, err error) { 2865 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoLDFLAGS := b.cflags(p, true) 2866 _, cgoexeCFLAGS, _, _ := b.cflags(p, false) 2867 cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...) 2868 cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...) 2869 // If we are compiling Objective-C code, then we need to link against libobjc 2870 if len(mfiles) > 0 { 2871 cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc") 2872 } 2873 2874 // Allows including _cgo_export.h from .[ch] files in the package. 2875 cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", obj) 2876 2877 // cgo 2878 // TODO: CGOPKGPATH, CGO_FLAGS? 2879 gofiles := []string{obj + "_cgo_gotypes.go"} 2880 cfiles := []string{"_cgo_main.c", "_cgo_export.c"} 2881 for _, fn := range cgofiles { 2882 f := cgoRe.ReplaceAllString(fn[:len(fn)-2], "_") 2883 gofiles = append(gofiles, obj+f+"cgo1.go") 2884 cfiles = append(cfiles, f+"cgo2.c") 2885 } 2886 defunC := obj + "_cgo_defun.c" 2887 2888 cgoflags := []string{} 2889 // TODO: make cgo not depend on $GOARCH? 2890 2891 if p.Standard && p.ImportPath == "runtime/cgo" { 2892 cgoflags = append(cgoflags, "-import_runtime_cgo=false") 2893 } 2894 if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/cgo") { 2895 cgoflags = append(cgoflags, "-import_syscall=false") 2896 } 2897 2898 // Update $CGO_LDFLAGS with p.CgoLDFLAGS. 2899 var cgoenv []string 2900 if len(cgoLDFLAGS) > 0 { 2901 flags := make([]string, len(cgoLDFLAGS)) 2902 for i, f := range cgoLDFLAGS { 2903 flags[i] = strconv.Quote(f) 2904 } 2905 cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")} 2906 } 2907 2908 if _, ok := buildToolchain.(gccgoToolchain); ok { 2909 switch goarch { 2910 case "386", "amd64": 2911 cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack") 2912 } 2913 cgoflags = append(cgoflags, "-gccgo") 2914 if pkgpath := gccgoPkgpath(p); pkgpath != "" { 2915 cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath) 2916 } 2917 } 2918 2919 switch buildBuildmode { 2920 case "c-archive", "c-shared": 2921 // Tell cgo that if there are any exported functions 2922 // it should generate a header file that C code can 2923 // #include. 2924 cgoflags = append(cgoflags, "-exportheader="+obj+"_cgo_install.h") 2925 } 2926 2927 if err := b.run(p.Dir, p.ImportPath, cgoenv, buildToolExec, cgoExe, "-objdir", obj, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoexeCFLAGS, cgofiles); err != nil { 2928 return nil, nil, err 2929 } 2930 outGo = append(outGo, gofiles...) 2931 2932 // cc _cgo_defun.c 2933 _, gccgo := buildToolchain.(gccgoToolchain) 2934 if gccgo { 2935 defunObj := obj + "_cgo_defun.o" 2936 if err := buildToolchain.cc(b, p, obj, defunObj, defunC); err != nil { 2937 return nil, nil, err 2938 } 2939 outObj = append(outObj, defunObj) 2940 } 2941 2942 // gcc 2943 var linkobj []string 2944 2945 var bareLDFLAGS []string 2946 // When linking relocatable objects, various flags need to be 2947 // filtered out as they are inapplicable and can cause some linkers 2948 // to fail. 2949 for i := 0; i < len(cgoLDFLAGS); i++ { 2950 f := cgoLDFLAGS[i] 2951 switch { 2952 // skip "-lc" or "-l somelib" 2953 case strings.HasPrefix(f, "-l"): 2954 if f == "-l" { 2955 i++ 2956 } 2957 // skip "-framework X" on Darwin 2958 case goos == "darwin" && f == "-framework": 2959 i++ 2960 // skip "*.{dylib,so,dll}" 2961 case strings.HasSuffix(f, ".dylib"), 2962 strings.HasSuffix(f, ".so"), 2963 strings.HasSuffix(f, ".dll"): 2964 // Remove any -fsanitize=foo flags. 2965 // Otherwise the compiler driver thinks that we are doing final link 2966 // and links sanitizer runtime into the object file. But we are not doing 2967 // the final link, we will link the resulting object file again. And 2968 // so the program ends up with two copies of sanitizer runtime. 2969 // See issue 8788 for details. 2970 case strings.HasPrefix(f, "-fsanitize="): 2971 continue 2972 // runpath flags not applicable unless building a shared 2973 // object or executable; see issue 12115 for details. This 2974 // is necessary as Go currently does not offer a way to 2975 // specify the set of LDFLAGS that only apply to shared 2976 // objects. 2977 case strings.HasPrefix(f, "-Wl,-rpath"): 2978 if f == "-Wl,-rpath" || f == "-Wl,-rpath-link" { 2979 // Skip following argument to -rpath* too. 2980 i++ 2981 } 2982 default: 2983 bareLDFLAGS = append(bareLDFLAGS, f) 2984 } 2985 } 2986 2987 cgoLibGccFileOnce.Do(func() { 2988 cgoLibGccFile, cgoLibGccErr = b.libgcc(p) 2989 }) 2990 if cgoLibGccFile == "" && cgoLibGccErr != nil { 2991 return nil, nil, err 2992 } 2993 2994 var staticLibs []string 2995 if goos == "windows" { 2996 // libmingw32 and libmingwex might also use libgcc, so libgcc must come last, 2997 // and they also have some inter-dependencies, so must use linker groups. 2998 staticLibs = []string{"-Wl,--start-group", "-lmingwex", "-lmingw32", "-Wl,--end-group"} 2999 } 3000 if cgoLibGccFile != "" { 3001 staticLibs = append(staticLibs, cgoLibGccFile) 3002 } 3003 3004 cflags := stringList(cgoCPPFLAGS, cgoCFLAGS) 3005 for _, cfile := range cfiles { 3006 ofile := obj + cfile[:len(cfile)-1] + "o" 3007 if err := b.gcc(p, ofile, cflags, obj+cfile); err != nil { 3008 return nil, nil, err 3009 } 3010 linkobj = append(linkobj, ofile) 3011 if !strings.HasSuffix(ofile, "_cgo_main.o") { 3012 outObj = append(outObj, ofile) 3013 } 3014 } 3015 3016 for _, file := range gccfiles { 3017 ofile := obj + cgoRe.ReplaceAllString(file[:len(file)-1], "_") + "o" 3018 if err := b.gcc(p, ofile, cflags, file); err != nil { 3019 return nil, nil, err 3020 } 3021 linkobj = append(linkobj, ofile) 3022 outObj = append(outObj, ofile) 3023 } 3024 3025 cxxflags := stringList(cgoCPPFLAGS, cgoCXXFLAGS) 3026 for _, file := range gxxfiles { 3027 // Append .o to the file, just in case the pkg has file.c and file.cpp 3028 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o" 3029 if err := b.gxx(p, ofile, cxxflags, file); err != nil { 3030 return nil, nil, err 3031 } 3032 linkobj = append(linkobj, ofile) 3033 outObj = append(outObj, ofile) 3034 } 3035 3036 for _, file := range mfiles { 3037 // Append .o to the file, just in case the pkg has file.c and file.m 3038 ofile := obj + cgoRe.ReplaceAllString(file, "_") + ".o" 3039 if err := b.gcc(p, ofile, cflags, file); err != nil { 3040 return nil, nil, err 3041 } 3042 linkobj = append(linkobj, ofile) 3043 outObj = append(outObj, ofile) 3044 } 3045 3046 linkobj = append(linkobj, p.SysoFiles...) 3047 dynobj := obj + "_cgo_.o" 3048 pie := goarch == "arm" && (goos == "linux" || goos == "android") 3049 if pie { // we need to use -pie for Linux/ARM to get accurate imported sym 3050 cgoLDFLAGS = append(cgoLDFLAGS, "-pie") 3051 } 3052 if err := b.gccld(p, dynobj, cgoLDFLAGS, linkobj); err != nil { 3053 return nil, nil, err 3054 } 3055 if pie { // but we don't need -pie for normal cgo programs 3056 cgoLDFLAGS = cgoLDFLAGS[0 : len(cgoLDFLAGS)-1] 3057 } 3058 3059 if _, ok := buildToolchain.(gccgoToolchain); ok { 3060 // we don't use dynimport when using gccgo. 3061 return outGo, outObj, nil 3062 } 3063 3064 // cgo -dynimport 3065 importGo := obj + "_cgo_import.go" 3066 cgoflags = []string{} 3067 if p.Standard && p.ImportPath == "runtime/cgo" { 3068 cgoflags = append(cgoflags, "-dynlinker") // record path to dynamic linker 3069 } 3070 if err := b.run(p.Dir, p.ImportPath, nil, buildToolExec, cgoExe, "-objdir", obj, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags); err != nil { 3071 return nil, nil, err 3072 } 3073 outGo = append(outGo, importGo) 3074 3075 ofile := obj + "_all.o" 3076 var gccObjs, nonGccObjs []string 3077 for _, f := range outObj { 3078 if strings.HasSuffix(f, ".o") { 3079 gccObjs = append(gccObjs, f) 3080 } else { 3081 nonGccObjs = append(nonGccObjs, f) 3082 } 3083 } 3084 ldflags := stringList(bareLDFLAGS, "-Wl,-r", "-nostdlib", staticLibs) 3085 3086 // We are creating an object file, so we don't want a build ID. 3087 ldflags = b.disableBuildID(ldflags) 3088 3089 if err := b.gccld(p, ofile, ldflags, gccObjs); err != nil { 3090 return nil, nil, err 3091 } 3092 3093 // NOTE(rsc): The importObj is a 5c/6c/8c object and on Windows 3094 // must be processed before the gcc-generated objects. 3095 // Put it first. https://golang.org/issue/2601 3096 outObj = stringList(nonGccObjs, ofile) 3097 3098 return outGo, outObj, nil 3099 } 3100 3101 // Run SWIG on all SWIG input files. 3102 // TODO: Don't build a shared library, once SWIG emits the necessary 3103 // pragmas for external linking. 3104 func (b *builder) swig(p *Package, obj string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) { 3105 if err := b.swigVersionCheck(); err != nil { 3106 return nil, nil, nil, err 3107 } 3108 3109 intgosize, err := b.swigIntSize(obj) 3110 if err != nil { 3111 return nil, nil, nil, err 3112 } 3113 3114 for _, f := range p.SwigFiles { 3115 goFile, cFile, err := b.swigOne(p, f, obj, pcCFLAGS, false, intgosize) 3116 if err != nil { 3117 return nil, nil, nil, err 3118 } 3119 if goFile != "" { 3120 outGo = append(outGo, goFile) 3121 } 3122 if cFile != "" { 3123 outC = append(outC, cFile) 3124 } 3125 } 3126 for _, f := range p.SwigCXXFiles { 3127 goFile, cxxFile, err := b.swigOne(p, f, obj, pcCFLAGS, true, intgosize) 3128 if err != nil { 3129 return nil, nil, nil, err 3130 } 3131 if goFile != "" { 3132 outGo = append(outGo, goFile) 3133 } 3134 if cxxFile != "" { 3135 outCXX = append(outCXX, cxxFile) 3136 } 3137 } 3138 return outGo, outC, outCXX, nil 3139 } 3140 3141 // Make sure SWIG is new enough. 3142 var ( 3143 swigCheckOnce sync.Once 3144 swigCheck error 3145 ) 3146 3147 func (b *builder) swigDoVersionCheck() error { 3148 out, err := b.runOut("", "", nil, "swig", "-version") 3149 if err != nil { 3150 return err 3151 } 3152 re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`) 3153 matches := re.FindSubmatch(out) 3154 if matches == nil { 3155 // Can't find version number; hope for the best. 3156 return nil 3157 } 3158 3159 major, err := strconv.Atoi(string(matches[1])) 3160 if err != nil { 3161 // Can't find version number; hope for the best. 3162 return nil 3163 } 3164 const errmsg = "must have SWIG version >= 3.0.6" 3165 if major < 3 { 3166 return errors.New(errmsg) 3167 } 3168 if major > 3 { 3169 // 4.0 or later 3170 return nil 3171 } 3172 3173 // We have SWIG version 3.x. 3174 if len(matches[2]) > 0 { 3175 minor, err := strconv.Atoi(string(matches[2][1:])) 3176 if err != nil { 3177 return nil 3178 } 3179 if minor > 0 { 3180 // 3.1 or later 3181 return nil 3182 } 3183 } 3184 3185 // We have SWIG version 3.0.x. 3186 if len(matches[3]) > 0 { 3187 patch, err := strconv.Atoi(string(matches[3][1:])) 3188 if err != nil { 3189 return nil 3190 } 3191 if patch < 6 { 3192 // Before 3.0.6. 3193 return errors.New(errmsg) 3194 } 3195 } 3196 3197 return nil 3198 } 3199 3200 func (b *builder) swigVersionCheck() error { 3201 swigCheckOnce.Do(func() { 3202 swigCheck = b.swigDoVersionCheck() 3203 }) 3204 return swigCheck 3205 } 3206 3207 // This code fails to build if sizeof(int) <= 32 3208 const swigIntSizeCode = ` 3209 package main 3210 const i int = 1 << 32 3211 ` 3212 3213 // Determine the size of int on the target system for the -intgosize option 3214 // of swig >= 2.0.9 3215 func (b *builder) swigIntSize(obj string) (intsize string, err error) { 3216 if buildN { 3217 return "$INTBITS", nil 3218 } 3219 src := filepath.Join(b.work, "swig_intsize.go") 3220 if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0644); err != nil { 3221 return 3222 } 3223 srcs := []string{src} 3224 3225 p := goFilesPackage(srcs) 3226 3227 if _, _, e := buildToolchain.gc(b, p, "", obj, false, nil, srcs); e != nil { 3228 return "32", nil 3229 } 3230 return "64", nil 3231 } 3232 3233 // Run SWIG on one SWIG input file. 3234 func (b *builder) swigOne(p *Package, file, obj string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) { 3235 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _ := b.cflags(p, true) 3236 var cflags []string 3237 if cxx { 3238 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS) 3239 } else { 3240 cflags = stringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS) 3241 } 3242 3243 n := 5 // length of ".swig" 3244 if cxx { 3245 n = 8 // length of ".swigcxx" 3246 } 3247 base := file[:len(file)-n] 3248 goFile := base + ".go" 3249 gccBase := base + "_wrap." 3250 gccExt := "c" 3251 if cxx { 3252 gccExt = "cxx" 3253 } 3254 3255 _, gccgo := buildToolchain.(gccgoToolchain) 3256 3257 // swig 3258 args := []string{ 3259 "-go", 3260 "-cgo", 3261 "-intgosize", intgosize, 3262 "-module", base, 3263 "-o", obj + gccBase + gccExt, 3264 "-outdir", obj, 3265 } 3266 3267 for _, f := range cflags { 3268 if len(f) > 3 && f[:2] == "-I" { 3269 args = append(args, f) 3270 } 3271 } 3272 3273 if gccgo { 3274 args = append(args, "-gccgo") 3275 if pkgpath := gccgoPkgpath(p); pkgpath != "" { 3276 args = append(args, "-go-pkgpath", pkgpath) 3277 } 3278 } 3279 if cxx { 3280 args = append(args, "-c++") 3281 } 3282 3283 out, err := b.runOut(p.Dir, p.ImportPath, nil, "swig", args, file) 3284 if err != nil { 3285 if len(out) > 0 { 3286 if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) { 3287 return "", "", errors.New("must have SWIG version >= 3.0.6") 3288 } 3289 b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig error 3290 return "", "", errPrintedOutput 3291 } 3292 return "", "", err 3293 } 3294 if len(out) > 0 { 3295 b.showOutput(p.Dir, p.ImportPath, b.processOutput(out)) // swig warning 3296 } 3297 3298 return obj + goFile, obj + gccBase + gccExt, nil 3299 } 3300 3301 // disableBuildID adjusts a linker command line to avoid creating a 3302 // build ID when creating an object file rather than an executable or 3303 // shared library. Some systems, such as Ubuntu, always add 3304 // --build-id to every link, but we don't want a build ID when we are 3305 // producing an object file. On some of those system a plain -r (not 3306 // -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a 3307 // plain -r. I don't know how to turn off --build-id when using clang 3308 // other than passing a trailing --build-id=none. So that is what we 3309 // do, but only on systems likely to support it, which is to say, 3310 // systems that normally use gold or the GNU linker. 3311 func (b *builder) disableBuildID(ldflags []string) []string { 3312 switch goos { 3313 case "android", "dragonfly", "linux", "netbsd": 3314 ldflags = append(ldflags, "-Wl,--build-id=none") 3315 } 3316 return ldflags 3317 } 3318 3319 // An actionQueue is a priority queue of actions. 3320 type actionQueue []*action 3321 3322 // Implement heap.Interface 3323 func (q *actionQueue) Len() int { return len(*q) } 3324 func (q *actionQueue) Swap(i, j int) { (*q)[i], (*q)[j] = (*q)[j], (*q)[i] } 3325 func (q *actionQueue) Less(i, j int) bool { return (*q)[i].priority < (*q)[j].priority } 3326 func (q *actionQueue) Push(x interface{}) { *q = append(*q, x.(*action)) } 3327 func (q *actionQueue) Pop() interface{} { 3328 n := len(*q) - 1 3329 x := (*q)[n] 3330 *q = (*q)[:n] 3331 return x 3332 } 3333 3334 func (q *actionQueue) push(a *action) { 3335 heap.Push(q, a) 3336 } 3337 3338 func (q *actionQueue) pop() *action { 3339 return heap.Pop(q).(*action) 3340 } 3341 3342 func raceInit() { 3343 if !buildRace { 3344 return 3345 } 3346 if goarch != "amd64" || goos != "linux" && goos != "freebsd" && goos != "darwin" && goos != "windows" { 3347 fmt.Fprintf(os.Stderr, "go %s: -race is only supported on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64\n", flag.Args()[0]) 3348 os.Exit(2) 3349 } 3350 buildGcflags = append(buildGcflags, "-race") 3351 buildLdflags = append(buildLdflags, "-race") 3352 if buildContext.InstallSuffix != "" { 3353 buildContext.InstallSuffix += "_" 3354 } 3355 buildContext.InstallSuffix += "race" 3356 buildContext.BuildTags = append(buildContext.BuildTags, "race") 3357 } 3358 3359 // defaultSuffix returns file extension used for command files in 3360 // current os environment. 3361 func defaultSuffix() string { 3362 switch runtime.GOOS { 3363 case "windows": 3364 return ".bat" 3365 case "plan9": 3366 return ".rc" 3367 default: 3368 return ".bash" 3369 } 3370 }