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