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