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