github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/cmd/go/internal/work/exec.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 // Action graph execution. 6 7 package work 8 9 import ( 10 "bytes" 11 "encoding/json" 12 "errors" 13 "fmt" 14 "io" 15 "io/ioutil" 16 "log" 17 "math/rand" 18 "os" 19 "os/exec" 20 "path/filepath" 21 "regexp" 22 "runtime" 23 "strconv" 24 "strings" 25 "sync" 26 "time" 27 28 "cmd/go/internal/base" 29 "cmd/go/internal/cache" 30 "cmd/go/internal/cfg" 31 "cmd/go/internal/load" 32 "cmd/go/internal/str" 33 ) 34 35 // actionList returns the list of actions in the dag rooted at root 36 // as visited in a depth-first post-order traversal. 37 func actionList(root *Action) []*Action { 38 seen := map[*Action]bool{} 39 all := []*Action{} 40 var walk func(*Action) 41 walk = func(a *Action) { 42 if seen[a] { 43 return 44 } 45 seen[a] = true 46 for _, a1 := range a.Deps { 47 walk(a1) 48 } 49 all = append(all, a) 50 } 51 walk(root) 52 return all 53 } 54 55 // do runs the action graph rooted at root. 56 func (b *Builder) Do(root *Action) { 57 if c := cache.Default(); c != nil && !b.IsCmdList { 58 // If we're doing real work, take time at the end to trim the cache. 59 defer c.Trim() 60 } 61 62 // Build list of all actions, assigning depth-first post-order priority. 63 // The original implementation here was a true queue 64 // (using a channel) but it had the effect of getting 65 // distracted by low-level leaf actions to the detriment 66 // of completing higher-level actions. The order of 67 // work does not matter much to overall execution time, 68 // but when running "go test std" it is nice to see each test 69 // results as soon as possible. The priorities assigned 70 // ensure that, all else being equal, the execution prefers 71 // to do what it would have done first in a simple depth-first 72 // dependency order traversal. 73 all := actionList(root) 74 for i, a := range all { 75 a.priority = i 76 } 77 78 if cfg.DebugActiongraph != "" { 79 js := actionGraphJSON(root) 80 if err := ioutil.WriteFile(cfg.DebugActiongraph, []byte(js), 0666); err != nil { 81 fmt.Fprintf(os.Stderr, "go: writing action graph: %v\n", err) 82 base.SetExitStatus(1) 83 } 84 } 85 86 b.readySema = make(chan bool, len(all)) 87 88 // Initialize per-action execution state. 89 for _, a := range all { 90 for _, a1 := range a.Deps { 91 a1.triggers = append(a1.triggers, a) 92 } 93 a.pending = len(a.Deps) 94 if a.pending == 0 { 95 b.ready.push(a) 96 b.readySema <- true 97 } 98 } 99 100 // Handle runs a single action and takes care of triggering 101 // any actions that are runnable as a result. 102 handle := func(a *Action) { 103 var err error 104 105 if a.Func != nil && (!a.Failed || a.IgnoreFail) { 106 if err == nil { 107 err = a.Func(b, a) 108 } 109 } 110 111 // The actions run in parallel but all the updates to the 112 // shared work state are serialized through b.exec. 113 b.exec.Lock() 114 defer b.exec.Unlock() 115 116 if err != nil { 117 if err == errPrintedOutput { 118 base.SetExitStatus(2) 119 } else { 120 base.Errorf("%s", err) 121 } 122 a.Failed = true 123 } 124 125 for _, a0 := range a.triggers { 126 if a.Failed { 127 a0.Failed = true 128 } 129 if a0.pending--; a0.pending == 0 { 130 b.ready.push(a0) 131 b.readySema <- true 132 } 133 } 134 135 if a == root { 136 close(b.readySema) 137 } 138 } 139 140 var wg sync.WaitGroup 141 142 // Kick off goroutines according to parallelism. 143 // If we are using the -n flag (just printing commands) 144 // drop the parallelism to 1, both to make the output 145 // deterministic and because there is no real work anyway. 146 par := cfg.BuildP 147 if cfg.BuildN { 148 par = 1 149 } 150 for i := 0; i < par; i++ { 151 wg.Add(1) 152 go func() { 153 defer wg.Done() 154 for { 155 select { 156 case _, ok := <-b.readySema: 157 if !ok { 158 return 159 } 160 // Receiving a value from b.readySema entitles 161 // us to take from the ready queue. 162 b.exec.Lock() 163 a := b.ready.pop() 164 b.exec.Unlock() 165 handle(a) 166 case <-base.Interrupted: 167 base.SetExitStatus(1) 168 return 169 } 170 } 171 }() 172 } 173 174 wg.Wait() 175 } 176 177 // buildActionID computes the action ID for a build action. 178 func (b *Builder) buildActionID(a *Action) cache.ActionID { 179 p := a.Package 180 h := cache.NewHash("build " + p.ImportPath) 181 182 // Configuration independent of compiler toolchain. 183 // Note: buildmode has already been accounted for in buildGcflags 184 // and should not be inserted explicitly. Most buildmodes use the 185 // same compiler settings and can reuse each other's results. 186 // If not, the reason is already recorded in buildGcflags. 187 fmt.Fprintf(h, "compile\n") 188 // The compiler hides the exact value of $GOROOT 189 // when building things in GOROOT, 190 // but it does not hide the exact value of $GOPATH. 191 // Include the full dir in that case. 192 // Assume b.WorkDir is being trimmed properly. 193 if !p.Goroot && !strings.HasPrefix(p.Dir, b.WorkDir) { 194 fmt.Fprintf(h, "dir %s\n", p.Dir) 195 } 196 fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch) 197 fmt.Fprintf(h, "import %q\n", p.ImportPath) 198 fmt.Fprintf(h, "omitdebug %v standard %v local %v prefix %q\n", p.Internal.OmitDebug, p.Standard, p.Internal.Local, p.Internal.LocalPrefix) 199 if p.Internal.ForceLibrary { 200 fmt.Fprintf(h, "forcelibrary\n") 201 } 202 if len(p.CgoFiles)+len(p.SwigFiles) > 0 { 203 fmt.Fprintf(h, "cgo %q\n", b.toolID("cgo")) 204 cppflags, cflags, cxxflags, fflags, ldflags, _ := b.CFlags(p) 205 fmt.Fprintf(h, "CC=%q %q %q %q\n", b.ccExe(), cppflags, cflags, ldflags) 206 if len(p.CXXFiles)+len(p.SwigFiles) > 0 { 207 fmt.Fprintf(h, "CXX=%q %q\n", b.cxxExe(), cxxflags) 208 } 209 if len(p.FFiles) > 0 { 210 fmt.Fprintf(h, "FC=%q %q\n", b.fcExe(), fflags) 211 } 212 // TODO(rsc): Should we include the SWIG version or Fortran/GCC/G++/Objective-C compiler versions? 213 } 214 if p.Internal.CoverMode != "" { 215 fmt.Fprintf(h, "cover %q %q\n", p.Internal.CoverMode, b.toolID("cover")) 216 } 217 218 // Configuration specific to compiler toolchain. 219 switch cfg.BuildToolchainName { 220 default: 221 base.Fatalf("buildActionID: unknown build toolchain %q", cfg.BuildToolchainName) 222 case "gc": 223 fmt.Fprintf(h, "compile %s %q %q\n", b.toolID("compile"), forcedGcflags, p.Internal.Gcflags) 224 if len(p.SFiles) > 0 { 225 fmt.Fprintf(h, "asm %q %q %q\n", b.toolID("asm"), forcedAsmflags, p.Internal.Asmflags) 226 } 227 // GO386, GOARM, GOMIPS, etc. 228 baseArch := strings.TrimSuffix(cfg.BuildContext.GOARCH, "le") 229 fmt.Fprintf(h, "GO$GOARCH=%s\n", os.Getenv("GO"+strings.ToUpper(baseArch))) 230 231 // TODO(rsc): Convince compiler team not to add more magic environment variables, 232 // or perhaps restrict the environment variables passed to subprocesses. 233 magic := []string{ 234 "GOCLOBBERDEADHASH", 235 "GOSSAFUNC", 236 "GO_SSA_PHI_LOC_CUTOFF", 237 "GOSSAHASH", 238 } 239 for _, env := range magic { 240 if x := os.Getenv(env); x != "" { 241 fmt.Fprintf(h, "magic %s=%s\n", env, x) 242 } 243 } 244 if os.Getenv("GOSSAHASH") != "" { 245 for i := 0; ; i++ { 246 env := fmt.Sprintf("GOSSAHASH%d", i) 247 x := os.Getenv(env) 248 if x == "" { 249 break 250 } 251 fmt.Fprintf(h, "magic %s=%s\n", env, x) 252 } 253 } 254 if os.Getenv("GSHS_LOGFILE") != "" { 255 // Clumsy hack. Compiler writes to this log file, 256 // so do not allow use of cache at all. 257 // We will still write to the cache but it will be 258 // essentially unfindable. 259 fmt.Fprintf(h, "nocache %d\n", time.Now().UnixNano()) 260 } 261 262 case "gccgo": 263 id, err := b.gccgoToolID(BuildToolchain.compiler(), "go") 264 if err != nil { 265 base.Fatalf("%v", err) 266 } 267 fmt.Fprintf(h, "compile %s %q %q\n", id, forcedGccgoflags, p.Internal.Gccgoflags) 268 fmt.Fprintf(h, "pkgpath %s\n", gccgoPkgpath(p)) 269 if len(p.SFiles) > 0 { 270 id, err = b.gccgoToolID(BuildToolchain.compiler(), "assembler-with-cpp") 271 // Ignore error; different assembler versions 272 // are unlikely to make any difference anyhow. 273 fmt.Fprintf(h, "asm %q\n", id) 274 } 275 } 276 277 // Input files. 278 inputFiles := str.StringList( 279 p.GoFiles, 280 p.CgoFiles, 281 p.CFiles, 282 p.CXXFiles, 283 p.FFiles, 284 p.MFiles, 285 p.HFiles, 286 p.SFiles, 287 p.SysoFiles, 288 p.SwigFiles, 289 p.SwigCXXFiles, 290 ) 291 for _, file := range inputFiles { 292 fmt.Fprintf(h, "file %s %s\n", file, b.fileHash(filepath.Join(p.Dir, file))) 293 } 294 for _, a1 := range a.Deps { 295 p1 := a1.Package 296 if p1 != nil { 297 fmt.Fprintf(h, "import %s %s\n", p1.ImportPath, contentID(a1.buildID)) 298 } 299 } 300 301 return h.Sum() 302 } 303 304 // needCgoHdr reports whether the actions triggered by this one 305 // expect to be able to access the cgo-generated header file. 306 func (b *Builder) needCgoHdr(a *Action) bool { 307 // If this build triggers a header install, run cgo to get the header. 308 if !b.IsCmdList && (a.Package.UsesCgo() || a.Package.UsesSwig()) && (cfg.BuildBuildmode == "c-archive" || cfg.BuildBuildmode == "c-shared") { 309 for _, t1 := range a.triggers { 310 if t1.Mode == "install header" { 311 return true 312 } 313 } 314 for _, t1 := range a.triggers { 315 for _, t2 := range t1.triggers { 316 if t2.Mode == "install header" { 317 return true 318 } 319 } 320 } 321 } 322 return false 323 } 324 325 // allowedVersion reports whether the version v is an allowed version of go 326 // (one that we can compile). 327 // v is known to be of the form "1.23". 328 func allowedVersion(v string) bool { 329 // Special case: no requirement. 330 if v == "" { 331 return true 332 } 333 // Special case "1.0" means "go1", which is OK. 334 if v == "1.0" { 335 return true 336 } 337 // Otherwise look through release tags of form "go1.23" for one that matches. 338 for _, tag := range cfg.BuildContext.ReleaseTags { 339 if strings.HasPrefix(tag, "go") && tag[2:] == v { 340 return true 341 } 342 } 343 return false 344 } 345 346 const ( 347 needBuild uint32 = 1 << iota 348 needCgoHdr 349 needVet 350 needCompiledGoFiles 351 needStale 352 ) 353 354 // build is the action for building a single package. 355 // Note that any new influence on this logic must be reported in b.buildActionID above as well. 356 func (b *Builder) build(a *Action) (err error) { 357 p := a.Package 358 359 bit := func(x uint32, b bool) uint32 { 360 if b { 361 return x 362 } 363 return 0 364 } 365 366 cached := false 367 need := bit(needBuild, !b.IsCmdList || b.NeedExport) | 368 bit(needCgoHdr, b.needCgoHdr(a)) | 369 bit(needVet, a.needVet) | 370 bit(needCompiledGoFiles, b.NeedCompiledGoFiles) 371 372 if !p.BinaryOnly { 373 if b.useCache(a, p, b.buildActionID(a), p.Target) { 374 // We found the main output in the cache. 375 // If we don't need any other outputs, we can stop. 376 need &^= needBuild 377 if b.NeedExport { 378 p.Export = a.built 379 } 380 if need&needCompiledGoFiles != 0 && b.loadCachedSrcFiles(a) { 381 need &^= needCompiledGoFiles 382 } 383 // Otherwise, we need to write files to a.Objdir (needVet, needCgoHdr). 384 // Remember that we might have them in cache 385 // and check again after we create a.Objdir. 386 cached = true 387 a.output = []byte{} // start saving output in case we miss any cache results 388 } 389 390 // Source files might be cached, even if the full action is not 391 // (e.g., go list -compiled -find). 392 if !cached && need&needCompiledGoFiles != 0 && b.loadCachedSrcFiles(a) { 393 need &^= needCompiledGoFiles 394 } 395 396 if need == 0 { 397 return nil 398 } 399 defer b.flushOutput(a) 400 } 401 402 defer func() { 403 if err != nil && err != errPrintedOutput { 404 err = fmt.Errorf("go build %s: %v", a.Package.ImportPath, err) 405 } 406 if err != nil && b.IsCmdList && b.NeedError && p.Error == nil { 407 p.Error = &load.PackageError{Err: err.Error()} 408 } 409 }() 410 if cfg.BuildN { 411 // In -n mode, print a banner between packages. 412 // The banner is five lines so that when changes to 413 // different sections of the bootstrap script have to 414 // be merged, the banners give patch something 415 // to use to find its context. 416 b.Print("\n#\n# " + a.Package.ImportPath + "\n#\n\n") 417 } 418 419 if cfg.BuildV { 420 b.Print(a.Package.ImportPath + "\n") 421 } 422 423 if a.Package.BinaryOnly { 424 _, err := os.Stat(a.Package.Target) 425 if err == nil { 426 a.built = a.Package.Target 427 a.Target = a.Package.Target 428 if b.NeedExport { 429 a.Package.Export = a.Package.Target 430 } 431 a.buildID = b.fileHash(a.Package.Target) 432 a.Package.Stale = false 433 a.Package.StaleReason = "binary-only package" 434 return nil 435 } 436 a.Package.Stale = true 437 a.Package.StaleReason = "missing or invalid binary-only package" 438 if b.IsCmdList { 439 return nil 440 } 441 return fmt.Errorf("missing or invalid binary-only package; expected file %q", a.Package.Target) 442 } 443 444 if err := b.Mkdir(a.Objdir); err != nil { 445 return err 446 } 447 objdir := a.Objdir 448 449 if cached { 450 if need&needCgoHdr != 0 && b.loadCachedCgoHdr(a) { 451 need &^= needCgoHdr 452 } 453 454 // Load cached vet config, but only if that's all we have left 455 // (need == needVet, not testing just the one bit). 456 // If we are going to do a full build anyway, 457 // we're going to regenerate the files below anyway. 458 if need == needVet && b.loadCachedVet(a) { 459 need &^= needVet 460 } 461 if need == 0 { 462 return nil 463 } 464 } 465 466 // make target directory 467 dir, _ := filepath.Split(a.Target) 468 if dir != "" { 469 if err := b.Mkdir(dir); err != nil { 470 return err 471 } 472 } 473 474 gofiles := str.StringList(a.Package.GoFiles) 475 cgofiles := str.StringList(a.Package.CgoFiles) 476 cfiles := str.StringList(a.Package.CFiles) 477 sfiles := str.StringList(a.Package.SFiles) 478 cxxfiles := str.StringList(a.Package.CXXFiles) 479 var objects, cgoObjects, pcCFLAGS, pcLDFLAGS []string 480 481 if a.Package.UsesCgo() || a.Package.UsesSwig() { 482 if pcCFLAGS, pcLDFLAGS, err = b.getPkgConfigFlags(a.Package); err != nil { 483 return 484 } 485 } 486 487 // Run SWIG on each .swig and .swigcxx file. 488 // Each run will generate two files, a .go file and a .c or .cxx file. 489 // The .go file will use import "C" and is to be processed by cgo. 490 if a.Package.UsesSwig() { 491 outGo, outC, outCXX, err := b.swig(a, a.Package, objdir, pcCFLAGS) 492 if err != nil { 493 return err 494 } 495 cgofiles = append(cgofiles, outGo...) 496 cfiles = append(cfiles, outC...) 497 cxxfiles = append(cxxfiles, outCXX...) 498 } 499 500 // If we're doing coverage, preprocess the .go files and put them in the work directory 501 if a.Package.Internal.CoverMode != "" { 502 for i, file := range str.StringList(gofiles, cgofiles) { 503 var sourceFile string 504 var coverFile string 505 var key string 506 if strings.HasSuffix(file, ".cgo1.go") { 507 // cgo files have absolute paths 508 base := filepath.Base(file) 509 sourceFile = file 510 coverFile = objdir + base 511 key = strings.TrimSuffix(base, ".cgo1.go") + ".go" 512 } else { 513 sourceFile = filepath.Join(a.Package.Dir, file) 514 coverFile = objdir + file 515 key = file 516 } 517 coverFile = strings.TrimSuffix(coverFile, ".go") + ".cover.go" 518 cover := a.Package.Internal.CoverVars[key] 519 if cover == nil || base.IsTestFile(file) { 520 // Not covering this file. 521 continue 522 } 523 if err := b.cover(a, coverFile, sourceFile, cover.Var); err != nil { 524 return err 525 } 526 if i < len(gofiles) { 527 gofiles[i] = coverFile 528 } else { 529 cgofiles[i-len(gofiles)] = coverFile 530 } 531 } 532 } 533 534 // Run cgo. 535 if a.Package.UsesCgo() || a.Package.UsesSwig() { 536 // In a package using cgo, cgo compiles the C, C++ and assembly files with gcc. 537 // There is one exception: runtime/cgo's job is to bridge the 538 // cgo and non-cgo worlds, so it necessarily has files in both. 539 // In that case gcc only gets the gcc_* files. 540 var gccfiles []string 541 gccfiles = append(gccfiles, cfiles...) 542 cfiles = nil 543 if a.Package.Standard && a.Package.ImportPath == "runtime/cgo" { 544 filter := func(files, nongcc, gcc []string) ([]string, []string) { 545 for _, f := range files { 546 if strings.HasPrefix(f, "gcc_") { 547 gcc = append(gcc, f) 548 } else { 549 nongcc = append(nongcc, f) 550 } 551 } 552 return nongcc, gcc 553 } 554 sfiles, gccfiles = filter(sfiles, sfiles[:0], gccfiles) 555 } else { 556 for _, sfile := range sfiles { 557 data, err := ioutil.ReadFile(filepath.Join(a.Package.Dir, sfile)) 558 if err == nil { 559 if bytes.HasPrefix(data, []byte("TEXT")) || bytes.Contains(data, []byte("\nTEXT")) || 560 bytes.HasPrefix(data, []byte("DATA")) || bytes.Contains(data, []byte("\nDATA")) || 561 bytes.HasPrefix(data, []byte("GLOBL")) || bytes.Contains(data, []byte("\nGLOBL")) { 562 return fmt.Errorf("package using cgo has Go assembly file %s", sfile) 563 } 564 } 565 } 566 gccfiles = append(gccfiles, sfiles...) 567 sfiles = nil 568 } 569 570 outGo, outObj, err := b.cgo(a, base.Tool("cgo"), objdir, pcCFLAGS, pcLDFLAGS, mkAbsFiles(a.Package.Dir, cgofiles), gccfiles, cxxfiles, a.Package.MFiles, a.Package.FFiles) 571 if err != nil { 572 return err 573 } 574 if cfg.BuildToolchainName == "gccgo" { 575 cgoObjects = append(cgoObjects, a.Objdir+"_cgo_flags") 576 } 577 cgoObjects = append(cgoObjects, outObj...) 578 gofiles = append(gofiles, outGo...) 579 580 switch cfg.BuildBuildmode { 581 case "c-archive", "c-shared": 582 b.cacheCgoHdr(a) 583 } 584 } 585 586 var srcfiles []string // .go and non-.go 587 srcfiles = append(srcfiles, gofiles...) 588 srcfiles = append(srcfiles, sfiles...) 589 srcfiles = append(srcfiles, cfiles...) 590 srcfiles = append(srcfiles, cxxfiles...) 591 b.cacheSrcFiles(a, srcfiles) 592 593 // Running cgo generated the cgo header. 594 need &^= needCgoHdr 595 596 // Sanity check only, since Package.load already checked as well. 597 if len(gofiles) == 0 { 598 return &load.NoGoError{Package: a.Package} 599 } 600 601 // Prepare Go vet config if needed. 602 if need&needVet != 0 { 603 buildVetConfig(a, srcfiles) 604 need &^= needVet 605 } 606 if need&needCompiledGoFiles != 0 { 607 if !b.loadCachedSrcFiles(a) { 608 return fmt.Errorf("failed to cache compiled Go files") 609 } 610 need &^= needCompiledGoFiles 611 } 612 if need == 0 { 613 // Nothing left to do. 614 return nil 615 } 616 617 // Collect symbol ABI requirements from assembly. 618 symabis, err := BuildToolchain.symabis(b, a, sfiles) 619 if err != nil { 620 return err 621 } 622 623 // Prepare Go import config. 624 // We start it off with a comment so it can't be empty, so icfg.Bytes() below is never nil. 625 // It should never be empty anyway, but there have been bugs in the past that resulted 626 // in empty configs, which then unfortunately turn into "no config passed to compiler", 627 // and the compiler falls back to looking in pkg itself, which mostly works, 628 // except when it doesn't. 629 var icfg bytes.Buffer 630 fmt.Fprintf(&icfg, "# import config\n") 631 for i, raw := range a.Package.Internal.RawImports { 632 final := a.Package.Imports[i] 633 if final != raw { 634 fmt.Fprintf(&icfg, "importmap %s=%s\n", raw, final) 635 } 636 } 637 for _, a1 := range a.Deps { 638 p1 := a1.Package 639 if p1 == nil || p1.ImportPath == "" || a1.built == "" { 640 continue 641 } 642 fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built) 643 } 644 645 if p.Internal.BuildInfo != "" && cfg.ModulesEnabled { 646 if err := b.writeFile(objdir+"_gomod_.go", load.ModInfoProg(p.Internal.BuildInfo)); err != nil { 647 return err 648 } 649 gofiles = append(gofiles, objdir+"_gomod_.go") 650 } 651 652 // Compile Go. 653 objpkg := objdir + "_pkg_.a" 654 ofile, out, err := BuildToolchain.gc(b, a, objpkg, icfg.Bytes(), symabis, len(sfiles) > 0, gofiles) 655 if len(out) > 0 { 656 output := b.processOutput(out) 657 if p.Module != nil && !allowedVersion(p.Module.GoVersion) { 658 output += "note: module requires Go " + p.Module.GoVersion + "\n" 659 } 660 b.showOutput(a, a.Package.Dir, a.Package.Desc(), output) 661 if err != nil { 662 return errPrintedOutput 663 } 664 } 665 if err != nil { 666 if p.Module != nil && !allowedVersion(p.Module.GoVersion) { 667 b.showOutput(a, a.Package.Dir, a.Package.Desc(), "note: module requires Go "+p.Module.GoVersion) 668 } 669 return err 670 } 671 if ofile != objpkg { 672 objects = append(objects, ofile) 673 } 674 675 // Copy .h files named for goos or goarch or goos_goarch 676 // to names using GOOS and GOARCH. 677 // For example, defs_linux_amd64.h becomes defs_GOOS_GOARCH.h. 678 _goos_goarch := "_" + cfg.Goos + "_" + cfg.Goarch 679 _goos := "_" + cfg.Goos 680 _goarch := "_" + cfg.Goarch 681 for _, file := range a.Package.HFiles { 682 name, ext := fileExtSplit(file) 683 switch { 684 case strings.HasSuffix(name, _goos_goarch): 685 targ := file[:len(name)-len(_goos_goarch)] + "_GOOS_GOARCH." + ext 686 if err := b.copyFile(objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil { 687 return err 688 } 689 case strings.HasSuffix(name, _goarch): 690 targ := file[:len(name)-len(_goarch)] + "_GOARCH." + ext 691 if err := b.copyFile(objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil { 692 return err 693 } 694 case strings.HasSuffix(name, _goos): 695 targ := file[:len(name)-len(_goos)] + "_GOOS." + ext 696 if err := b.copyFile(objdir+targ, filepath.Join(a.Package.Dir, file), 0666, true); err != nil { 697 return err 698 } 699 } 700 } 701 702 for _, file := range cfiles { 703 out := file[:len(file)-len(".c")] + ".o" 704 if err := BuildToolchain.cc(b, a, objdir+out, file); err != nil { 705 return err 706 } 707 objects = append(objects, out) 708 } 709 710 // Assemble .s files. 711 if len(sfiles) > 0 { 712 ofiles, err := BuildToolchain.asm(b, a, sfiles) 713 if err != nil { 714 return err 715 } 716 objects = append(objects, ofiles...) 717 } 718 719 // For gccgo on ELF systems, we write the build ID as an assembler file. 720 // This lets us set the SHF_EXCLUDE flag. 721 // This is read by readGccgoArchive in cmd/internal/buildid/buildid.go. 722 if a.buildID != "" && cfg.BuildToolchainName == "gccgo" { 723 switch cfg.Goos { 724 case "aix", "android", "dragonfly", "freebsd", "linux", "netbsd", "openbsd", "solaris": 725 asmfile, err := b.gccgoBuildIDFile(a) 726 if err != nil { 727 return err 728 } 729 ofiles, err := BuildToolchain.asm(b, a, []string{asmfile}) 730 if err != nil { 731 return err 732 } 733 objects = append(objects, ofiles...) 734 } 735 } 736 737 // NOTE(rsc): On Windows, it is critically important that the 738 // gcc-compiled objects (cgoObjects) be listed after the ordinary 739 // objects in the archive. I do not know why this is. 740 // https://golang.org/issue/2601 741 objects = append(objects, cgoObjects...) 742 743 // Add system object files. 744 for _, syso := range a.Package.SysoFiles { 745 objects = append(objects, filepath.Join(a.Package.Dir, syso)) 746 } 747 748 // Pack into archive in objdir directory. 749 // If the Go compiler wrote an archive, we only need to add the 750 // object files for non-Go sources to the archive. 751 // If the Go compiler wrote an archive and the package is entirely 752 // Go sources, there is no pack to execute at all. 753 if len(objects) > 0 { 754 if err := BuildToolchain.pack(b, a, objpkg, objects); err != nil { 755 return err 756 } 757 } 758 759 if err := b.updateBuildID(a, objpkg, true); err != nil { 760 return err 761 } 762 763 a.built = objpkg 764 return nil 765 } 766 767 func (b *Builder) cacheObjdirFile(a *Action, c *cache.Cache, name string) error { 768 f, err := os.Open(a.Objdir + name) 769 if err != nil { 770 return err 771 } 772 defer f.Close() 773 _, _, err = c.Put(cache.Subkey(a.actionID, name), f) 774 return err 775 } 776 777 func (b *Builder) findCachedObjdirFile(a *Action, c *cache.Cache, name string) (string, error) { 778 file, _, err := c.GetFile(cache.Subkey(a.actionID, name)) 779 if err != nil { 780 return "", err 781 } 782 return file, nil 783 } 784 785 func (b *Builder) loadCachedObjdirFile(a *Action, c *cache.Cache, name string) error { 786 cached, err := b.findCachedObjdirFile(a, c, name) 787 if err != nil { 788 return err 789 } 790 return b.copyFile(a.Objdir+name, cached, 0666, true) 791 } 792 793 func (b *Builder) cacheCgoHdr(a *Action) { 794 c := cache.Default() 795 if c == nil { 796 return 797 } 798 b.cacheObjdirFile(a, c, "_cgo_install.h") 799 } 800 801 func (b *Builder) loadCachedCgoHdr(a *Action) bool { 802 c := cache.Default() 803 if c == nil { 804 return false 805 } 806 err := b.loadCachedObjdirFile(a, c, "_cgo_install.h") 807 return err == nil 808 } 809 810 func (b *Builder) cacheSrcFiles(a *Action, srcfiles []string) { 811 c := cache.Default() 812 if c == nil { 813 return 814 } 815 var buf bytes.Buffer 816 for _, file := range srcfiles { 817 if !strings.HasPrefix(file, a.Objdir) { 818 // not generated 819 buf.WriteString("./") 820 buf.WriteString(file) 821 buf.WriteString("\n") 822 continue 823 } 824 name := file[len(a.Objdir):] 825 buf.WriteString(name) 826 buf.WriteString("\n") 827 if err := b.cacheObjdirFile(a, c, name); err != nil { 828 return 829 } 830 } 831 c.PutBytes(cache.Subkey(a.actionID, "srcfiles"), buf.Bytes()) 832 } 833 834 func (b *Builder) loadCachedVet(a *Action) bool { 835 c := cache.Default() 836 if c == nil { 837 return false 838 } 839 list, _, err := c.GetBytes(cache.Subkey(a.actionID, "srcfiles")) 840 if err != nil { 841 return false 842 } 843 var srcfiles []string 844 for _, name := range strings.Split(string(list), "\n") { 845 if name == "" { // end of list 846 continue 847 } 848 if strings.HasPrefix(name, "./") { 849 srcfiles = append(srcfiles, name[2:]) 850 continue 851 } 852 if err := b.loadCachedObjdirFile(a, c, name); err != nil { 853 return false 854 } 855 srcfiles = append(srcfiles, a.Objdir+name) 856 } 857 buildVetConfig(a, srcfiles) 858 return true 859 } 860 861 func (b *Builder) loadCachedSrcFiles(a *Action) bool { 862 c := cache.Default() 863 if c == nil { 864 return false 865 } 866 list, _, err := c.GetBytes(cache.Subkey(a.actionID, "srcfiles")) 867 if err != nil { 868 return false 869 } 870 var files []string 871 for _, name := range strings.Split(string(list), "\n") { 872 if name == "" { // end of list 873 continue 874 } 875 if strings.HasPrefix(name, "./") { 876 files = append(files, name[len("./"):]) 877 continue 878 } 879 file, err := b.findCachedObjdirFile(a, c, name) 880 if err != nil { 881 return false 882 } 883 files = append(files, file) 884 } 885 a.Package.CompiledGoFiles = files 886 return true 887 } 888 889 // vetConfig is the configuration passed to vet describing a single package. 890 type vetConfig struct { 891 ID string // package ID (example: "fmt [fmt.test]") 892 Compiler string // compiler name (gc, gccgo) 893 Dir string // directory containing package 894 ImportPath string // canonical import path ("package path") 895 GoFiles []string // absolute paths to package source files 896 NonGoFiles []string // absolute paths to package non-Go files 897 898 ImportMap map[string]string // map import path in source code to package path 899 PackageFile map[string]string // map package path to .a file with export data 900 Standard map[string]bool // map package path to whether it's in the standard library 901 PackageVetx map[string]string // map package path to vetx data from earlier vet run 902 VetxOnly bool // only compute vetx data; don't report detected problems 903 VetxOutput string // write vetx data to this output file 904 905 SucceedOnTypecheckFailure bool // awful hack; see #18395 and below 906 } 907 908 func buildVetConfig(a *Action, srcfiles []string) { 909 // Classify files based on .go extension. 910 // srcfiles does not include raw cgo files. 911 var gofiles, nongofiles []string 912 for _, name := range srcfiles { 913 if strings.HasSuffix(name, ".go") { 914 gofiles = append(gofiles, name) 915 } else { 916 nongofiles = append(nongofiles, name) 917 } 918 } 919 920 // Pass list of absolute paths to vet, 921 // so that vet's error messages will use absolute paths, 922 // so that we can reformat them relative to the directory 923 // in which the go command is invoked. 924 vcfg := &vetConfig{ 925 ID: a.Package.ImportPath, 926 Compiler: cfg.BuildToolchainName, 927 Dir: a.Package.Dir, 928 GoFiles: mkAbsFiles(a.Package.Dir, gofiles), 929 NonGoFiles: mkAbsFiles(a.Package.Dir, nongofiles), 930 ImportPath: a.Package.ImportPath, 931 ImportMap: make(map[string]string), 932 PackageFile: make(map[string]string), 933 Standard: make(map[string]bool), 934 } 935 a.vetCfg = vcfg 936 for i, raw := range a.Package.Internal.RawImports { 937 final := a.Package.Imports[i] 938 vcfg.ImportMap[raw] = final 939 } 940 941 // Compute the list of mapped imports in the vet config 942 // so that we can add any missing mappings below. 943 vcfgMapped := make(map[string]bool) 944 for _, p := range vcfg.ImportMap { 945 vcfgMapped[p] = true 946 } 947 948 for _, a1 := range a.Deps { 949 p1 := a1.Package 950 if p1 == nil || p1.ImportPath == "" { 951 continue 952 } 953 // Add import mapping if needed 954 // (for imports like "runtime/cgo" that appear only in generated code). 955 if !vcfgMapped[p1.ImportPath] { 956 vcfg.ImportMap[p1.ImportPath] = p1.ImportPath 957 } 958 if a1.built != "" { 959 vcfg.PackageFile[p1.ImportPath] = a1.built 960 } 961 if p1.Standard { 962 vcfg.Standard[p1.ImportPath] = true 963 } 964 } 965 } 966 967 // VetTool is the path to an alternate vet tool binary. 968 // The caller is expected to set it (if needed) before executing any vet actions. 969 var VetTool string 970 971 // VetFlags are the flags to pass to vet. 972 // The caller is expected to set them before executing any vet actions. 973 var VetFlags []string 974 975 func (b *Builder) vet(a *Action) error { 976 // a.Deps[0] is the build of the package being vetted. 977 // a.Deps[1] is the build of the "fmt" package. 978 979 a.Failed = false // vet of dependency may have failed but we can still succeed 980 981 if a.Deps[0].Failed { 982 // The build of the package has failed. Skip vet check. 983 // Vet could return export data for non-typecheck errors, 984 // but we ignore it because the package cannot be compiled. 985 return nil 986 } 987 988 vcfg := a.Deps[0].vetCfg 989 if vcfg == nil { 990 // Vet config should only be missing if the build failed. 991 return fmt.Errorf("vet config not found") 992 } 993 994 vcfg.VetxOnly = a.VetxOnly 995 vcfg.VetxOutput = a.Objdir + "vet.out" 996 vcfg.PackageVetx = make(map[string]string) 997 998 h := cache.NewHash("vet " + a.Package.ImportPath) 999 fmt.Fprintf(h, "vet %q\n", b.toolID("vet")) 1000 1001 // Note: We could decide that vet should compute export data for 1002 // all analyses, in which case we don't need to include the flags here. 1003 // But that would mean that if an analysis causes problems like 1004 // unexpected crashes there would be no way to turn it off. 1005 // It seems better to let the flags disable export analysis too. 1006 fmt.Fprintf(h, "vetflags %q\n", VetFlags) 1007 1008 fmt.Fprintf(h, "pkg %q\n", a.Deps[0].actionID) 1009 for _, a1 := range a.Deps { 1010 if a1.Mode == "vet" && a1.built != "" { 1011 fmt.Fprintf(h, "vetout %q %s\n", a1.Package.ImportPath, b.fileHash(a1.built)) 1012 vcfg.PackageVetx[a1.Package.ImportPath] = a1.built 1013 } 1014 } 1015 key := cache.ActionID(h.Sum()) 1016 1017 if vcfg.VetxOnly { 1018 if c := cache.Default(); c != nil && !cfg.BuildA { 1019 if file, _, err := c.GetFile(key); err == nil { 1020 a.built = file 1021 return nil 1022 } 1023 } 1024 } 1025 1026 // TODO(adonovan): delete this when we use the new vet printf checker. 1027 // https://github.com/golang/go/issues/28756 1028 if vcfg.ImportMap["fmt"] == "" { 1029 a1 := a.Deps[1] 1030 vcfg.ImportMap["fmt"] = "fmt" 1031 if a1.built != "" { 1032 vcfg.PackageFile["fmt"] = a1.built 1033 } 1034 vcfg.Standard["fmt"] = true 1035 } 1036 1037 // During go test, ignore type-checking failures during vet. 1038 // We only run vet if the compilation has succeeded, 1039 // so at least for now assume the bug is in vet. 1040 // We know of at least #18395. 1041 // TODO(rsc,gri): Try to remove this for Go 1.11. 1042 // 1043 // Disabled 2018-04-20. Let's see if we can do without it. 1044 // vcfg.SucceedOnTypecheckFailure = cfg.CmdName == "test" 1045 1046 js, err := json.MarshalIndent(vcfg, "", "\t") 1047 if err != nil { 1048 return fmt.Errorf("internal error marshaling vet config: %v", err) 1049 } 1050 js = append(js, '\n') 1051 if err := b.writeFile(a.Objdir+"vet.cfg", js); err != nil { 1052 return err 1053 } 1054 1055 env := b.cCompilerEnv() 1056 if cfg.BuildToolchainName == "gccgo" { 1057 env = append(env, "GCCGO="+BuildToolchain.compiler()) 1058 } 1059 1060 p := a.Package 1061 tool := VetTool 1062 if tool == "" { 1063 tool = base.Tool("vet") 1064 } 1065 runErr := b.run(a, p.Dir, p.ImportPath, env, cfg.BuildToolexec, tool, VetFlags, a.Objdir+"vet.cfg") 1066 1067 // If vet wrote export data, save it for input to future vets. 1068 if f, err := os.Open(vcfg.VetxOutput); err == nil { 1069 a.built = vcfg.VetxOutput 1070 if c := cache.Default(); c != nil { 1071 c.Put(key, f) 1072 } 1073 f.Close() 1074 } 1075 1076 return runErr 1077 } 1078 1079 // linkActionID computes the action ID for a link action. 1080 func (b *Builder) linkActionID(a *Action) cache.ActionID { 1081 p := a.Package 1082 h := cache.NewHash("link " + p.ImportPath) 1083 1084 // Toolchain-independent configuration. 1085 fmt.Fprintf(h, "link\n") 1086 fmt.Fprintf(h, "buildmode %s goos %s goarch %s\n", cfg.BuildBuildmode, cfg.Goos, cfg.Goarch) 1087 fmt.Fprintf(h, "import %q\n", p.ImportPath) 1088 fmt.Fprintf(h, "omitdebug %v standard %v local %v prefix %q\n", p.Internal.OmitDebug, p.Standard, p.Internal.Local, p.Internal.LocalPrefix) 1089 1090 // Toolchain-dependent configuration, shared with b.linkSharedActionID. 1091 b.printLinkerConfig(h, p) 1092 1093 // Input files. 1094 for _, a1 := range a.Deps { 1095 p1 := a1.Package 1096 if p1 != nil { 1097 if a1.built != "" || a1.buildID != "" { 1098 buildID := a1.buildID 1099 if buildID == "" { 1100 buildID = b.buildID(a1.built) 1101 } 1102 fmt.Fprintf(h, "packagefile %s=%s\n", p1.ImportPath, contentID(buildID)) 1103 } 1104 // Because we put package main's full action ID into the binary's build ID, 1105 // we must also put the full action ID into the binary's action ID hash. 1106 if p1.Name == "main" { 1107 fmt.Fprintf(h, "packagemain %s\n", a1.buildID) 1108 } 1109 if p1.Shlib != "" { 1110 fmt.Fprintf(h, "packageshlib %s=%s\n", p1.ImportPath, contentID(b.buildID(p1.Shlib))) 1111 } 1112 } 1113 } 1114 1115 return h.Sum() 1116 } 1117 1118 // printLinkerConfig prints the linker config into the hash h, 1119 // as part of the computation of a linker-related action ID. 1120 func (b *Builder) printLinkerConfig(h io.Writer, p *load.Package) { 1121 switch cfg.BuildToolchainName { 1122 default: 1123 base.Fatalf("linkActionID: unknown toolchain %q", cfg.BuildToolchainName) 1124 1125 case "gc": 1126 fmt.Fprintf(h, "link %s %q %s\n", b.toolID("link"), forcedLdflags, ldBuildmode) 1127 if p != nil { 1128 fmt.Fprintf(h, "linkflags %q\n", p.Internal.Ldflags) 1129 } 1130 fmt.Fprintf(h, "GO$GOARCH=%s\n", os.Getenv("GO"+strings.ToUpper(cfg.BuildContext.GOARCH))) // GO386, GOARM, etc 1131 1132 // The linker writes source file paths that say GOROOT_FINAL. 1133 fmt.Fprintf(h, "GOROOT=%s\n", cfg.GOROOT_FINAL) 1134 1135 // TODO(rsc): Convince linker team not to add more magic environment variables, 1136 // or perhaps restrict the environment variables passed to subprocesses. 1137 magic := []string{ 1138 "GO_EXTLINK_ENABLED", 1139 } 1140 for _, env := range magic { 1141 if x := os.Getenv(env); x != "" { 1142 fmt.Fprintf(h, "magic %s=%s\n", env, x) 1143 } 1144 } 1145 1146 // TODO(rsc): Do cgo settings and flags need to be included? 1147 // Or external linker settings and flags? 1148 1149 case "gccgo": 1150 id, err := b.gccgoToolID(BuildToolchain.linker(), "go") 1151 if err != nil { 1152 base.Fatalf("%v", err) 1153 } 1154 fmt.Fprintf(h, "link %s %s\n", id, ldBuildmode) 1155 // TODO(iant): Should probably include cgo flags here. 1156 } 1157 } 1158 1159 // link is the action for linking a single command. 1160 // Note that any new influence on this logic must be reported in b.linkActionID above as well. 1161 func (b *Builder) link(a *Action) (err error) { 1162 if b.useCache(a, a.Package, b.linkActionID(a), a.Package.Target) || b.IsCmdList { 1163 return nil 1164 } 1165 defer b.flushOutput(a) 1166 1167 if err := b.Mkdir(a.Objdir); err != nil { 1168 return err 1169 } 1170 1171 importcfg := a.Objdir + "importcfg.link" 1172 if err := b.writeLinkImportcfg(a, importcfg); err != nil { 1173 return err 1174 } 1175 1176 // make target directory 1177 dir, _ := filepath.Split(a.Target) 1178 if dir != "" { 1179 if err := b.Mkdir(dir); err != nil { 1180 return err 1181 } 1182 } 1183 1184 if err := BuildToolchain.ld(b, a, a.Target, importcfg, a.Deps[0].built); err != nil { 1185 return err 1186 } 1187 1188 // Update the binary with the final build ID. 1189 // But if OmitDebug is set, don't rewrite the binary, because we set OmitDebug 1190 // on binaries that we are going to run and then delete. 1191 // There's no point in doing work on such a binary. 1192 // Worse, opening the binary for write here makes it 1193 // essentially impossible to safely fork+exec due to a fundamental 1194 // incompatibility between ETXTBSY and threads on modern Unix systems. 1195 // See golang.org/issue/22220. 1196 // We still call updateBuildID to update a.buildID, which is important 1197 // for test result caching, but passing rewrite=false (final arg) 1198 // means we don't actually rewrite the binary, nor store the 1199 // result into the cache. That's probably a net win: 1200 // less cache space wasted on large binaries we are not likely to 1201 // need again. (On the other hand it does make repeated go test slower.) 1202 // It also makes repeated go run slower, which is a win in itself: 1203 // we don't want people to treat go run like a scripting environment. 1204 if err := b.updateBuildID(a, a.Target, !a.Package.Internal.OmitDebug); err != nil { 1205 return err 1206 } 1207 1208 a.built = a.Target 1209 return nil 1210 } 1211 1212 func (b *Builder) writeLinkImportcfg(a *Action, file string) error { 1213 // Prepare Go import cfg. 1214 var icfg bytes.Buffer 1215 for _, a1 := range a.Deps { 1216 p1 := a1.Package 1217 if p1 == nil { 1218 continue 1219 } 1220 fmt.Fprintf(&icfg, "packagefile %s=%s\n", p1.ImportPath, a1.built) 1221 if p1.Shlib != "" { 1222 fmt.Fprintf(&icfg, "packageshlib %s=%s\n", p1.ImportPath, p1.Shlib) 1223 } 1224 } 1225 return b.writeFile(file, icfg.Bytes()) 1226 } 1227 1228 // PkgconfigCmd returns a pkg-config binary name 1229 // defaultPkgConfig is defined in zdefaultcc.go, written by cmd/dist. 1230 func (b *Builder) PkgconfigCmd() string { 1231 return envList("PKG_CONFIG", cfg.DefaultPkgConfig)[0] 1232 } 1233 1234 // splitPkgConfigOutput parses the pkg-config output into a slice of 1235 // flags. This implements the algorithm from pkgconf/libpkgconf/argvsplit.c. 1236 func splitPkgConfigOutput(out []byte) ([]string, error) { 1237 if len(out) == 0 { 1238 return nil, nil 1239 } 1240 var flags []string 1241 flag := make([]byte, 0, len(out)) 1242 escaped := false 1243 quote := byte(0) 1244 1245 for _, c := range out { 1246 if escaped { 1247 if quote != 0 { 1248 switch c { 1249 case '$', '`', '"', '\\': 1250 default: 1251 flag = append(flag, '\\') 1252 } 1253 flag = append(flag, c) 1254 } else { 1255 flag = append(flag, c) 1256 } 1257 escaped = false 1258 } else if quote != 0 { 1259 if c == quote { 1260 quote = 0 1261 } else { 1262 switch c { 1263 case '\\': 1264 escaped = true 1265 default: 1266 flag = append(flag, c) 1267 } 1268 } 1269 } else if strings.IndexByte(" \t\n\v\f\r", c) < 0 { 1270 switch c { 1271 case '\\': 1272 escaped = true 1273 case '\'', '"': 1274 quote = c 1275 default: 1276 flag = append(flag, c) 1277 } 1278 } else if len(flag) != 0 { 1279 flags = append(flags, string(flag)) 1280 flag = flag[:0] 1281 } 1282 } 1283 if escaped { 1284 return nil, errors.New("broken character escaping in pkgconf output ") 1285 } 1286 if quote != 0 { 1287 return nil, errors.New("unterminated quoted string in pkgconf output ") 1288 } else if len(flag) != 0 { 1289 flags = append(flags, string(flag)) 1290 } 1291 1292 return flags, nil 1293 } 1294 1295 // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package. 1296 func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, err error) { 1297 if pcargs := p.CgoPkgConfig; len(pcargs) > 0 { 1298 // pkg-config permits arguments to appear anywhere in 1299 // the command line. Move them all to the front, before --. 1300 var pcflags []string 1301 var pkgs []string 1302 for _, pcarg := range pcargs { 1303 if pcarg == "--" { 1304 // We're going to add our own "--" argument. 1305 } else if strings.HasPrefix(pcarg, "--") { 1306 pcflags = append(pcflags, pcarg) 1307 } else { 1308 pkgs = append(pkgs, pcarg) 1309 } 1310 } 1311 for _, pkg := range pkgs { 1312 if !load.SafeArg(pkg) { 1313 return nil, nil, fmt.Errorf("invalid pkg-config package name: %s", pkg) 1314 } 1315 } 1316 var out []byte 1317 out, err = b.runOut(p.Dir, nil, b.PkgconfigCmd(), "--cflags", pcflags, "--", pkgs) 1318 if err != nil { 1319 b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --cflags "+strings.Join(pcflags, " ")+" -- "+strings.Join(pkgs, " "), string(out)) 1320 b.Print(err.Error() + "\n") 1321 return nil, nil, errPrintedOutput 1322 } 1323 if len(out) > 0 { 1324 cflags, err = splitPkgConfigOutput(out) 1325 if err != nil { 1326 return nil, nil, err 1327 } 1328 if err := checkCompilerFlags("CFLAGS", "pkg-config --cflags", cflags); err != nil { 1329 return nil, nil, err 1330 } 1331 } 1332 out, err = b.runOut(p.Dir, nil, b.PkgconfigCmd(), "--libs", pcflags, "--", pkgs) 1333 if err != nil { 1334 b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pcflags, " ")+" -- "+strings.Join(pkgs, " "), string(out)) 1335 b.Print(err.Error() + "\n") 1336 return nil, nil, errPrintedOutput 1337 } 1338 if len(out) > 0 { 1339 ldflags = strings.Fields(string(out)) 1340 if err := checkLinkerFlags("LDFLAGS", "pkg-config --libs", ldflags); err != nil { 1341 return nil, nil, err 1342 } 1343 } 1344 } 1345 1346 return 1347 } 1348 1349 func (b *Builder) installShlibname(a *Action) error { 1350 // TODO: BuildN 1351 a1 := a.Deps[0] 1352 err := ioutil.WriteFile(a.Target, []byte(filepath.Base(a1.Target)+"\n"), 0666) 1353 if err != nil { 1354 return err 1355 } 1356 if cfg.BuildX { 1357 b.Showcmd("", "echo '%s' > %s # internal", filepath.Base(a1.Target), a.Target) 1358 } 1359 return nil 1360 } 1361 1362 func (b *Builder) linkSharedActionID(a *Action) cache.ActionID { 1363 h := cache.NewHash("linkShared") 1364 1365 // Toolchain-independent configuration. 1366 fmt.Fprintf(h, "linkShared\n") 1367 fmt.Fprintf(h, "goos %s goarch %s\n", cfg.Goos, cfg.Goarch) 1368 1369 // Toolchain-dependent configuration, shared with b.linkActionID. 1370 b.printLinkerConfig(h, nil) 1371 1372 // Input files. 1373 for _, a1 := range a.Deps { 1374 p1 := a1.Package 1375 if a1.built == "" { 1376 continue 1377 } 1378 if p1 != nil { 1379 fmt.Fprintf(h, "packagefile %s=%s\n", p1.ImportPath, contentID(b.buildID(a1.built))) 1380 if p1.Shlib != "" { 1381 fmt.Fprintf(h, "packageshlib %s=%s\n", p1.ImportPath, contentID(b.buildID(p1.Shlib))) 1382 } 1383 } 1384 } 1385 // Files named on command line are special. 1386 for _, a1 := range a.Deps[0].Deps { 1387 p1 := a1.Package 1388 fmt.Fprintf(h, "top %s=%s\n", p1.ImportPath, contentID(b.buildID(a1.built))) 1389 } 1390 1391 return h.Sum() 1392 } 1393 1394 func (b *Builder) linkShared(a *Action) (err error) { 1395 if b.useCache(a, nil, b.linkSharedActionID(a), a.Target) || b.IsCmdList { 1396 return nil 1397 } 1398 defer b.flushOutput(a) 1399 1400 if err := b.Mkdir(a.Objdir); err != nil { 1401 return err 1402 } 1403 1404 importcfg := a.Objdir + "importcfg.link" 1405 if err := b.writeLinkImportcfg(a, importcfg); err != nil { 1406 return err 1407 } 1408 1409 // TODO(rsc): There is a missing updateBuildID here, 1410 // but we have to decide where to store the build ID in these files. 1411 a.built = a.Target 1412 return BuildToolchain.ldShared(b, a, a.Deps[0].Deps, a.Target, importcfg, a.Deps) 1413 } 1414 1415 // BuildInstallFunc is the action for installing a single package or executable. 1416 func BuildInstallFunc(b *Builder, a *Action) (err error) { 1417 defer func() { 1418 if err != nil && err != errPrintedOutput { 1419 // a.Package == nil is possible for the go install -buildmode=shared 1420 // action that installs libmangledname.so, which corresponds to 1421 // a list of packages, not just one. 1422 sep, path := "", "" 1423 if a.Package != nil { 1424 sep, path = " ", a.Package.ImportPath 1425 } 1426 err = fmt.Errorf("go %s%s%s: %v", cfg.CmdName, sep, path, err) 1427 } 1428 }() 1429 1430 a1 := a.Deps[0] 1431 a.buildID = a1.buildID 1432 1433 // If we are using the eventual install target as an up-to-date 1434 // cached copy of the thing we built, then there's no need to 1435 // copy it into itself (and that would probably fail anyway). 1436 // In this case a1.built == a.Target because a1.built == p.Target, 1437 // so the built target is not in the a1.Objdir tree that b.cleanup(a1) removes. 1438 if a1.built == a.Target { 1439 a.built = a.Target 1440 if !a.buggyInstall { 1441 b.cleanup(a1) 1442 } 1443 // Whether we're smart enough to avoid a complete rebuild 1444 // depends on exactly what the staleness and rebuild algorithms 1445 // are, as well as potentially the state of the Go build cache. 1446 // We don't really want users to be able to infer (or worse start depending on) 1447 // those details from whether the modification time changes during 1448 // "go install", so do a best-effort update of the file times to make it 1449 // look like we rewrote a.Target even if we did not. Updating the mtime 1450 // may also help other mtime-based systems that depend on our 1451 // previous mtime updates that happened more often. 1452 // This is still not perfect - we ignore the error result, and if the file was 1453 // unwritable for some reason then pretending to have written it is also 1454 // confusing - but it's probably better than not doing the mtime update. 1455 // 1456 // But don't do that for the special case where building an executable 1457 // with -linkshared implicitly installs all its dependent libraries. 1458 // We want to hide that awful detail as much as possible, so don't 1459 // advertise it by touching the mtimes (usually the libraries are up 1460 // to date). 1461 if !a.buggyInstall && !b.IsCmdList { 1462 now := time.Now() 1463 os.Chtimes(a.Target, now, now) 1464 } 1465 return nil 1466 } 1467 1468 // If we're building for go list -export, 1469 // never install anything; just keep the cache reference. 1470 if b.IsCmdList { 1471 a.built = a1.built 1472 return nil 1473 } 1474 1475 if err := b.Mkdir(a.Objdir); err != nil { 1476 return err 1477 } 1478 1479 perm := os.FileMode(0666) 1480 if a1.Mode == "link" { 1481 switch cfg.BuildBuildmode { 1482 case "c-archive", "c-shared", "plugin": 1483 default: 1484 perm = 0777 1485 } 1486 } 1487 1488 // make target directory 1489 dir, _ := filepath.Split(a.Target) 1490 if dir != "" { 1491 if err := b.Mkdir(dir); err != nil { 1492 return err 1493 } 1494 } 1495 1496 if !a.buggyInstall { 1497 defer b.cleanup(a1) 1498 } 1499 1500 return b.moveOrCopyFile(a.Target, a1.built, perm, false) 1501 } 1502 1503 // cleanup removes a's object dir to keep the amount of 1504 // on-disk garbage down in a large build. On an operating system 1505 // with aggressive buffering, cleaning incrementally like 1506 // this keeps the intermediate objects from hitting the disk. 1507 func (b *Builder) cleanup(a *Action) { 1508 if !cfg.BuildWork { 1509 if cfg.BuildX { 1510 // Don't say we are removing the directory if 1511 // we never created it. 1512 if _, err := os.Stat(a.Objdir); err == nil || cfg.BuildN { 1513 b.Showcmd("", "rm -r %s", a.Objdir) 1514 } 1515 } 1516 os.RemoveAll(a.Objdir) 1517 } 1518 } 1519 1520 // moveOrCopyFile is like 'mv src dst' or 'cp src dst'. 1521 func (b *Builder) moveOrCopyFile(dst, src string, perm os.FileMode, force bool) error { 1522 if cfg.BuildN { 1523 b.Showcmd("", "mv %s %s", src, dst) 1524 return nil 1525 } 1526 1527 // If we can update the mode and rename to the dst, do it. 1528 // Otherwise fall back to standard copy. 1529 1530 // If the source is in the build cache, we need to copy it. 1531 if strings.HasPrefix(src, cache.DefaultDir()) { 1532 return b.copyFile(dst, src, perm, force) 1533 } 1534 1535 // On Windows, always copy the file, so that we respect the NTFS 1536 // permissions of the parent folder. https://golang.org/issue/22343. 1537 // What matters here is not cfg.Goos (the system we are building 1538 // for) but runtime.GOOS (the system we are building on). 1539 if runtime.GOOS == "windows" { 1540 return b.copyFile(dst, src, perm, force) 1541 } 1542 1543 // If the destination directory has the group sticky bit set, 1544 // we have to copy the file to retain the correct permissions. 1545 // https://golang.org/issue/18878 1546 if fi, err := os.Stat(filepath.Dir(dst)); err == nil { 1547 if fi.IsDir() && (fi.Mode()&os.ModeSetgid) != 0 { 1548 return b.copyFile(dst, src, perm, force) 1549 } 1550 } 1551 1552 // The perm argument is meant to be adjusted according to umask, 1553 // but we don't know what the umask is. 1554 // Create a dummy file to find out. 1555 // This avoids build tags and works even on systems like Plan 9 1556 // where the file mask computation incorporates other information. 1557 mode := perm 1558 f, err := os.OpenFile(filepath.Clean(dst)+"-go-tmp-umask", os.O_WRONLY|os.O_CREATE|os.O_EXCL, perm) 1559 if err == nil { 1560 fi, err := f.Stat() 1561 if err == nil { 1562 mode = fi.Mode() & 0777 1563 } 1564 name := f.Name() 1565 f.Close() 1566 os.Remove(name) 1567 } 1568 1569 if err := os.Chmod(src, mode); err == nil { 1570 if err := os.Rename(src, dst); err == nil { 1571 if cfg.BuildX { 1572 b.Showcmd("", "mv %s %s", src, dst) 1573 } 1574 return nil 1575 } 1576 } 1577 1578 return b.copyFile(dst, src, perm, force) 1579 } 1580 1581 // copyFile is like 'cp src dst'. 1582 func (b *Builder) copyFile(dst, src string, perm os.FileMode, force bool) error { 1583 if cfg.BuildN || cfg.BuildX { 1584 b.Showcmd("", "cp %s %s", src, dst) 1585 if cfg.BuildN { 1586 return nil 1587 } 1588 } 1589 1590 sf, err := os.Open(src) 1591 if err != nil { 1592 return err 1593 } 1594 defer sf.Close() 1595 1596 // Be careful about removing/overwriting dst. 1597 // Do not remove/overwrite if dst exists and is a directory 1598 // or a non-object file. 1599 if fi, err := os.Stat(dst); err == nil { 1600 if fi.IsDir() { 1601 return fmt.Errorf("build output %q already exists and is a directory", dst) 1602 } 1603 if !force && fi.Mode().IsRegular() && !isObject(dst) { 1604 return fmt.Errorf("build output %q already exists and is not an object file", dst) 1605 } 1606 } 1607 1608 // On Windows, remove lingering ~ file from last attempt. 1609 if base.ToolIsWindows { 1610 if _, err := os.Stat(dst + "~"); err == nil { 1611 os.Remove(dst + "~") 1612 } 1613 } 1614 1615 mayberemovefile(dst) 1616 df, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) 1617 if err != nil && base.ToolIsWindows { 1618 // Windows does not allow deletion of a binary file 1619 // while it is executing. Try to move it out of the way. 1620 // If the move fails, which is likely, we'll try again the 1621 // next time we do an install of this binary. 1622 if err := os.Rename(dst, dst+"~"); err == nil { 1623 os.Remove(dst + "~") 1624 } 1625 df, err = os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) 1626 } 1627 if err != nil { 1628 return err 1629 } 1630 1631 _, err = io.Copy(df, sf) 1632 df.Close() 1633 if err != nil { 1634 mayberemovefile(dst) 1635 return fmt.Errorf("copying %s to %s: %v", src, dst, err) 1636 } 1637 return nil 1638 } 1639 1640 // writeFile writes the text to file. 1641 func (b *Builder) writeFile(file string, text []byte) error { 1642 if cfg.BuildN || cfg.BuildX { 1643 b.Showcmd("", "cat >%s << 'EOF' # internal\n%sEOF", file, text) 1644 } 1645 if cfg.BuildN { 1646 return nil 1647 } 1648 return ioutil.WriteFile(file, text, 0666) 1649 } 1650 1651 // appendFile appends the text to file. 1652 func (b *Builder) appendFile(file string, text []byte) error { 1653 if cfg.BuildN || cfg.BuildX { 1654 b.Showcmd("", "cat >>%s << 'EOF' # internal\n%sEOF", file, text) 1655 } 1656 if cfg.BuildN { 1657 return nil 1658 } 1659 f, err := os.OpenFile(file, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) 1660 if err != nil { 1661 return err 1662 } 1663 defer f.Close() 1664 if _, err = f.Write(text); err != nil { 1665 return err 1666 } 1667 return f.Close() 1668 } 1669 1670 // Install the cgo export header file, if there is one. 1671 func (b *Builder) installHeader(a *Action) error { 1672 src := a.Objdir + "_cgo_install.h" 1673 if _, err := os.Stat(src); os.IsNotExist(err) { 1674 // If the file does not exist, there are no exported 1675 // functions, and we do not install anything. 1676 // TODO(rsc): Once we know that caching is rebuilding 1677 // at the right times (not missing rebuilds), here we should 1678 // probably delete the installed header, if any. 1679 if cfg.BuildX { 1680 b.Showcmd("", "# %s not created", src) 1681 } 1682 return nil 1683 } 1684 1685 dir, _ := filepath.Split(a.Target) 1686 if dir != "" { 1687 if err := b.Mkdir(dir); err != nil { 1688 return err 1689 } 1690 } 1691 1692 return b.moveOrCopyFile(a.Target, src, 0666, true) 1693 } 1694 1695 // cover runs, in effect, 1696 // go tool cover -mode=b.coverMode -var="varName" -o dst.go src.go 1697 func (b *Builder) cover(a *Action, dst, src string, varName string) error { 1698 return b.run(a, a.Objdir, "cover "+a.Package.ImportPath, nil, 1699 cfg.BuildToolexec, 1700 base.Tool("cover"), 1701 "-mode", a.Package.Internal.CoverMode, 1702 "-var", varName, 1703 "-o", dst, 1704 src) 1705 } 1706 1707 var objectMagic = [][]byte{ 1708 {'!', '<', 'a', 'r', 'c', 'h', '>', '\n'}, // Package archive 1709 {'<', 'b', 'i', 'g', 'a', 'f', '>', '\n'}, // Package AIX big archive 1710 {'\x7F', 'E', 'L', 'F'}, // ELF 1711 {0xFE, 0xED, 0xFA, 0xCE}, // Mach-O big-endian 32-bit 1712 {0xFE, 0xED, 0xFA, 0xCF}, // Mach-O big-endian 64-bit 1713 {0xCE, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 32-bit 1714 {0xCF, 0xFA, 0xED, 0xFE}, // Mach-O little-endian 64-bit 1715 {0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00}, // PE (Windows) as generated by 6l/8l and gcc 1716 {0x00, 0x00, 0x01, 0xEB}, // Plan 9 i386 1717 {0x00, 0x00, 0x8a, 0x97}, // Plan 9 amd64 1718 {0x00, 0x00, 0x06, 0x47}, // Plan 9 arm 1719 {0x00, 0x61, 0x73, 0x6D}, // WASM 1720 {0x01, 0xDF}, // XCOFF 32bit 1721 {0x01, 0xF7}, // XCOFF 64bit 1722 } 1723 1724 func isObject(s string) bool { 1725 f, err := os.Open(s) 1726 if err != nil { 1727 return false 1728 } 1729 defer f.Close() 1730 buf := make([]byte, 64) 1731 io.ReadFull(f, buf) 1732 for _, magic := range objectMagic { 1733 if bytes.HasPrefix(buf, magic) { 1734 return true 1735 } 1736 } 1737 return false 1738 } 1739 1740 // mayberemovefile removes a file only if it is a regular file 1741 // When running as a user with sufficient privileges, we may delete 1742 // even device files, for example, which is not intended. 1743 func mayberemovefile(s string) { 1744 if fi, err := os.Lstat(s); err == nil && !fi.Mode().IsRegular() { 1745 return 1746 } 1747 os.Remove(s) 1748 } 1749 1750 // fmtcmd formats a command in the manner of fmt.Sprintf but also: 1751 // 1752 // If dir is non-empty and the script is not in dir right now, 1753 // fmtcmd inserts "cd dir\n" before the command. 1754 // 1755 // fmtcmd replaces the value of b.WorkDir with $WORK. 1756 // fmtcmd replaces the value of goroot with $GOROOT. 1757 // fmtcmd replaces the value of b.gobin with $GOBIN. 1758 // 1759 // fmtcmd replaces the name of the current directory with dot (.) 1760 // but only when it is at the beginning of a space-separated token. 1761 // 1762 func (b *Builder) fmtcmd(dir string, format string, args ...interface{}) string { 1763 cmd := fmt.Sprintf(format, args...) 1764 if dir != "" && dir != "/" { 1765 dot := " ." 1766 if dir[len(dir)-1] == filepath.Separator { 1767 dot += string(filepath.Separator) 1768 } 1769 cmd = strings.ReplaceAll(" "+cmd, " "+dir, dot)[1:] 1770 if b.scriptDir != dir { 1771 b.scriptDir = dir 1772 cmd = "cd " + dir + "\n" + cmd 1773 } 1774 } 1775 if b.WorkDir != "" { 1776 cmd = strings.ReplaceAll(cmd, b.WorkDir, "$WORK") 1777 } 1778 return cmd 1779 } 1780 1781 // showcmd prints the given command to standard output 1782 // for the implementation of -n or -x. 1783 func (b *Builder) Showcmd(dir string, format string, args ...interface{}) { 1784 b.output.Lock() 1785 defer b.output.Unlock() 1786 b.Print(b.fmtcmd(dir, format, args...) + "\n") 1787 } 1788 1789 // showOutput prints "# desc" followed by the given output. 1790 // The output is expected to contain references to 'dir', usually 1791 // the source directory for the package that has failed to build. 1792 // showOutput rewrites mentions of dir with a relative path to dir 1793 // when the relative path is shorter. This is usually more pleasant. 1794 // For example, if fmt doesn't compile and we are in src/html, 1795 // the output is 1796 // 1797 // $ go build 1798 // # fmt 1799 // ../fmt/print.go:1090: undefined: asdf 1800 // $ 1801 // 1802 // instead of 1803 // 1804 // $ go build 1805 // # fmt 1806 // /usr/gopher/go/src/fmt/print.go:1090: undefined: asdf 1807 // $ 1808 // 1809 // showOutput also replaces references to the work directory with $WORK. 1810 // 1811 // If a is not nil and a.output is not nil, showOutput appends to that slice instead of 1812 // printing to b.Print. 1813 // 1814 func (b *Builder) showOutput(a *Action, dir, desc, out string) { 1815 prefix := "# " + desc 1816 suffix := "\n" + out 1817 if reldir := base.ShortPath(dir); reldir != dir { 1818 suffix = strings.ReplaceAll(suffix, " "+dir, " "+reldir) 1819 suffix = strings.ReplaceAll(suffix, "\n"+dir, "\n"+reldir) 1820 } 1821 suffix = strings.ReplaceAll(suffix, " "+b.WorkDir, " $WORK") 1822 1823 if a != nil && a.output != nil { 1824 a.output = append(a.output, prefix...) 1825 a.output = append(a.output, suffix...) 1826 return 1827 } 1828 1829 b.output.Lock() 1830 defer b.output.Unlock() 1831 b.Print(prefix, suffix) 1832 } 1833 1834 // errPrintedOutput is a special error indicating that a command failed 1835 // but that it generated output as well, and that output has already 1836 // been printed, so there's no point showing 'exit status 1' or whatever 1837 // the wait status was. The main executor, builder.do, knows not to 1838 // print this error. 1839 var errPrintedOutput = errors.New("already printed output - no need to show error") 1840 1841 var cgoLine = regexp.MustCompile(`\[[^\[\]]+\.(cgo1|cover)\.go:[0-9]+(:[0-9]+)?\]`) 1842 var cgoTypeSigRe = regexp.MustCompile(`\b_C2?(type|func|var|macro)_\B`) 1843 1844 // run runs the command given by cmdline in the directory dir. 1845 // If the command fails, run prints information about the failure 1846 // and returns a non-nil error. 1847 func (b *Builder) run(a *Action, dir string, desc string, env []string, cmdargs ...interface{}) error { 1848 out, err := b.runOut(dir, env, cmdargs...) 1849 if len(out) > 0 { 1850 if desc == "" { 1851 desc = b.fmtcmd(dir, "%s", strings.Join(str.StringList(cmdargs...), " ")) 1852 } 1853 b.showOutput(a, dir, desc, b.processOutput(out)) 1854 if err != nil { 1855 err = errPrintedOutput 1856 } 1857 } 1858 return err 1859 } 1860 1861 // processOutput prepares the output of runOut to be output to the console. 1862 func (b *Builder) processOutput(out []byte) string { 1863 if out[len(out)-1] != '\n' { 1864 out = append(out, '\n') 1865 } 1866 messages := string(out) 1867 // Fix up output referring to cgo-generated code to be more readable. 1868 // Replace x.go:19[/tmp/.../x.cgo1.go:18] with x.go:19. 1869 // Replace *[100]_Ctype_foo with *[100]C.foo. 1870 // If we're using -x, assume we're debugging and want the full dump, so disable the rewrite. 1871 if !cfg.BuildX && cgoLine.MatchString(messages) { 1872 messages = cgoLine.ReplaceAllString(messages, "") 1873 messages = cgoTypeSigRe.ReplaceAllString(messages, "C.") 1874 } 1875 return messages 1876 } 1877 1878 // runOut runs the command given by cmdline in the directory dir. 1879 // It returns the command output and any errors that occurred. 1880 func (b *Builder) runOut(dir string, env []string, cmdargs ...interface{}) ([]byte, error) { 1881 cmdline := str.StringList(cmdargs...) 1882 1883 for _, arg := range cmdline { 1884 // GNU binutils commands, including gcc and gccgo, interpret an argument 1885 // @foo anywhere in the command line (even following --) as meaning 1886 // "read and insert arguments from the file named foo." 1887 // Don't say anything that might be misinterpreted that way. 1888 if strings.HasPrefix(arg, "@") { 1889 return nil, fmt.Errorf("invalid command-line argument %s in command: %s", arg, joinUnambiguously(cmdline)) 1890 } 1891 } 1892 1893 if cfg.BuildN || cfg.BuildX { 1894 var envcmdline string 1895 for _, e := range env { 1896 if j := strings.IndexByte(e, '='); j != -1 { 1897 if strings.ContainsRune(e[j+1:], '\'') { 1898 envcmdline += fmt.Sprintf("%s=%q", e[:j], e[j+1:]) 1899 } else { 1900 envcmdline += fmt.Sprintf("%s='%s'", e[:j], e[j+1:]) 1901 } 1902 envcmdline += " " 1903 } 1904 } 1905 envcmdline += joinUnambiguously(cmdline) 1906 b.Showcmd(dir, "%s", envcmdline) 1907 if cfg.BuildN { 1908 return nil, nil 1909 } 1910 } 1911 1912 var buf bytes.Buffer 1913 cmd := exec.Command(cmdline[0], cmdline[1:]...) 1914 cmd.Stdout = &buf 1915 cmd.Stderr = &buf 1916 cleanup := passLongArgsInResponseFiles(cmd) 1917 defer cleanup() 1918 cmd.Dir = dir 1919 cmd.Env = base.MergeEnvLists(env, base.EnvForDir(cmd.Dir, os.Environ())) 1920 err := cmd.Run() 1921 1922 // err can be something like 'exit status 1'. 1923 // Add information about what program was running. 1924 // Note that if buf.Bytes() is non-empty, the caller usually 1925 // shows buf.Bytes() and does not print err at all, so the 1926 // prefix here does not make most output any more verbose. 1927 if err != nil { 1928 err = errors.New(cmdline[0] + ": " + err.Error()) 1929 } 1930 return buf.Bytes(), err 1931 } 1932 1933 // joinUnambiguously prints the slice, quoting where necessary to make the 1934 // output unambiguous. 1935 // TODO: See issue 5279. The printing of commands needs a complete redo. 1936 func joinUnambiguously(a []string) string { 1937 var buf bytes.Buffer 1938 for i, s := range a { 1939 if i > 0 { 1940 buf.WriteByte(' ') 1941 } 1942 q := strconv.Quote(s) 1943 // A gccgo command line can contain -( and -). 1944 // Make sure we quote them since they are special to the shell. 1945 if s == "" || strings.ContainsAny(s, " ()") || len(q) > len(s)+2 { 1946 buf.WriteString(q) 1947 } else { 1948 buf.WriteString(s) 1949 } 1950 } 1951 return buf.String() 1952 } 1953 1954 // cCompilerEnv returns environment variables to set when running the 1955 // C compiler. This is needed to disable escape codes in clang error 1956 // messages that confuse tools like cgo. 1957 func (b *Builder) cCompilerEnv() []string { 1958 return []string{"TERM=dumb"} 1959 } 1960 1961 // mkdir makes the named directory. 1962 func (b *Builder) Mkdir(dir string) error { 1963 // Make Mkdir(a.Objdir) a no-op instead of an error when a.Objdir == "". 1964 if dir == "" { 1965 return nil 1966 } 1967 1968 b.exec.Lock() 1969 defer b.exec.Unlock() 1970 // We can be a little aggressive about being 1971 // sure directories exist. Skip repeated calls. 1972 if b.mkdirCache[dir] { 1973 return nil 1974 } 1975 b.mkdirCache[dir] = true 1976 1977 if cfg.BuildN || cfg.BuildX { 1978 b.Showcmd("", "mkdir -p %s", dir) 1979 if cfg.BuildN { 1980 return nil 1981 } 1982 } 1983 1984 if err := os.MkdirAll(dir, 0777); err != nil { 1985 return err 1986 } 1987 return nil 1988 } 1989 1990 // symlink creates a symlink newname -> oldname. 1991 func (b *Builder) Symlink(oldname, newname string) error { 1992 // It's not an error to try to recreate an existing symlink. 1993 if link, err := os.Readlink(newname); err == nil && link == oldname { 1994 return nil 1995 } 1996 1997 if cfg.BuildN || cfg.BuildX { 1998 b.Showcmd("", "ln -s %s %s", oldname, newname) 1999 if cfg.BuildN { 2000 return nil 2001 } 2002 } 2003 return os.Symlink(oldname, newname) 2004 } 2005 2006 // mkAbs returns an absolute path corresponding to 2007 // evaluating f in the directory dir. 2008 // We always pass absolute paths of source files so that 2009 // the error messages will include the full path to a file 2010 // in need of attention. 2011 func mkAbs(dir, f string) string { 2012 // Leave absolute paths alone. 2013 // Also, during -n mode we use the pseudo-directory $WORK 2014 // instead of creating an actual work directory that won't be used. 2015 // Leave paths beginning with $WORK alone too. 2016 if filepath.IsAbs(f) || strings.HasPrefix(f, "$WORK") { 2017 return f 2018 } 2019 return filepath.Join(dir, f) 2020 } 2021 2022 type toolchain interface { 2023 // gc runs the compiler in a specific directory on a set of files 2024 // and returns the name of the generated output file. 2025 // 2026 // TODO: This argument list is long. Consider putting it in a struct. 2027 gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) 2028 // cc runs the toolchain's C compiler in a directory on a C file 2029 // to produce an output file. 2030 cc(b *Builder, a *Action, ofile, cfile string) error 2031 // asm runs the assembler in a specific directory on specific files 2032 // and returns a list of named output files. 2033 asm(b *Builder, a *Action, sfiles []string) ([]string, error) 2034 // symabis scans the symbol ABIs from sfiles and returns the 2035 // path to the output symbol ABIs file, or "" if none. 2036 symabis(b *Builder, a *Action, sfiles []string) (string, error) 2037 // pack runs the archive packer in a specific directory to create 2038 // an archive from a set of object files. 2039 // typically it is run in the object directory. 2040 pack(b *Builder, a *Action, afile string, ofiles []string) error 2041 // ld runs the linker to create an executable starting at mainpkg. 2042 ld(b *Builder, root *Action, out, importcfg, mainpkg string) error 2043 // ldShared runs the linker to create a shared library containing the pkgs built by toplevelactions 2044 ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error 2045 2046 compiler() string 2047 linker() string 2048 } 2049 2050 type noToolchain struct{} 2051 2052 func noCompiler() error { 2053 log.Fatalf("unknown compiler %q", cfg.BuildContext.Compiler) 2054 return nil 2055 } 2056 2057 func (noToolchain) compiler() string { 2058 noCompiler() 2059 return "" 2060 } 2061 2062 func (noToolchain) linker() string { 2063 noCompiler() 2064 return "" 2065 } 2066 2067 func (noToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, symabis string, asmhdr bool, gofiles []string) (ofile string, out []byte, err error) { 2068 return "", nil, noCompiler() 2069 } 2070 2071 func (noToolchain) asm(b *Builder, a *Action, sfiles []string) ([]string, error) { 2072 return nil, noCompiler() 2073 } 2074 2075 func (noToolchain) symabis(b *Builder, a *Action, sfiles []string) (string, error) { 2076 return "", noCompiler() 2077 } 2078 2079 func (noToolchain) pack(b *Builder, a *Action, afile string, ofiles []string) error { 2080 return noCompiler() 2081 } 2082 2083 func (noToolchain) ld(b *Builder, root *Action, out, importcfg, mainpkg string) error { 2084 return noCompiler() 2085 } 2086 2087 func (noToolchain) ldShared(b *Builder, root *Action, toplevelactions []*Action, out, importcfg string, allactions []*Action) error { 2088 return noCompiler() 2089 } 2090 2091 func (noToolchain) cc(b *Builder, a *Action, ofile, cfile string) error { 2092 return noCompiler() 2093 } 2094 2095 // gcc runs the gcc C compiler to create an object from a single C file. 2096 func (b *Builder) gcc(a *Action, p *load.Package, workdir, out string, flags []string, cfile string) error { 2097 return b.ccompile(a, p, out, flags, cfile, b.GccCmd(p.Dir, workdir)) 2098 } 2099 2100 // gxx runs the g++ C++ compiler to create an object from a single C++ file. 2101 func (b *Builder) gxx(a *Action, p *load.Package, workdir, out string, flags []string, cxxfile string) error { 2102 return b.ccompile(a, p, out, flags, cxxfile, b.GxxCmd(p.Dir, workdir)) 2103 } 2104 2105 // gfortran runs the gfortran Fortran compiler to create an object from a single Fortran file. 2106 func (b *Builder) gfortran(a *Action, p *load.Package, workdir, out string, flags []string, ffile string) error { 2107 return b.ccompile(a, p, out, flags, ffile, b.gfortranCmd(p.Dir, workdir)) 2108 } 2109 2110 // ccompile runs the given C or C++ compiler and creates an object from a single source file. 2111 func (b *Builder) ccompile(a *Action, p *load.Package, outfile string, flags []string, file string, compiler []string) error { 2112 file = mkAbs(p.Dir, file) 2113 desc := p.ImportPath 2114 if !filepath.IsAbs(outfile) { 2115 outfile = filepath.Join(p.Dir, outfile) 2116 } 2117 output, err := b.runOut(filepath.Dir(file), b.cCompilerEnv(), compiler, flags, "-o", outfile, "-c", filepath.Base(file)) 2118 if len(output) > 0 { 2119 // On FreeBSD 11, when we pass -g to clang 3.8 it 2120 // invokes its internal assembler with -dwarf-version=2. 2121 // When it sees .section .note.GNU-stack, it warns 2122 // "DWARF2 only supports one section per compilation unit". 2123 // This warning makes no sense, since the section is empty, 2124 // but it confuses people. 2125 // We work around the problem by detecting the warning 2126 // and dropping -g and trying again. 2127 if bytes.Contains(output, []byte("DWARF2 only supports one section per compilation unit")) { 2128 newFlags := make([]string, 0, len(flags)) 2129 for _, f := range flags { 2130 if !strings.HasPrefix(f, "-g") { 2131 newFlags = append(newFlags, f) 2132 } 2133 } 2134 if len(newFlags) < len(flags) { 2135 return b.ccompile(a, p, outfile, newFlags, file, compiler) 2136 } 2137 } 2138 2139 b.showOutput(a, p.Dir, desc, b.processOutput(output)) 2140 if err != nil { 2141 err = errPrintedOutput 2142 } else if os.Getenv("GO_BUILDER_NAME") != "" { 2143 return errors.New("C compiler warning promoted to error on Go builders") 2144 } 2145 } 2146 return err 2147 } 2148 2149 // gccld runs the gcc linker to create an executable from a set of object files. 2150 func (b *Builder) gccld(p *load.Package, objdir, outfile string, flags []string, objs []string) error { 2151 var cmd []string 2152 if len(p.CXXFiles) > 0 || len(p.SwigCXXFiles) > 0 { 2153 cmd = b.GxxCmd(p.Dir, objdir) 2154 } else { 2155 cmd = b.GccCmd(p.Dir, objdir) 2156 } 2157 2158 cmdargs := []interface{}{cmd, "-o", outfile, objs, flags} 2159 dir := p.Dir 2160 out, err := b.runOut(dir, b.cCompilerEnv(), cmdargs...) 2161 if len(out) > 0 { 2162 // Filter out useless linker warnings caused by bugs outside Go. 2163 // See also cmd/link/internal/ld's hostlink method. 2164 var save [][]byte 2165 for _, line := range bytes.SplitAfter(out, []byte("\n")) { 2166 // golang.org/issue/26073 - Apple Xcode bug 2167 if bytes.Contains(line, []byte("ld: warning: text-based stub file")) { 2168 continue 2169 } 2170 save = append(save, line) 2171 } 2172 out = bytes.Join(save, nil) 2173 if len(out) > 0 { 2174 b.showOutput(nil, dir, p.ImportPath, b.processOutput(out)) 2175 if err != nil { 2176 err = errPrintedOutput 2177 } 2178 } 2179 } 2180 return err 2181 } 2182 2183 // Grab these before main helpfully overwrites them. 2184 var ( 2185 origCC = os.Getenv("CC") 2186 origCXX = os.Getenv("CXX") 2187 ) 2188 2189 // gccCmd returns a gcc command line prefix 2190 // defaultCC is defined in zdefaultcc.go, written by cmd/dist. 2191 func (b *Builder) GccCmd(incdir, workdir string) []string { 2192 return b.compilerCmd(b.ccExe(), incdir, workdir) 2193 } 2194 2195 // gxxCmd returns a g++ command line prefix 2196 // defaultCXX is defined in zdefaultcc.go, written by cmd/dist. 2197 func (b *Builder) GxxCmd(incdir, workdir string) []string { 2198 return b.compilerCmd(b.cxxExe(), incdir, workdir) 2199 } 2200 2201 // gfortranCmd returns a gfortran command line prefix. 2202 func (b *Builder) gfortranCmd(incdir, workdir string) []string { 2203 return b.compilerCmd(b.fcExe(), incdir, workdir) 2204 } 2205 2206 // ccExe returns the CC compiler setting without all the extra flags we add implicitly. 2207 func (b *Builder) ccExe() []string { 2208 return b.compilerExe(origCC, cfg.DefaultCC(cfg.Goos, cfg.Goarch)) 2209 } 2210 2211 // cxxExe returns the CXX compiler setting without all the extra flags we add implicitly. 2212 func (b *Builder) cxxExe() []string { 2213 return b.compilerExe(origCXX, cfg.DefaultCXX(cfg.Goos, cfg.Goarch)) 2214 } 2215 2216 // fcExe returns the FC compiler setting without all the extra flags we add implicitly. 2217 func (b *Builder) fcExe() []string { 2218 return b.compilerExe(os.Getenv("FC"), "gfortran") 2219 } 2220 2221 // compilerExe returns the compiler to use given an 2222 // environment variable setting (the value not the name) 2223 // and a default. The resulting slice is usually just the name 2224 // of the compiler but can have additional arguments if they 2225 // were present in the environment value. 2226 // For example if CC="gcc -DGOPHER" then the result is ["gcc", "-DGOPHER"]. 2227 func (b *Builder) compilerExe(envValue string, def string) []string { 2228 compiler := strings.Fields(envValue) 2229 if len(compiler) == 0 { 2230 compiler = []string{def} 2231 } 2232 return compiler 2233 } 2234 2235 // compilerCmd returns a command line prefix for the given environment 2236 // variable and using the default command when the variable is empty. 2237 func (b *Builder) compilerCmd(compiler []string, incdir, workdir string) []string { 2238 // NOTE: env.go's mkEnv knows that the first three 2239 // strings returned are "gcc", "-I", incdir (and cuts them off). 2240 a := []string{compiler[0], "-I", incdir} 2241 a = append(a, compiler[1:]...) 2242 2243 // Definitely want -fPIC but on Windows gcc complains 2244 // "-fPIC ignored for target (all code is position independent)" 2245 if cfg.Goos != "windows" { 2246 a = append(a, "-fPIC") 2247 } 2248 a = append(a, b.gccArchArgs()...) 2249 // gcc-4.5 and beyond require explicit "-pthread" flag 2250 // for multithreading with pthread library. 2251 if cfg.BuildContext.CgoEnabled { 2252 switch cfg.Goos { 2253 case "windows": 2254 a = append(a, "-mthreads") 2255 default: 2256 a = append(a, "-pthread") 2257 } 2258 } 2259 2260 // disable ASCII art in clang errors, if possible 2261 if b.gccSupportsFlag(compiler, "-fno-caret-diagnostics") { 2262 a = append(a, "-fno-caret-diagnostics") 2263 } 2264 // clang is too smart about command-line arguments 2265 if b.gccSupportsFlag(compiler, "-Qunused-arguments") { 2266 a = append(a, "-Qunused-arguments") 2267 } 2268 2269 // disable word wrapping in error messages 2270 a = append(a, "-fmessage-length=0") 2271 2272 // Tell gcc not to include the work directory in object files. 2273 if b.gccSupportsFlag(compiler, "-fdebug-prefix-map=a=b") { 2274 if workdir == "" { 2275 workdir = b.WorkDir 2276 } 2277 workdir = strings.TrimSuffix(workdir, string(filepath.Separator)) 2278 a = append(a, "-fdebug-prefix-map="+workdir+"=/tmp/go-build") 2279 } 2280 2281 // Tell gcc not to include flags in object files, which defeats the 2282 // point of -fdebug-prefix-map above. 2283 if b.gccSupportsFlag(compiler, "-gno-record-gcc-switches") { 2284 a = append(a, "-gno-record-gcc-switches") 2285 } 2286 2287 // On OS X, some of the compilers behave as if -fno-common 2288 // is always set, and the Mach-O linker in 6l/8l assumes this. 2289 // See https://golang.org/issue/3253. 2290 if cfg.Goos == "darwin" { 2291 a = append(a, "-fno-common") 2292 } 2293 2294 return a 2295 } 2296 2297 // gccNoPie returns the flag to use to request non-PIE. On systems 2298 // with PIE (position independent executables) enabled by default, 2299 // -no-pie must be passed when doing a partial link with -Wl,-r. 2300 // But -no-pie is not supported by all compilers, and clang spells it -nopie. 2301 func (b *Builder) gccNoPie(linker []string) string { 2302 if b.gccSupportsFlag(linker, "-no-pie") { 2303 return "-no-pie" 2304 } 2305 if b.gccSupportsFlag(linker, "-nopie") { 2306 return "-nopie" 2307 } 2308 return "" 2309 } 2310 2311 // gccSupportsFlag checks to see if the compiler supports a flag. 2312 func (b *Builder) gccSupportsFlag(compiler []string, flag string) bool { 2313 key := [2]string{compiler[0], flag} 2314 2315 b.exec.Lock() 2316 defer b.exec.Unlock() 2317 if b, ok := b.flagCache[key]; ok { 2318 return b 2319 } 2320 if b.flagCache == nil { 2321 b.flagCache = make(map[[2]string]bool) 2322 } 2323 // We used to write an empty C file, but that gets complicated with 2324 // go build -n. We tried using a file that does not exist, but that 2325 // fails on systems with GCC version 4.2.1; that is the last GPLv2 2326 // version of GCC, so some systems have frozen on it. 2327 // Now we pass an empty file on stdin, which should work at least for 2328 // GCC and clang. 2329 cmdArgs := str.StringList(compiler, flag, "-c", "-x", "c", "-") 2330 if cfg.BuildN || cfg.BuildX { 2331 b.Showcmd(b.WorkDir, "%s || true", joinUnambiguously(cmdArgs)) 2332 if cfg.BuildN { 2333 return false 2334 } 2335 } 2336 cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...) 2337 cmd.Dir = b.WorkDir 2338 cmd.Env = base.MergeEnvLists([]string{"LC_ALL=C"}, base.EnvForDir(cmd.Dir, os.Environ())) 2339 out, _ := cmd.CombinedOutput() 2340 // GCC says "unrecognized command line option". 2341 // clang says "unknown argument". 2342 // Older versions of GCC say "unrecognised debug output level". 2343 // For -fsplit-stack GCC says "'-fsplit-stack' is not supported". 2344 supported := !bytes.Contains(out, []byte("unrecognized")) && 2345 !bytes.Contains(out, []byte("unknown")) && 2346 !bytes.Contains(out, []byte("unrecognised")) && 2347 !bytes.Contains(out, []byte("is not supported")) 2348 b.flagCache[key] = supported 2349 return supported 2350 } 2351 2352 // gccArchArgs returns arguments to pass to gcc based on the architecture. 2353 func (b *Builder) gccArchArgs() []string { 2354 switch cfg.Goarch { 2355 case "386": 2356 return []string{"-m32"} 2357 case "amd64", "amd64p32": 2358 return []string{"-m64"} 2359 case "arm": 2360 return []string{"-marm"} // not thumb 2361 case "s390x": 2362 return []string{"-m64", "-march=z196"} 2363 case "mips64", "mips64le": 2364 return []string{"-mabi=64"} 2365 case "mips", "mipsle": 2366 return []string{"-mabi=32", "-march=mips32"} 2367 case "ppc64": 2368 if cfg.Goos == "aix" { 2369 return []string{"-maix64"} 2370 } 2371 } 2372 return nil 2373 } 2374 2375 // envList returns the value of the given environment variable broken 2376 // into fields, using the default value when the variable is empty. 2377 func envList(key, def string) []string { 2378 v := os.Getenv(key) 2379 if v == "" { 2380 v = def 2381 } 2382 return strings.Fields(v) 2383 } 2384 2385 // CFlags returns the flags to use when invoking the C, C++ or Fortran compilers, or cgo. 2386 func (b *Builder) CFlags(p *load.Package) (cppflags, cflags, cxxflags, fflags, ldflags []string, err error) { 2387 defaults := "-g -O2" 2388 2389 if cppflags, err = buildFlags("CPPFLAGS", "", p.CgoCPPFLAGS, checkCompilerFlags); err != nil { 2390 return 2391 } 2392 if cflags, err = buildFlags("CFLAGS", defaults, p.CgoCFLAGS, checkCompilerFlags); err != nil { 2393 return 2394 } 2395 if cxxflags, err = buildFlags("CXXFLAGS", defaults, p.CgoCXXFLAGS, checkCompilerFlags); err != nil { 2396 return 2397 } 2398 if fflags, err = buildFlags("FFLAGS", defaults, p.CgoFFLAGS, checkCompilerFlags); err != nil { 2399 return 2400 } 2401 if ldflags, err = buildFlags("LDFLAGS", defaults, p.CgoLDFLAGS, checkLinkerFlags); err != nil { 2402 return 2403 } 2404 2405 return 2406 } 2407 2408 func buildFlags(name, defaults string, fromPackage []string, check func(string, string, []string) error) ([]string, error) { 2409 if err := check(name, "#cgo "+name, fromPackage); err != nil { 2410 return nil, err 2411 } 2412 return str.StringList(envList("CGO_"+name, defaults), fromPackage), nil 2413 } 2414 2415 var cgoRe = regexp.MustCompile(`[/\\:]`) 2416 2417 func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgofiles, gccfiles, gxxfiles, mfiles, ffiles []string) (outGo, outObj []string, err error) { 2418 p := a.Package 2419 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, cgoFFLAGS, cgoLDFLAGS, err := b.CFlags(p) 2420 if err != nil { 2421 return nil, nil, err 2422 } 2423 2424 cgoCPPFLAGS = append(cgoCPPFLAGS, pcCFLAGS...) 2425 cgoLDFLAGS = append(cgoLDFLAGS, pcLDFLAGS...) 2426 // If we are compiling Objective-C code, then we need to link against libobjc 2427 if len(mfiles) > 0 { 2428 cgoLDFLAGS = append(cgoLDFLAGS, "-lobjc") 2429 } 2430 2431 // Likewise for Fortran, except there are many Fortran compilers. 2432 // Support gfortran out of the box and let others pass the correct link options 2433 // via CGO_LDFLAGS 2434 if len(ffiles) > 0 { 2435 fc := os.Getenv("FC") 2436 if fc == "" { 2437 fc = "gfortran" 2438 } 2439 if strings.Contains(fc, "gfortran") { 2440 cgoLDFLAGS = append(cgoLDFLAGS, "-lgfortran") 2441 } 2442 } 2443 2444 if cfg.BuildMSan { 2445 cgoCFLAGS = append([]string{"-fsanitize=memory"}, cgoCFLAGS...) 2446 cgoLDFLAGS = append([]string{"-fsanitize=memory"}, cgoLDFLAGS...) 2447 } 2448 2449 // Allows including _cgo_export.h from .[ch] files in the package. 2450 cgoCPPFLAGS = append(cgoCPPFLAGS, "-I", objdir) 2451 2452 // cgo 2453 // TODO: CGO_FLAGS? 2454 gofiles := []string{objdir + "_cgo_gotypes.go"} 2455 cfiles := []string{"_cgo_export.c"} 2456 for _, fn := range cgofiles { 2457 f := strings.TrimSuffix(filepath.Base(fn), ".go") 2458 gofiles = append(gofiles, objdir+f+".cgo1.go") 2459 cfiles = append(cfiles, f+".cgo2.c") 2460 } 2461 2462 // TODO: make cgo not depend on $GOARCH? 2463 2464 cgoflags := []string{} 2465 if p.Standard && p.ImportPath == "runtime/cgo" { 2466 cgoflags = append(cgoflags, "-import_runtime_cgo=false") 2467 } 2468 if p.Standard && (p.ImportPath == "runtime/race" || p.ImportPath == "runtime/msan" || p.ImportPath == "runtime/cgo") { 2469 cgoflags = append(cgoflags, "-import_syscall=false") 2470 } 2471 2472 // Update $CGO_LDFLAGS with p.CgoLDFLAGS. 2473 // These flags are recorded in the generated _cgo_gotypes.go file 2474 // using //go:cgo_ldflag directives, the compiler records them in the 2475 // object file for the package, and then the Go linker passes them 2476 // along to the host linker. At this point in the code, cgoLDFLAGS 2477 // consists of the original $CGO_LDFLAGS (unchecked) and all the 2478 // flags put together from source code (checked). 2479 cgoenv := b.cCompilerEnv() 2480 if len(cgoLDFLAGS) > 0 { 2481 flags := make([]string, len(cgoLDFLAGS)) 2482 for i, f := range cgoLDFLAGS { 2483 flags[i] = strconv.Quote(f) 2484 } 2485 cgoenv = []string{"CGO_LDFLAGS=" + strings.Join(flags, " ")} 2486 } 2487 2488 if cfg.BuildToolchainName == "gccgo" { 2489 switch cfg.Goarch { 2490 case "386", "amd64": 2491 cgoCFLAGS = append(cgoCFLAGS, "-fsplit-stack") 2492 } 2493 cgoflags = append(cgoflags, "-gccgo") 2494 if pkgpath := gccgoPkgpath(p); pkgpath != "" { 2495 cgoflags = append(cgoflags, "-gccgopkgpath="+pkgpath) 2496 } 2497 } 2498 2499 switch cfg.BuildBuildmode { 2500 case "c-archive", "c-shared": 2501 // Tell cgo that if there are any exported functions 2502 // it should generate a header file that C code can 2503 // #include. 2504 cgoflags = append(cgoflags, "-exportheader="+objdir+"_cgo_install.h") 2505 } 2506 2507 if err := b.run(a, p.Dir, p.ImportPath, cgoenv, cfg.BuildToolexec, cgoExe, "-objdir", objdir, "-importpath", p.ImportPath, cgoflags, "--", cgoCPPFLAGS, cgoCFLAGS, cgofiles); err != nil { 2508 return nil, nil, err 2509 } 2510 outGo = append(outGo, gofiles...) 2511 2512 // Use sequential object file names to keep them distinct 2513 // and short enough to fit in the .a header file name slots. 2514 // We no longer collect them all into _all.o, and we'd like 2515 // tools to see both the .o suffix and unique names, so 2516 // we need to make them short enough not to be truncated 2517 // in the final archive. 2518 oseq := 0 2519 nextOfile := func() string { 2520 oseq++ 2521 return objdir + fmt.Sprintf("_x%03d.o", oseq) 2522 } 2523 2524 // gcc 2525 cflags := str.StringList(cgoCPPFLAGS, cgoCFLAGS) 2526 for _, cfile := range cfiles { 2527 ofile := nextOfile() 2528 if err := b.gcc(a, p, a.Objdir, ofile, cflags, objdir+cfile); err != nil { 2529 return nil, nil, err 2530 } 2531 outObj = append(outObj, ofile) 2532 } 2533 2534 for _, file := range gccfiles { 2535 ofile := nextOfile() 2536 if err := b.gcc(a, p, a.Objdir, ofile, cflags, file); err != nil { 2537 return nil, nil, err 2538 } 2539 outObj = append(outObj, ofile) 2540 } 2541 2542 cxxflags := str.StringList(cgoCPPFLAGS, cgoCXXFLAGS) 2543 for _, file := range gxxfiles { 2544 ofile := nextOfile() 2545 if err := b.gxx(a, p, a.Objdir, ofile, cxxflags, file); err != nil { 2546 return nil, nil, err 2547 } 2548 outObj = append(outObj, ofile) 2549 } 2550 2551 for _, file := range mfiles { 2552 ofile := nextOfile() 2553 if err := b.gcc(a, p, a.Objdir, ofile, cflags, file); err != nil { 2554 return nil, nil, err 2555 } 2556 outObj = append(outObj, ofile) 2557 } 2558 2559 fflags := str.StringList(cgoCPPFLAGS, cgoFFLAGS) 2560 for _, file := range ffiles { 2561 ofile := nextOfile() 2562 if err := b.gfortran(a, p, a.Objdir, ofile, fflags, file); err != nil { 2563 return nil, nil, err 2564 } 2565 outObj = append(outObj, ofile) 2566 } 2567 2568 switch cfg.BuildToolchainName { 2569 case "gc": 2570 importGo := objdir + "_cgo_import.go" 2571 if err := b.dynimport(a, p, objdir, importGo, cgoExe, cflags, cgoLDFLAGS, outObj); err != nil { 2572 return nil, nil, err 2573 } 2574 outGo = append(outGo, importGo) 2575 2576 case "gccgo": 2577 defunC := objdir + "_cgo_defun.c" 2578 defunObj := objdir + "_cgo_defun.o" 2579 if err := BuildToolchain.cc(b, a, defunObj, defunC); err != nil { 2580 return nil, nil, err 2581 } 2582 outObj = append(outObj, defunObj) 2583 2584 default: 2585 noCompiler() 2586 } 2587 2588 return outGo, outObj, nil 2589 } 2590 2591 // dynimport creates a Go source file named importGo containing 2592 // //go:cgo_import_dynamic directives for each symbol or library 2593 // dynamically imported by the object files outObj. 2594 func (b *Builder) dynimport(a *Action, p *load.Package, objdir, importGo, cgoExe string, cflags, cgoLDFLAGS, outObj []string) error { 2595 cfile := objdir + "_cgo_main.c" 2596 ofile := objdir + "_cgo_main.o" 2597 if err := b.gcc(a, p, objdir, ofile, cflags, cfile); err != nil { 2598 return err 2599 } 2600 2601 linkobj := str.StringList(ofile, outObj, p.SysoFiles) 2602 dynobj := objdir + "_cgo_.o" 2603 2604 // we need to use -pie for Linux/ARM to get accurate imported sym 2605 ldflags := cgoLDFLAGS 2606 if (cfg.Goarch == "arm" && cfg.Goos == "linux") || cfg.Goos == "android" { 2607 // -static -pie doesn't make sense, and causes link errors. 2608 // Issue 26197. 2609 n := make([]string, 0, len(ldflags)) 2610 for _, flag := range ldflags { 2611 if flag != "-static" { 2612 n = append(n, flag) 2613 } 2614 } 2615 ldflags = append(n, "-pie") 2616 } 2617 if err := b.gccld(p, objdir, dynobj, ldflags, linkobj); err != nil { 2618 return err 2619 } 2620 2621 // cgo -dynimport 2622 var cgoflags []string 2623 if p.Standard && p.ImportPath == "runtime/cgo" { 2624 cgoflags = []string{"-dynlinker"} // record path to dynamic linker 2625 } 2626 return b.run(a, p.Dir, p.ImportPath, b.cCompilerEnv(), cfg.BuildToolexec, cgoExe, "-dynpackage", p.Name, "-dynimport", dynobj, "-dynout", importGo, cgoflags) 2627 } 2628 2629 // Run SWIG on all SWIG input files. 2630 // TODO: Don't build a shared library, once SWIG emits the necessary 2631 // pragmas for external linking. 2632 func (b *Builder) swig(a *Action, p *load.Package, objdir string, pcCFLAGS []string) (outGo, outC, outCXX []string, err error) { 2633 if err := b.swigVersionCheck(); err != nil { 2634 return nil, nil, nil, err 2635 } 2636 2637 intgosize, err := b.swigIntSize(objdir) 2638 if err != nil { 2639 return nil, nil, nil, err 2640 } 2641 2642 for _, f := range p.SwigFiles { 2643 goFile, cFile, err := b.swigOne(a, p, f, objdir, pcCFLAGS, false, intgosize) 2644 if err != nil { 2645 return nil, nil, nil, err 2646 } 2647 if goFile != "" { 2648 outGo = append(outGo, goFile) 2649 } 2650 if cFile != "" { 2651 outC = append(outC, cFile) 2652 } 2653 } 2654 for _, f := range p.SwigCXXFiles { 2655 goFile, cxxFile, err := b.swigOne(a, p, f, objdir, pcCFLAGS, true, intgosize) 2656 if err != nil { 2657 return nil, nil, nil, err 2658 } 2659 if goFile != "" { 2660 outGo = append(outGo, goFile) 2661 } 2662 if cxxFile != "" { 2663 outCXX = append(outCXX, cxxFile) 2664 } 2665 } 2666 return outGo, outC, outCXX, nil 2667 } 2668 2669 // Make sure SWIG is new enough. 2670 var ( 2671 swigCheckOnce sync.Once 2672 swigCheck error 2673 ) 2674 2675 func (b *Builder) swigDoVersionCheck() error { 2676 out, err := b.runOut("", nil, "swig", "-version") 2677 if err != nil { 2678 return err 2679 } 2680 re := regexp.MustCompile(`[vV]ersion +([\d]+)([.][\d]+)?([.][\d]+)?`) 2681 matches := re.FindSubmatch(out) 2682 if matches == nil { 2683 // Can't find version number; hope for the best. 2684 return nil 2685 } 2686 2687 major, err := strconv.Atoi(string(matches[1])) 2688 if err != nil { 2689 // Can't find version number; hope for the best. 2690 return nil 2691 } 2692 const errmsg = "must have SWIG version >= 3.0.6" 2693 if major < 3 { 2694 return errors.New(errmsg) 2695 } 2696 if major > 3 { 2697 // 4.0 or later 2698 return nil 2699 } 2700 2701 // We have SWIG version 3.x. 2702 if len(matches[2]) > 0 { 2703 minor, err := strconv.Atoi(string(matches[2][1:])) 2704 if err != nil { 2705 return nil 2706 } 2707 if minor > 0 { 2708 // 3.1 or later 2709 return nil 2710 } 2711 } 2712 2713 // We have SWIG version 3.0.x. 2714 if len(matches[3]) > 0 { 2715 patch, err := strconv.Atoi(string(matches[3][1:])) 2716 if err != nil { 2717 return nil 2718 } 2719 if patch < 6 { 2720 // Before 3.0.6. 2721 return errors.New(errmsg) 2722 } 2723 } 2724 2725 return nil 2726 } 2727 2728 func (b *Builder) swigVersionCheck() error { 2729 swigCheckOnce.Do(func() { 2730 swigCheck = b.swigDoVersionCheck() 2731 }) 2732 return swigCheck 2733 } 2734 2735 // Find the value to pass for the -intgosize option to swig. 2736 var ( 2737 swigIntSizeOnce sync.Once 2738 swigIntSize string 2739 swigIntSizeError error 2740 ) 2741 2742 // This code fails to build if sizeof(int) <= 32 2743 const swigIntSizeCode = ` 2744 package main 2745 const i int = 1 << 32 2746 ` 2747 2748 // Determine the size of int on the target system for the -intgosize option 2749 // of swig >= 2.0.9. Run only once. 2750 func (b *Builder) swigDoIntSize(objdir string) (intsize string, err error) { 2751 if cfg.BuildN { 2752 return "$INTBITS", nil 2753 } 2754 src := filepath.Join(b.WorkDir, "swig_intsize.go") 2755 if err = ioutil.WriteFile(src, []byte(swigIntSizeCode), 0666); err != nil { 2756 return 2757 } 2758 srcs := []string{src} 2759 2760 p := load.GoFilesPackage(srcs) 2761 2762 if _, _, e := BuildToolchain.gc(b, &Action{Mode: "swigDoIntSize", Package: p, Objdir: objdir}, "", nil, "", false, srcs); e != nil { 2763 return "32", nil 2764 } 2765 return "64", nil 2766 } 2767 2768 // Determine the size of int on the target system for the -intgosize option 2769 // of swig >= 2.0.9. 2770 func (b *Builder) swigIntSize(objdir string) (intsize string, err error) { 2771 swigIntSizeOnce.Do(func() { 2772 swigIntSize, swigIntSizeError = b.swigDoIntSize(objdir) 2773 }) 2774 return swigIntSize, swigIntSizeError 2775 } 2776 2777 // Run SWIG on one SWIG input file. 2778 func (b *Builder) swigOne(a *Action, p *load.Package, file, objdir string, pcCFLAGS []string, cxx bool, intgosize string) (outGo, outC string, err error) { 2779 cgoCPPFLAGS, cgoCFLAGS, cgoCXXFLAGS, _, _, err := b.CFlags(p) 2780 if err != nil { 2781 return "", "", err 2782 } 2783 2784 var cflags []string 2785 if cxx { 2786 cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCXXFLAGS) 2787 } else { 2788 cflags = str.StringList(cgoCPPFLAGS, pcCFLAGS, cgoCFLAGS) 2789 } 2790 2791 n := 5 // length of ".swig" 2792 if cxx { 2793 n = 8 // length of ".swigcxx" 2794 } 2795 base := file[:len(file)-n] 2796 goFile := base + ".go" 2797 gccBase := base + "_wrap." 2798 gccExt := "c" 2799 if cxx { 2800 gccExt = "cxx" 2801 } 2802 2803 gccgo := cfg.BuildToolchainName == "gccgo" 2804 2805 // swig 2806 args := []string{ 2807 "-go", 2808 "-cgo", 2809 "-intgosize", intgosize, 2810 "-module", base, 2811 "-o", objdir + gccBase + gccExt, 2812 "-outdir", objdir, 2813 } 2814 2815 for _, f := range cflags { 2816 if len(f) > 3 && f[:2] == "-I" { 2817 args = append(args, f) 2818 } 2819 } 2820 2821 if gccgo { 2822 args = append(args, "-gccgo") 2823 if pkgpath := gccgoPkgpath(p); pkgpath != "" { 2824 args = append(args, "-go-pkgpath", pkgpath) 2825 } 2826 } 2827 if cxx { 2828 args = append(args, "-c++") 2829 } 2830 2831 out, err := b.runOut(p.Dir, nil, "swig", args, file) 2832 if err != nil { 2833 if len(out) > 0 { 2834 if bytes.Contains(out, []byte("-intgosize")) || bytes.Contains(out, []byte("-cgo")) { 2835 return "", "", errors.New("must have SWIG version >= 3.0.6") 2836 } 2837 b.showOutput(a, p.Dir, p.Desc(), b.processOutput(out)) // swig error 2838 return "", "", errPrintedOutput 2839 } 2840 return "", "", err 2841 } 2842 if len(out) > 0 { 2843 b.showOutput(a, p.Dir, p.Desc(), b.processOutput(out)) // swig warning 2844 } 2845 2846 // If the input was x.swig, the output is x.go in the objdir. 2847 // But there might be an x.go in the original dir too, and if it 2848 // uses cgo as well, cgo will be processing both and will 2849 // translate both into x.cgo1.go in the objdir, overwriting one. 2850 // Rename x.go to _x_swig.go to avoid this problem. 2851 // We ignore files in the original dir that begin with underscore 2852 // so _x_swig.go cannot conflict with an original file we were 2853 // going to compile. 2854 goFile = objdir + goFile 2855 newGoFile := objdir + "_" + base + "_swig.go" 2856 if err := os.Rename(goFile, newGoFile); err != nil { 2857 return "", "", err 2858 } 2859 return newGoFile, objdir + gccBase + gccExt, nil 2860 } 2861 2862 // disableBuildID adjusts a linker command line to avoid creating a 2863 // build ID when creating an object file rather than an executable or 2864 // shared library. Some systems, such as Ubuntu, always add 2865 // --build-id to every link, but we don't want a build ID when we are 2866 // producing an object file. On some of those system a plain -r (not 2867 // -Wl,-r) will turn off --build-id, but clang 3.0 doesn't support a 2868 // plain -r. I don't know how to turn off --build-id when using clang 2869 // other than passing a trailing --build-id=none. So that is what we 2870 // do, but only on systems likely to support it, which is to say, 2871 // systems that normally use gold or the GNU linker. 2872 func (b *Builder) disableBuildID(ldflags []string) []string { 2873 switch cfg.Goos { 2874 case "android", "dragonfly", "linux", "netbsd": 2875 ldflags = append(ldflags, "-Wl,--build-id=none") 2876 } 2877 return ldflags 2878 } 2879 2880 // mkAbsFiles converts files into a list of absolute files, 2881 // assuming they were originally relative to dir, 2882 // and returns that new list. 2883 func mkAbsFiles(dir string, files []string) []string { 2884 abs := make([]string, len(files)) 2885 for i, f := range files { 2886 if !filepath.IsAbs(f) { 2887 f = filepath.Join(dir, f) 2888 } 2889 abs[i] = f 2890 } 2891 return abs 2892 } 2893 2894 // passLongArgsInResponseFiles modifies cmd on Windows such that, for 2895 // certain programs, long arguments are passed in "response files", a 2896 // file on disk with the arguments, with one arg per line. An actual 2897 // argument starting with '@' means that the rest of the argument is 2898 // a filename of arguments to expand. 2899 // 2900 // See Issue 18468. 2901 func passLongArgsInResponseFiles(cmd *exec.Cmd) (cleanup func()) { 2902 cleanup = func() {} // no cleanup by default 2903 2904 var argLen int 2905 for _, arg := range cmd.Args { 2906 argLen += len(arg) 2907 } 2908 2909 // If we're not approaching 32KB of args, just pass args normally. 2910 // (use 30KB instead to be conservative; not sure how accounting is done) 2911 if !useResponseFile(cmd.Path, argLen) { 2912 return 2913 } 2914 2915 tf, err := ioutil.TempFile("", "args") 2916 if err != nil { 2917 log.Fatalf("error writing long arguments to response file: %v", err) 2918 } 2919 cleanup = func() { os.Remove(tf.Name()) } 2920 var buf bytes.Buffer 2921 for _, arg := range cmd.Args[1:] { 2922 fmt.Fprintf(&buf, "%s\n", arg) 2923 } 2924 if _, err := tf.Write(buf.Bytes()); err != nil { 2925 tf.Close() 2926 cleanup() 2927 log.Fatalf("error writing long arguments to response file: %v", err) 2928 } 2929 if err := tf.Close(); err != nil { 2930 cleanup() 2931 log.Fatalf("error writing long arguments to response file: %v", err) 2932 } 2933 cmd.Args = []string{cmd.Args[0], "@" + tf.Name()} 2934 return cleanup 2935 } 2936 2937 func useResponseFile(path string, argLen int) bool { 2938 // Unless we're on Windows, don't use response files. 2939 if runtime.GOOS != "windows" { 2940 return false 2941 } 2942 2943 // Unless the program uses objabi.Flagparse, which understands 2944 // response files, don't use response files. 2945 // TODO: do we need more commands? asm? cgo? For now, no. 2946 prog := strings.TrimSuffix(filepath.Base(path), ".exe") 2947 switch prog { 2948 case "compile", "link": 2949 default: 2950 return false 2951 } 2952 2953 // Windows has a limit of 32 KB arguments. To be conservative and not 2954 // worry about whether that includes spaces or not, just use 30 KB. 2955 if argLen > (30 << 10) { 2956 return true 2957 } 2958 2959 // On the Go build system, use response files about 10% of the 2960 // time, just to exercise this codepath. 2961 isBuilder := os.Getenv("GO_BUILDER_NAME") != "" 2962 if isBuilder && rand.Intn(10) == 0 { 2963 return true 2964 } 2965 2966 return false 2967 }