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