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