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