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