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