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