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