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