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