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