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