]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/go/internal/load/pkg.go
misc/cgo: move easy tests to cmd/cgo/internal
[gostls13.git] / src / cmd / go / internal / load / pkg.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 // Package load loads packages.
6 package load
7
8 import (
9         "bytes"
10         "context"
11         "crypto/sha256"
12         "encoding/json"
13         "errors"
14         "fmt"
15         "go/build"
16         "go/scanner"
17         "go/token"
18         "internal/platform"
19         "io/fs"
20         "os"
21         "os/exec"
22         pathpkg "path"
23         "path/filepath"
24         "runtime"
25         "runtime/debug"
26         "slices"
27         "sort"
28         "strconv"
29         "strings"
30         "time"
31         "unicode"
32         "unicode/utf8"
33
34         "cmd/go/internal/base"
35         "cmd/go/internal/cfg"
36         "cmd/go/internal/fsys"
37         "cmd/go/internal/imports"
38         "cmd/go/internal/modfetch"
39         "cmd/go/internal/modindex"
40         "cmd/go/internal/modinfo"
41         "cmd/go/internal/modload"
42         "cmd/go/internal/par"
43         "cmd/go/internal/search"
44         "cmd/go/internal/str"
45         "cmd/go/internal/trace"
46         "cmd/go/internal/vcs"
47         "cmd/internal/pkgpattern"
48
49         "golang.org/x/mod/modfile"
50         "golang.org/x/mod/module"
51 )
52
53 // A Package describes a single package found in a directory.
54 type Package struct {
55         PackagePublic                 // visible in 'go list'
56         Internal      PackageInternal // for use inside go command only
57 }
58
59 type PackagePublic struct {
60         // Note: These fields are part of the go command's public API.
61         // See list.go. It is okay to add fields, but not to change or
62         // remove existing ones. Keep in sync with ../list/list.go
63         Dir           string                `json:",omitempty"` // directory containing package sources
64         ImportPath    string                `json:",omitempty"` // import path of package in dir
65         ImportComment string                `json:",omitempty"` // path in import comment on package statement
66         Name          string                `json:",omitempty"` // package name
67         Doc           string                `json:",omitempty"` // package documentation string
68         Target        string                `json:",omitempty"` // installed target for this package (may be executable)
69         Shlib         string                `json:",omitempty"` // the shared library that contains this package (only set when -linkshared)
70         Root          string                `json:",omitempty"` // Go root, Go path dir, or module root dir containing this package
71         ConflictDir   string                `json:",omitempty"` // Dir is hidden by this other directory
72         ForTest       string                `json:",omitempty"` // package is only for use in named test
73         Export        string                `json:",omitempty"` // file containing export data (set by go list -export)
74         BuildID       string                `json:",omitempty"` // build ID of the compiled package (set by go list -export)
75         Module        *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any
76         Match         []string              `json:",omitempty"` // command-line patterns matching this package
77         Goroot        bool                  `json:",omitempty"` // is this package found in the Go root?
78         Standard      bool                  `json:",omitempty"` // is this package part of the standard Go library?
79         DepOnly       bool                  `json:",omitempty"` // package is only as a dependency, not explicitly listed
80         BinaryOnly    bool                  `json:",omitempty"` // package cannot be recompiled
81         Incomplete    bool                  `json:",omitempty"` // was there an error loading this package or dependencies?
82
83         DefaultGODEBUG string `json:",omitempty"` // default GODEBUG setting (only for Name=="main")
84
85         // Stale and StaleReason remain here *only* for the list command.
86         // They are only initialized in preparation for list execution.
87         // The regular build determines staleness on the fly during action execution.
88         Stale       bool   `json:",omitempty"` // would 'go install' do anything for this package?
89         StaleReason string `json:",omitempty"` // why is Stale true?
90
91         // Source files
92         // If you add to this list you MUST add to p.AllFiles (below) too.
93         // Otherwise file name security lists will not apply to any new additions.
94         GoFiles           []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
95         CgoFiles          []string `json:",omitempty"` // .go source files that import "C"
96         CompiledGoFiles   []string `json:",omitempty"` // .go output from running cgo on CgoFiles
97         IgnoredGoFiles    []string `json:",omitempty"` // .go source files ignored due to build constraints
98         InvalidGoFiles    []string `json:",omitempty"` // .go source files with detected problems (parse error, wrong package name, and so on)
99         IgnoredOtherFiles []string `json:",omitempty"` // non-.go source files ignored due to build constraints
100         CFiles            []string `json:",omitempty"` // .c source files
101         CXXFiles          []string `json:",omitempty"` // .cc, .cpp and .cxx source files
102         MFiles            []string `json:",omitempty"` // .m source files
103         HFiles            []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files
104         FFiles            []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files
105         SFiles            []string `json:",omitempty"` // .s source files
106         SwigFiles         []string `json:",omitempty"` // .swig files
107         SwigCXXFiles      []string `json:",omitempty"` // .swigcxx files
108         SysoFiles         []string `json:",omitempty"` // .syso system object files added to package
109
110         // Embedded files
111         EmbedPatterns []string `json:",omitempty"` // //go:embed patterns
112         EmbedFiles    []string `json:",omitempty"` // files matched by EmbedPatterns
113
114         // Cgo directives
115         CgoCFLAGS    []string `json:",omitempty"` // cgo: flags for C compiler
116         CgoCPPFLAGS  []string `json:",omitempty"` // cgo: flags for C preprocessor
117         CgoCXXFLAGS  []string `json:",omitempty"` // cgo: flags for C++ compiler
118         CgoFFLAGS    []string `json:",omitempty"` // cgo: flags for Fortran compiler
119         CgoLDFLAGS   []string `json:",omitempty"` // cgo: flags for linker
120         CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
121
122         // Dependency information
123         Imports   []string          `json:",omitempty"` // import paths used by this package
124         ImportMap map[string]string `json:",omitempty"` // map from source import to ImportPath (identity entries omitted)
125         Deps      []string          `json:",omitempty"` // all (recursively) imported dependencies
126
127         // Error information
128         // Incomplete is above, packed into the other bools
129         Error      *PackageError   `json:",omitempty"` // error loading this package (not dependencies)
130         DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies, collected by go list before output
131
132         // Test information
133         // If you add to this list you MUST add to p.AllFiles (below) too.
134         // Otherwise file name security lists will not apply to any new additions.
135         TestGoFiles        []string `json:",omitempty"` // _test.go files in package
136         TestImports        []string `json:",omitempty"` // imports from TestGoFiles
137         TestEmbedPatterns  []string `json:",omitempty"` // //go:embed patterns
138         TestEmbedFiles     []string `json:",omitempty"` // files matched by TestEmbedPatterns
139         XTestGoFiles       []string `json:",omitempty"` // _test.go files outside package
140         XTestImports       []string `json:",omitempty"` // imports from XTestGoFiles
141         XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns
142         XTestEmbedFiles    []string `json:",omitempty"` // files matched by XTestEmbedPatterns
143 }
144
145 // AllFiles returns the names of all the files considered for the package.
146 // This is used for sanity and security checks, so we include all files,
147 // even IgnoredGoFiles, because some subcommands consider them.
148 // The go/build package filtered others out (like foo_wrongGOARCH.s)
149 // and that's OK.
150 func (p *Package) AllFiles() []string {
151         files := str.StringList(
152                 p.GoFiles,
153                 p.CgoFiles,
154                 // no p.CompiledGoFiles, because they are from GoFiles or generated by us
155                 p.IgnoredGoFiles,
156                 // no p.InvalidGoFiles, because they are from GoFiles
157                 p.IgnoredOtherFiles,
158                 p.CFiles,
159                 p.CXXFiles,
160                 p.MFiles,
161                 p.HFiles,
162                 p.FFiles,
163                 p.SFiles,
164                 p.SwigFiles,
165                 p.SwigCXXFiles,
166                 p.SysoFiles,
167                 p.TestGoFiles,
168                 p.XTestGoFiles,
169         )
170
171         // EmbedFiles may overlap with the other files.
172         // Dedup, but delay building the map as long as possible.
173         // Only files in the current directory (no slash in name)
174         // need to be checked against the files variable above.
175         var have map[string]bool
176         for _, file := range p.EmbedFiles {
177                 if !strings.Contains(file, "/") {
178                         if have == nil {
179                                 have = make(map[string]bool)
180                                 for _, file := range files {
181                                         have[file] = true
182                                 }
183                         }
184                         if have[file] {
185                                 continue
186                         }
187                 }
188                 files = append(files, file)
189         }
190         return files
191 }
192
193 // Desc returns the package "description", for use in b.showOutput.
194 func (p *Package) Desc() string {
195         if p.ForTest != "" {
196                 return p.ImportPath + " [" + p.ForTest + ".test]"
197         }
198         if p.Internal.ForMain != "" {
199                 return p.ImportPath + " [" + p.Internal.ForMain + "]"
200         }
201         return p.ImportPath
202 }
203
204 // IsTestOnly reports whether p is a test-only package.
205 //
206 // A “test-only” package is one that:
207 //   - is a test-only variant of an ordinary package, or
208 //   - is a synthesized "main" package for a test binary, or
209 //   - contains only _test.go files.
210 func (p *Package) IsTestOnly() bool {
211         return p.ForTest != "" ||
212                 p.Internal.TestmainGo != nil ||
213                 len(p.TestGoFiles)+len(p.XTestGoFiles) > 0 && len(p.GoFiles)+len(p.CgoFiles) == 0
214 }
215
216 type PackageInternal struct {
217         // Unexported fields are not part of the public API.
218         Build             *build.Package
219         Imports           []*Package           // this package's direct imports
220         CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library); 1:1 with the end of PackagePublic.Imports
221         RawImports        []string             // this package's original imports as they appear in the text of the program; 1:1 with the end of PackagePublic.Imports
222         ForceLibrary      bool                 // this package is a library (even if named "main")
223         CmdlineFiles      bool                 // package built from files listed on command line
224         CmdlinePkg        bool                 // package listed on command line
225         CmdlinePkgLiteral bool                 // package listed as literal on command line (not via wildcard)
226         Local             bool                 // imported via local path (./ or ../)
227         LocalPrefix       string               // interpret ./ and ../ imports relative to this prefix
228         ExeName           string               // desired name for temporary executable
229         FuzzInstrument    bool                 // package should be instrumented for fuzzing
230         CoverMode         string               // preprocess Go source files with the coverage tool in this mode
231         CoverVars         map[string]*CoverVar // variables created by coverage analysis
232         CoverageCfg       string               // coverage info config file path (passed to compiler)
233         OmitDebug         bool                 // tell linker not to write debug information
234         GobinSubdir       bool                 // install target would be subdir of GOBIN
235         BuildInfo         string               // add this info to package main
236         TestmainGo        *[]byte              // content for _testmain.go
237         Embed             map[string][]string  // //go:embed comment mapping
238         OrigImportPath    string               // original import path before adding '_test' suffix
239         PGOProfile        string               // path to PGO profile
240         ForMain           string               // the main package if this package is built specifically for it
241
242         Asmflags   []string // -asmflags for this package
243         Gcflags    []string // -gcflags for this package
244         Ldflags    []string // -ldflags for this package
245         Gccgoflags []string // -gccgoflags for this package
246 }
247
248 // A NoGoError indicates that no Go files for the package were applicable to the
249 // build for that package.
250 //
251 // That may be because there were no files whatsoever, or because all files were
252 // excluded, or because all non-excluded files were test sources.
253 type NoGoError struct {
254         Package *Package
255 }
256
257 func (e *NoGoError) Error() string {
258         if len(e.Package.IgnoredGoFiles) > 0 {
259                 // Go files exist, but they were ignored due to build constraints.
260                 return "build constraints exclude all Go files in " + e.Package.Dir
261         }
262         if len(e.Package.TestGoFiles)+len(e.Package.XTestGoFiles) > 0 {
263                 // Test Go files exist, but we're not interested in them.
264                 // The double-negative is unfortunate but we want e.Package.Dir
265                 // to appear at the end of error message.
266                 return "no non-test Go files in " + e.Package.Dir
267         }
268         return "no Go files in " + e.Package.Dir
269 }
270
271 // setLoadPackageDataError presents an error found when loading package data
272 // as a *PackageError. It has special cases for some common errors to improve
273 // messages shown to users and reduce redundancy.
274 //
275 // setLoadPackageDataError returns true if it's safe to load information about
276 // imported packages, for example, if there was a parse error loading imports
277 // in one file, but other files are okay.
278 func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportStack, importPos []token.Position) {
279         matchErr, isMatchErr := err.(*search.MatchError)
280         if isMatchErr && matchErr.Match.Pattern() == path {
281                 if matchErr.Match.IsLiteral() {
282                         // The error has a pattern has a pattern similar to the import path.
283                         // It may be slightly different (./foo matching example.com/foo),
284                         // but close enough to seem redundant.
285                         // Unwrap the error so we don't show the pattern.
286                         err = matchErr.Err
287                 }
288         }
289
290         // Replace (possibly wrapped) *build.NoGoError with *load.NoGoError.
291         // The latter is more specific about the cause.
292         var nogoErr *build.NoGoError
293         if errors.As(err, &nogoErr) {
294                 if p.Dir == "" && nogoErr.Dir != "" {
295                         p.Dir = nogoErr.Dir
296                 }
297                 err = &NoGoError{Package: p}
298         }
299
300         // Take only the first error from a scanner.ErrorList. PackageError only
301         // has room for one position, so we report the first error with a position
302         // instead of all of the errors without a position.
303         var pos string
304         var isScanErr bool
305         if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 {
306                 isScanErr = true // For stack push/pop below.
307
308                 scanPos := scanErr[0].Pos
309                 scanPos.Filename = base.ShortPath(scanPos.Filename)
310                 pos = scanPos.String()
311                 err = errors.New(scanErr[0].Msg)
312         }
313
314         // Report the error on the importing package if the problem is with the import declaration
315         // for example, if the package doesn't exist or if the import path is malformed.
316         // On the other hand, don't include a position if the problem is with the imported package,
317         // for example there are no Go files (NoGoError), or there's a problem in the imported
318         // package's source files themselves (scanner errors).
319         //
320         // TODO(matloob): Perhaps make each of those the errors in the first group
321         // (including modload.ImportMissingError, ImportMissingSumError, and the
322         // corresponding "cannot find package %q in any of" GOPATH-mode error
323         // produced in build.(*Context).Import; modload.AmbiguousImportError,
324         // and modload.PackageNotInModuleError; and the malformed module path errors
325         // produced in golang.org/x/mod/module.CheckMod) implement an interface
326         // to make it easier to check for them? That would save us from having to
327         // move the modload errors into this package to avoid a package import cycle,
328         // and from having to export an error type for the errors produced in build.
329         if !isMatchErr && (nogoErr != nil || isScanErr) {
330                 stk.Push(path)
331                 defer stk.Pop()
332         }
333
334         p.Error = &PackageError{
335                 ImportStack: stk.Copy(),
336                 Pos:         pos,
337                 Err:         err,
338         }
339         p.Incomplete = true
340
341         if path != stk.Top() {
342                 p.Error.setPos(importPos)
343         }
344 }
345
346 // Resolve returns the resolved version of imports,
347 // which should be p.TestImports or p.XTestImports, NOT p.Imports.
348 // The imports in p.TestImports and p.XTestImports are not recursively
349 // loaded during the initial load of p, so they list the imports found in
350 // the source file, but most processing should be over the vendor-resolved
351 // import paths. We do this resolution lazily both to avoid file system work
352 // and because the eventual real load of the test imports (during 'go test')
353 // can produce better error messages if it starts with the original paths.
354 // The initial load of p loads all the non-test imports and rewrites
355 // the vendored paths, so nothing should ever call p.vendored(p.Imports).
356 func (p *Package) Resolve(imports []string) []string {
357         if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] {
358                 panic("internal error: p.Resolve(p.Imports) called")
359         }
360         seen := make(map[string]bool)
361         var all []string
362         for _, path := range imports {
363                 path = ResolveImportPath(p, path)
364                 if !seen[path] {
365                         seen[path] = true
366                         all = append(all, path)
367                 }
368         }
369         sort.Strings(all)
370         return all
371 }
372
373 // CoverVar holds the name of the generated coverage variables targeting the named file.
374 type CoverVar struct {
375         File string // local file name
376         Var  string // name of count struct
377 }
378
379 func (p *Package) copyBuild(opts PackageOpts, pp *build.Package) {
380         p.Internal.Build = pp
381
382         if pp.PkgTargetRoot != "" && cfg.BuildPkgdir != "" {
383                 old := pp.PkgTargetRoot
384                 pp.PkgRoot = cfg.BuildPkgdir
385                 pp.PkgTargetRoot = cfg.BuildPkgdir
386                 if pp.PkgObj != "" {
387                         pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old))
388                 }
389         }
390
391         p.Dir = pp.Dir
392         p.ImportPath = pp.ImportPath
393         p.ImportComment = pp.ImportComment
394         p.Name = pp.Name
395         p.Doc = pp.Doc
396         p.Root = pp.Root
397         p.ConflictDir = pp.ConflictDir
398         p.BinaryOnly = pp.BinaryOnly
399
400         // TODO? Target
401         p.Goroot = pp.Goroot
402         p.Standard = p.Goroot && p.ImportPath != "" && search.IsStandardImportPath(p.ImportPath)
403         p.GoFiles = pp.GoFiles
404         p.CgoFiles = pp.CgoFiles
405         p.IgnoredGoFiles = pp.IgnoredGoFiles
406         p.InvalidGoFiles = pp.InvalidGoFiles
407         p.IgnoredOtherFiles = pp.IgnoredOtherFiles
408         p.CFiles = pp.CFiles
409         p.CXXFiles = pp.CXXFiles
410         p.MFiles = pp.MFiles
411         p.HFiles = pp.HFiles
412         p.FFiles = pp.FFiles
413         p.SFiles = pp.SFiles
414         p.SwigFiles = pp.SwigFiles
415         p.SwigCXXFiles = pp.SwigCXXFiles
416         p.SysoFiles = pp.SysoFiles
417         if cfg.BuildMSan {
418                 // There's no way for .syso files to be built both with and without
419                 // support for memory sanitizer. Assume they are built without,
420                 // and drop them.
421                 p.SysoFiles = nil
422         }
423         p.CgoCFLAGS = pp.CgoCFLAGS
424         p.CgoCPPFLAGS = pp.CgoCPPFLAGS
425         p.CgoCXXFLAGS = pp.CgoCXXFLAGS
426         p.CgoFFLAGS = pp.CgoFFLAGS
427         p.CgoLDFLAGS = pp.CgoLDFLAGS
428         p.CgoPkgConfig = pp.CgoPkgConfig
429         // We modify p.Imports in place, so make copy now.
430         p.Imports = make([]string, len(pp.Imports))
431         copy(p.Imports, pp.Imports)
432         p.Internal.RawImports = pp.Imports
433         p.TestGoFiles = pp.TestGoFiles
434         p.TestImports = pp.TestImports
435         p.XTestGoFiles = pp.XTestGoFiles
436         p.XTestImports = pp.XTestImports
437         if opts.IgnoreImports {
438                 p.Imports = nil
439                 p.Internal.RawImports = nil
440                 p.TestImports = nil
441                 p.XTestImports = nil
442         }
443         p.EmbedPatterns = pp.EmbedPatterns
444         p.TestEmbedPatterns = pp.TestEmbedPatterns
445         p.XTestEmbedPatterns = pp.XTestEmbedPatterns
446         p.Internal.OrigImportPath = pp.ImportPath
447 }
448
449 // A PackageError describes an error loading information about a package.
450 type PackageError struct {
451         ImportStack      []string // shortest path from package named on command line to this one
452         Pos              string   // position of error
453         Err              error    // the error itself
454         IsImportCycle    bool     // the error is an import cycle
455         Hard             bool     // whether the error is soft or hard; soft errors are ignored in some places
456         alwaysPrintStack bool     // whether to always print the ImportStack
457 }
458
459 func (p *PackageError) Error() string {
460         // TODO(#43696): decide when to print the stack or the position based on
461         // the error type and whether the package is in the main module.
462         // Document the rationale.
463         if p.Pos != "" && (len(p.ImportStack) == 0 || !p.alwaysPrintStack) {
464                 // Omit import stack. The full path to the file where the error
465                 // is the most important thing.
466                 return p.Pos + ": " + p.Err.Error()
467         }
468
469         // If the error is an ImportPathError, and the last path on the stack appears
470         // in the error message, omit that path from the stack to avoid repetition.
471         // If an ImportPathError wraps another ImportPathError that matches the
472         // last path on the stack, we don't omit the path. An error like
473         // "package A imports B: error loading C caused by B" would not be clearer
474         // if "imports B" were omitted.
475         if len(p.ImportStack) == 0 {
476                 return p.Err.Error()
477         }
478         var optpos string
479         if p.Pos != "" {
480                 optpos = "\n\t" + p.Pos
481         }
482         return "package " + strings.Join(p.ImportStack, "\n\timports ") + optpos + ": " + p.Err.Error()
483 }
484
485 func (p *PackageError) Unwrap() error { return p.Err }
486
487 // PackageError implements MarshalJSON so that Err is marshaled as a string
488 // and non-essential fields are omitted.
489 func (p *PackageError) MarshalJSON() ([]byte, error) {
490         perr := struct {
491                 ImportStack []string
492                 Pos         string
493                 Err         string
494         }{p.ImportStack, p.Pos, p.Err.Error()}
495         return json.Marshal(perr)
496 }
497
498 func (p *PackageError) setPos(posList []token.Position) {
499         if len(posList) == 0 {
500                 return
501         }
502         pos := posList[0]
503         pos.Filename = base.ShortPath(pos.Filename)
504         p.Pos = pos.String()
505 }
506
507 // ImportPathError is a type of error that prevents a package from being loaded
508 // for a given import path. When such a package is loaded, a *Package is
509 // returned with Err wrapping an ImportPathError: the error is attached to
510 // the imported package, not the importing package.
511 //
512 // The string returned by ImportPath must appear in the string returned by
513 // Error. Errors that wrap ImportPathError (such as PackageError) may omit
514 // the import path.
515 type ImportPathError interface {
516         error
517         ImportPath() string
518 }
519
520 var (
521         _ ImportPathError = (*importError)(nil)
522         _ ImportPathError = (*mainPackageError)(nil)
523         _ ImportPathError = (*modload.ImportMissingError)(nil)
524         _ ImportPathError = (*modload.ImportMissingSumError)(nil)
525         _ ImportPathError = (*modload.DirectImportFromImplicitDependencyError)(nil)
526 )
527
528 type importError struct {
529         importPath string
530         err        error // created with fmt.Errorf
531 }
532
533 func ImportErrorf(path, format string, args ...any) ImportPathError {
534         err := &importError{importPath: path, err: fmt.Errorf(format, args...)}
535         if errStr := err.Error(); !strings.Contains(errStr, path) {
536                 panic(fmt.Sprintf("path %q not in error %q", path, errStr))
537         }
538         return err
539 }
540
541 func (e *importError) Error() string {
542         return e.err.Error()
543 }
544
545 func (e *importError) Unwrap() error {
546         // Don't return e.err directly, since we're only wrapping an error if %w
547         // was passed to ImportErrorf.
548         return errors.Unwrap(e.err)
549 }
550
551 func (e *importError) ImportPath() string {
552         return e.importPath
553 }
554
555 // An ImportStack is a stack of import paths, possibly with the suffix " (test)" appended.
556 // The import path of a test package is the import path of the corresponding
557 // non-test package with the suffix "_test" added.
558 type ImportStack []string
559
560 func (s *ImportStack) Push(p string) {
561         *s = append(*s, p)
562 }
563
564 func (s *ImportStack) Pop() {
565         *s = (*s)[0 : len(*s)-1]
566 }
567
568 func (s *ImportStack) Copy() []string {
569         return append([]string{}, *s...)
570 }
571
572 func (s *ImportStack) Top() string {
573         if len(*s) == 0 {
574                 return ""
575         }
576         return (*s)[len(*s)-1]
577 }
578
579 // shorterThan reports whether sp is shorter than t.
580 // We use this to record the shortest import sequence
581 // that leads to a particular package.
582 func (sp *ImportStack) shorterThan(t []string) bool {
583         s := *sp
584         if len(s) != len(t) {
585                 return len(s) < len(t)
586         }
587         // If they are the same length, settle ties using string ordering.
588         for i := range s {
589                 if s[i] != t[i] {
590                         return s[i] < t[i]
591                 }
592         }
593         return false // they are equal
594 }
595
596 // packageCache is a lookup cache for LoadImport,
597 // so that if we look up a package multiple times
598 // we return the same pointer each time.
599 var packageCache = map[string]*Package{}
600
601 // ClearPackageCache clears the in-memory package cache and the preload caches.
602 // It is only for use by GOPATH-based "go get".
603 // TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
604 func ClearPackageCache() {
605         for name := range packageCache {
606                 delete(packageCache, name)
607         }
608         resolvedImportCache.Clear()
609         packageDataCache.Clear()
610 }
611
612 // ClearPackageCachePartial clears packages with the given import paths from the
613 // in-memory package cache and the preload caches. It is only for use by
614 // GOPATH-based "go get".
615 // TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function.
616 func ClearPackageCachePartial(args []string) {
617         shouldDelete := make(map[string]bool)
618         for _, arg := range args {
619                 shouldDelete[arg] = true
620                 if p := packageCache[arg]; p != nil {
621                         delete(packageCache, arg)
622                 }
623         }
624         resolvedImportCache.DeleteIf(func(key importSpec) bool {
625                 return shouldDelete[key.path]
626         })
627         packageDataCache.DeleteIf(func(key string) bool {
628                 return shouldDelete[key]
629         })
630 }
631
632 // ReloadPackageNoFlags is like LoadImport but makes sure
633 // not to use the package cache.
634 // It is only for use by GOPATH-based "go get".
635 // TODO(rsc): When GOPATH-based "go get" is removed, delete this function.
636 func ReloadPackageNoFlags(arg string, stk *ImportStack) *Package {
637         p := packageCache[arg]
638         if p != nil {
639                 delete(packageCache, arg)
640                 resolvedImportCache.DeleteIf(func(key importSpec) bool {
641                         return key.path == p.ImportPath
642                 })
643                 packageDataCache.Delete(p.ImportPath)
644         }
645         return LoadPackage(context.TODO(), PackageOpts{}, arg, base.Cwd(), stk, nil, 0)
646 }
647
648 // dirToImportPath returns the pseudo-import path we use for a package
649 // outside the Go path. It begins with _/ and then contains the full path
650 // to the directory. If the package lives in c:\home\gopher\my\pkg then
651 // the pseudo-import path is _/c_/home/gopher/my/pkg.
652 // Using a pseudo-import path like this makes the ./ imports no longer
653 // a special case, so that all the code to deal with ordinary imports works
654 // automatically.
655 func dirToImportPath(dir string) string {
656         return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))
657 }
658
659 func makeImportValid(r rune) rune {
660         // Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.
661         const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
662         if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
663                 return '_'
664         }
665         return r
666 }
667
668 // Mode flags for loadImport and download (in get.go).
669 const (
670         // ResolveImport means that loadImport should do import path expansion.
671         // That is, ResolveImport means that the import path came from
672         // a source file and has not been expanded yet to account for
673         // vendoring or possible module adjustment.
674         // Every import path should be loaded initially with ResolveImport,
675         // and then the expanded version (for example with the /vendor/ in it)
676         // gets recorded as the canonical import path. At that point, future loads
677         // of that package must not pass ResolveImport, because
678         // disallowVendor will reject direct use of paths containing /vendor/.
679         ResolveImport = 1 << iota
680
681         // ResolveModule is for download (part of "go get") and indicates
682         // that the module adjustment should be done, but not vendor adjustment.
683         ResolveModule
684
685         // GetTestDeps is for download (part of "go get") and indicates
686         // that test dependencies should be fetched too.
687         GetTestDeps
688
689         // The remainder are internal modes for calls to loadImport.
690
691         // cmdlinePkg is for a package mentioned on the command line.
692         cmdlinePkg
693
694         // cmdlinePkgLiteral is for a package mentioned on the command line
695         // without using any wildcards or meta-patterns.
696         cmdlinePkgLiteral
697 )
698
699 // LoadImport scans the directory named by path, which must be an import path,
700 // but possibly a local import path (an absolute file system path or one beginning
701 // with ./ or ../). A local relative path is interpreted relative to srcDir.
702 // It returns a *Package describing the package found in that directory.
703 // LoadImport does not set tool flags and should only be used by
704 // this package, as part of a bigger load operation, and by GOPATH-based "go get".
705 // TODO(rsc): When GOPATH-based "go get" is removed, unexport this function.
706 // The returned PackageError, if any, describes why parent is not allowed
707 // to import the named package, with the error referring to importPos.
708 // The PackageError can only be non-nil when parent is not nil.
709 func LoadImport(ctx context.Context, opts PackageOpts, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) (*Package, *PackageError) {
710         return loadImport(ctx, opts, nil, path, srcDir, parent, stk, importPos, mode)
711 }
712
713 // LoadPackage does Load import, but without a parent package load contezt
714 func LoadPackage(ctx context.Context, opts PackageOpts, path, srcDir string, stk *ImportStack, importPos []token.Position, mode int) *Package {
715         p, err := loadImport(ctx, opts, nil, path, srcDir, nil, stk, importPos, mode)
716         if err != nil {
717                 base.Fatalf("internal error: loadImport of %q with nil parent returned an error", path)
718         }
719         return p
720 }
721
722 func loadImport(ctx context.Context, opts PackageOpts, pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) (*Package, *PackageError) {
723         ctx, span := trace.StartSpan(ctx, "modload.loadImport "+path)
724         defer span.Done()
725
726         if path == "" {
727                 panic("LoadImport called with empty package path")
728         }
729
730         var parentPath, parentRoot string
731         parentIsStd := false
732         if parent != nil {
733                 parentPath = parent.ImportPath
734                 parentRoot = parent.Root
735                 parentIsStd = parent.Standard
736         }
737         bp, loaded, err := loadPackageData(ctx, path, parentPath, srcDir, parentRoot, parentIsStd, mode)
738         if loaded && pre != nil && !opts.IgnoreImports {
739                 pre.preloadImports(ctx, opts, bp.Imports, bp)
740         }
741         if bp == nil {
742                 p := &Package{
743                         PackagePublic: PackagePublic{
744                                 ImportPath: path,
745                                 Incomplete: true,
746                         },
747                 }
748                 if importErr, ok := err.(ImportPathError); !ok || importErr.ImportPath() != path {
749                         // Only add path to the error's import stack if it's not already present
750                         // in the error.
751                         //
752                         // TODO(bcmills): setLoadPackageDataError itself has a similar Push / Pop
753                         // sequence that empirically doesn't trigger for these errors, guarded by
754                         // a somewhat complex condition. Figure out how to generalize that
755                         // condition and eliminate the explicit calls here.
756                         stk.Push(path)
757                         defer stk.Pop()
758                 }
759                 p.setLoadPackageDataError(err, path, stk, nil)
760                 return p, nil
761         }
762
763         setCmdline := func(p *Package) {
764                 if mode&cmdlinePkg != 0 {
765                         p.Internal.CmdlinePkg = true
766                 }
767                 if mode&cmdlinePkgLiteral != 0 {
768                         p.Internal.CmdlinePkgLiteral = true
769                 }
770         }
771
772         importPath := bp.ImportPath
773         p := packageCache[importPath]
774         if p != nil {
775                 stk.Push(path)
776                 p = reusePackage(p, stk)
777                 stk.Pop()
778                 setCmdline(p)
779         } else {
780                 p = new(Package)
781                 p.Internal.Local = build.IsLocalImport(path)
782                 p.ImportPath = importPath
783                 packageCache[importPath] = p
784
785                 setCmdline(p)
786
787                 // Load package.
788                 // loadPackageData may return bp != nil even if an error occurs,
789                 // in order to return partial information.
790                 p.load(ctx, opts, path, stk, importPos, bp, err)
791
792                 if !cfg.ModulesEnabled && path != cleanImport(path) {
793                         p.Error = &PackageError{
794                                 ImportStack: stk.Copy(),
795                                 Err:         ImportErrorf(path, "non-canonical import path %q: should be %q", path, pathpkg.Clean(path)),
796                         }
797                         p.Incomplete = true
798                         p.Error.setPos(importPos)
799                 }
800         }
801
802         // Checked on every import because the rules depend on the code doing the importing.
803         if perr := disallowInternal(ctx, srcDir, parent, parentPath, p, stk); perr != nil {
804                 perr.setPos(importPos)
805                 return p, perr
806         }
807         if mode&ResolveImport != 0 {
808                 if perr := disallowVendor(srcDir, path, parentPath, p, stk); perr != nil {
809                         perr.setPos(importPos)
810                         return p, perr
811                 }
812         }
813
814         if p.Name == "main" && parent != nil && parent.Dir != p.Dir {
815                 perr := &PackageError{
816                         ImportStack: stk.Copy(),
817                         Err:         ImportErrorf(path, "import %q is a program, not an importable package", path),
818                 }
819                 perr.setPos(importPos)
820                 return p, perr
821         }
822
823         if p.Internal.Local && parent != nil && !parent.Internal.Local {
824                 var err error
825                 if path == "." {
826                         err = ImportErrorf(path, "%s: cannot import current directory", path)
827                 } else {
828                         err = ImportErrorf(path, "local import %q in non-local package", path)
829                 }
830                 perr := &PackageError{
831                         ImportStack: stk.Copy(),
832                         Err:         err,
833                 }
834                 perr.setPos(importPos)
835                 return p, perr
836         }
837
838         return p, nil
839 }
840
841 // loadPackageData loads information needed to construct a *Package. The result
842 // is cached, and later calls to loadPackageData for the same package will return
843 // the same data.
844 //
845 // loadPackageData returns a non-nil package even if err is non-nil unless
846 // the package path is malformed (for example, the path contains "mod/" or "@").
847 //
848 // loadPackageData returns a boolean, loaded, which is true if this is the
849 // first time the package was loaded. Callers may preload imports in this case.
850 func loadPackageData(ctx context.Context, path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) {
851         ctx, span := trace.StartSpan(ctx, "load.loadPackageData "+path)
852         defer span.Done()
853
854         if path == "" {
855                 panic("loadPackageData called with empty package path")
856         }
857
858         if strings.HasPrefix(path, "mod/") {
859                 // Paths beginning with "mod/" might accidentally
860                 // look in the module cache directory tree in $GOPATH/pkg/mod/.
861                 // This prefix is owned by the Go core for possible use in the
862                 // standard library (since it does not begin with a domain name),
863                 // so it's OK to disallow entirely.
864                 return nil, false, fmt.Errorf("disallowed import path %q", path)
865         }
866
867         if strings.Contains(path, "@") {
868                 return nil, false, errors.New("can only use path@version syntax with 'go get' and 'go install' in module-aware mode")
869         }
870
871         // Determine canonical package path and directory.
872         // For a local import the identifier is the pseudo-import path
873         // we create from the full directory to the package.
874         // Otherwise it is the usual import path.
875         // For vendored imports, it is the expanded form.
876         //
877         // Note that when modules are enabled, local import paths are normally
878         // canonicalized by modload.LoadPackages before now. However, if there's an
879         // error resolving a local path, it will be returned untransformed
880         // so that 'go list -e' reports something useful.
881         importKey := importSpec{
882                 path:        path,
883                 parentPath:  parentPath,
884                 parentDir:   parentDir,
885                 parentRoot:  parentRoot,
886                 parentIsStd: parentIsStd,
887                 mode:        mode,
888         }
889         r := resolvedImportCache.Do(importKey, func() resolvedImport {
890                 var r resolvedImport
891                 if cfg.ModulesEnabled {
892                         r.dir, r.path, r.err = modload.Lookup(parentPath, parentIsStd, path)
893                 } else if build.IsLocalImport(path) {
894                         r.dir = filepath.Join(parentDir, path)
895                         r.path = dirToImportPath(r.dir)
896                 } else if mode&ResolveImport != 0 {
897                         // We do our own path resolution, because we want to
898                         // find out the key to use in packageCache without the
899                         // overhead of repeated calls to buildContext.Import.
900                         // The code is also needed in a few other places anyway.
901                         r.path = resolveImportPath(path, parentPath, parentDir, parentRoot, parentIsStd)
902                 } else if mode&ResolveModule != 0 {
903                         r.path = moduleImportPath(path, parentPath, parentDir, parentRoot)
904                 }
905                 if r.path == "" {
906                         r.path = path
907                 }
908                 return r
909         })
910         // Invariant: r.path is set to the resolved import path. If the path cannot
911         // be resolved, r.path is set to path, the source import path.
912         // r.path is never empty.
913
914         // Load the package from its directory. If we already found the package's
915         // directory when resolving its import path, use that.
916         p, err := packageDataCache.Do(r.path, func() (*build.Package, error) {
917                 loaded = true
918                 var data struct {
919                         p   *build.Package
920                         err error
921                 }
922                 if r.dir != "" {
923                         var buildMode build.ImportMode
924                         buildContext := cfg.BuildContext
925                         if !cfg.ModulesEnabled {
926                                 buildMode = build.ImportComment
927                         } else {
928                                 buildContext.GOPATH = "" // Clear GOPATH so packages are imported as pure module packages
929                         }
930                         modroot := modload.PackageModRoot(ctx, r.path)
931                         if modroot == "" && str.HasPathPrefix(r.dir, cfg.GOROOTsrc) {
932                                 modroot = cfg.GOROOTsrc
933                                 gorootSrcCmd := filepath.Join(cfg.GOROOTsrc, "cmd")
934                                 if str.HasPathPrefix(r.dir, gorootSrcCmd) {
935                                         modroot = gorootSrcCmd
936                                 }
937                         }
938                         if modroot != "" {
939                                 if rp, err := modindex.GetPackage(modroot, r.dir); err == nil {
940                                         data.p, data.err = rp.Import(cfg.BuildContext, buildMode)
941                                         goto Happy
942                                 } else if !errors.Is(err, modindex.ErrNotIndexed) {
943                                         base.Fatalf("go: %v", err)
944                                 }
945                         }
946                         data.p, data.err = buildContext.ImportDir(r.dir, buildMode)
947                 Happy:
948                         if cfg.ModulesEnabled {
949                                 // Override data.p.Root, since ImportDir sets it to $GOPATH, if
950                                 // the module is inside $GOPATH/src.
951                                 if info := modload.PackageModuleInfo(ctx, path); info != nil {
952                                         data.p.Root = info.Dir
953                                 }
954                         }
955                         if r.err != nil {
956                                 if data.err != nil {
957                                         // ImportDir gave us one error, and the module loader gave us another.
958                                         // We arbitrarily choose to keep the error from ImportDir because
959                                         // that's what our tests already expect, and it seems to provide a bit
960                                         // more detail in most cases.
961                                 } else if errors.Is(r.err, imports.ErrNoGo) {
962                                         // ImportDir said there were files in the package, but the module
963                                         // loader said there weren't. Which one is right?
964                                         // Without this special-case hack, the TestScript/test_vet case fails
965                                         // on the vetfail/p1 package (added in CL 83955).
966                                         // Apparently, imports.ShouldBuild biases toward rejecting files
967                                         // with invalid build constraints, whereas ImportDir biases toward
968                                         // accepting them.
969                                         //
970                                         // TODO(#41410: Figure out how this actually ought to work and fix
971                                         // this mess.
972                                 } else {
973                                         data.err = r.err
974                                 }
975                         }
976                 } else if r.err != nil {
977                         data.p = new(build.Package)
978                         data.err = r.err
979                 } else if cfg.ModulesEnabled && path != "unsafe" {
980                         data.p = new(build.Package)
981                         data.err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", r.path)
982                 } else {
983                         buildMode := build.ImportComment
984                         if mode&ResolveImport == 0 || r.path != path {
985                                 // Not vendoring, or we already found the vendored path.
986                                 buildMode |= build.IgnoreVendor
987                         }
988                         data.p, data.err = cfg.BuildContext.Import(r.path, parentDir, buildMode)
989                 }
990                 data.p.ImportPath = r.path
991
992                 // Set data.p.BinDir in cases where go/build.Context.Import
993                 // may give us a path we don't want.
994                 if !data.p.Goroot {
995                         if cfg.GOBIN != "" {
996                                 data.p.BinDir = cfg.GOBIN
997                         } else if cfg.ModulesEnabled {
998                                 data.p.BinDir = modload.BinDir()
999                         }
1000                 }
1001
1002                 if !cfg.ModulesEnabled && data.err == nil &&
1003                         data.p.ImportComment != "" && data.p.ImportComment != path &&
1004                         !strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {
1005                         data.err = fmt.Errorf("code in directory %s expects import %q", data.p.Dir, data.p.ImportComment)
1006                 }
1007                 return data.p, data.err
1008         })
1009
1010         return p, loaded, err
1011 }
1012
1013 // importSpec describes an import declaration in source code. It is used as a
1014 // cache key for resolvedImportCache.
1015 type importSpec struct {
1016         path                              string
1017         parentPath, parentDir, parentRoot string
1018         parentIsStd                       bool
1019         mode                              int
1020 }
1021
1022 // resolvedImport holds a canonical identifier for a package. It may also contain
1023 // a path to the package's directory and an error if one occurred. resolvedImport
1024 // is the value type in resolvedImportCache.
1025 type resolvedImport struct {
1026         path, dir string
1027         err       error
1028 }
1029
1030 // resolvedImportCache maps import strings to canonical package names.
1031 var resolvedImportCache par.Cache[importSpec, resolvedImport]
1032
1033 // packageDataCache maps canonical package names (string) to package metadata.
1034 var packageDataCache par.ErrCache[string, *build.Package]
1035
1036 // preloadWorkerCount is the number of concurrent goroutines that can load
1037 // packages. Experimentally, there are diminishing returns with more than
1038 // 4 workers. This was measured on the following machines.
1039 //
1040 // * MacBookPro with a 4-core Intel Core i7 CPU
1041 // * Linux workstation with 6-core Intel Xeon CPU
1042 // * Linux workstation with 24-core Intel Xeon CPU
1043 //
1044 // It is very likely (though not confirmed) that this workload is limited
1045 // by memory bandwidth. We don't have a good way to determine the number of
1046 // workers that would saturate the bus though, so runtime.GOMAXPROCS
1047 // seems like a reasonable default.
1048 var preloadWorkerCount = runtime.GOMAXPROCS(0)
1049
1050 // preload holds state for managing concurrent preloading of package data.
1051 //
1052 // A preload should be created with newPreload before loading a large
1053 // package graph. flush must be called when package loading is complete
1054 // to ensure preload goroutines are no longer active. This is necessary
1055 // because of global mutable state that cannot safely be read and written
1056 // concurrently. In particular, packageDataCache may be cleared by "go get"
1057 // in GOPATH mode, and modload.loaded (accessed via modload.Lookup) may be
1058 // modified by modload.LoadPackages.
1059 type preload struct {
1060         cancel chan struct{}
1061         sema   chan struct{}
1062 }
1063
1064 // newPreload creates a new preloader. flush must be called later to avoid
1065 // accessing global state while it is being modified.
1066 func newPreload() *preload {
1067         pre := &preload{
1068                 cancel: make(chan struct{}),
1069                 sema:   make(chan struct{}, preloadWorkerCount),
1070         }
1071         return pre
1072 }
1073
1074 // preloadMatches loads data for package paths matched by patterns.
1075 // When preloadMatches returns, some packages may not be loaded yet, but
1076 // loadPackageData and loadImport are always safe to call.
1077 func (pre *preload) preloadMatches(ctx context.Context, opts PackageOpts, matches []*search.Match) {
1078         for _, m := range matches {
1079                 for _, pkg := range m.Pkgs {
1080                         select {
1081                         case <-pre.cancel:
1082                                 return
1083                         case pre.sema <- struct{}{}:
1084                                 go func(pkg string) {
1085                                         mode := 0 // don't use vendoring or module import resolution
1086                                         bp, loaded, err := loadPackageData(ctx, pkg, "", base.Cwd(), "", false, mode)
1087                                         <-pre.sema
1088                                         if bp != nil && loaded && err == nil && !opts.IgnoreImports {
1089                                                 pre.preloadImports(ctx, opts, bp.Imports, bp)
1090                                         }
1091                                 }(pkg)
1092                         }
1093                 }
1094         }
1095 }
1096
1097 // preloadImports queues a list of imports for preloading.
1098 // When preloadImports returns, some packages may not be loaded yet,
1099 // but loadPackageData and loadImport are always safe to call.
1100 func (pre *preload) preloadImports(ctx context.Context, opts PackageOpts, imports []string, parent *build.Package) {
1101         parentIsStd := parent.Goroot && parent.ImportPath != "" && search.IsStandardImportPath(parent.ImportPath)
1102         for _, path := range imports {
1103                 if path == "C" || path == "unsafe" {
1104                         continue
1105                 }
1106                 select {
1107                 case <-pre.cancel:
1108                         return
1109                 case pre.sema <- struct{}{}:
1110                         go func(path string) {
1111                                 bp, loaded, err := loadPackageData(ctx, path, parent.ImportPath, parent.Dir, parent.Root, parentIsStd, ResolveImport)
1112                                 <-pre.sema
1113                                 if bp != nil && loaded && err == nil && !opts.IgnoreImports {
1114                                         pre.preloadImports(ctx, opts, bp.Imports, bp)
1115                                 }
1116                         }(path)
1117                 }
1118         }
1119 }
1120
1121 // flush stops pending preload operations. flush blocks until preload calls to
1122 // loadPackageData have completed. The preloader will not make any new calls
1123 // to loadPackageData.
1124 func (pre *preload) flush() {
1125         // flush is usually deferred.
1126         // Don't hang program waiting for workers on panic.
1127         if v := recover(); v != nil {
1128                 panic(v)
1129         }
1130
1131         close(pre.cancel)
1132         for i := 0; i < preloadWorkerCount; i++ {
1133                 pre.sema <- struct{}{}
1134         }
1135 }
1136
1137 func cleanImport(path string) string {
1138         orig := path
1139         path = pathpkg.Clean(path)
1140         if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") {
1141                 path = "./" + path
1142         }
1143         return path
1144 }
1145
1146 var isDirCache par.Cache[string, bool]
1147
1148 func isDir(path string) bool {
1149         return isDirCache.Do(path, func() bool {
1150                 fi, err := fsys.Stat(path)
1151                 return err == nil && fi.IsDir()
1152         })
1153 }
1154
1155 // ResolveImportPath returns the true meaning of path when it appears in parent.
1156 // There are two different resolutions applied.
1157 // First, there is Go 1.5 vendoring (golang.org/s/go15vendor).
1158 // If vendor expansion doesn't trigger, then the path is also subject to
1159 // Go 1.11 module legacy conversion (golang.org/issue/25069).
1160 func ResolveImportPath(parent *Package, path string) (found string) {
1161         var parentPath, parentDir, parentRoot string
1162         parentIsStd := false
1163         if parent != nil {
1164                 parentPath = parent.ImportPath
1165                 parentDir = parent.Dir
1166                 parentRoot = parent.Root
1167                 parentIsStd = parent.Standard
1168         }
1169         return resolveImportPath(path, parentPath, parentDir, parentRoot, parentIsStd)
1170 }
1171
1172 func resolveImportPath(path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) {
1173         if cfg.ModulesEnabled {
1174                 if _, p, e := modload.Lookup(parentPath, parentIsStd, path); e == nil {
1175                         return p
1176                 }
1177                 return path
1178         }
1179         found = vendoredImportPath(path, parentPath, parentDir, parentRoot)
1180         if found != path {
1181                 return found
1182         }
1183         return moduleImportPath(path, parentPath, parentDir, parentRoot)
1184 }
1185
1186 // dirAndRoot returns the source directory and workspace root
1187 // for the package p, guaranteeing that root is a path prefix of dir.
1188 func dirAndRoot(path string, dir, root string) (string, string) {
1189         origDir, origRoot := dir, root
1190         dir = filepath.Clean(dir)
1191         root = filepath.Join(root, "src")
1192         if !str.HasFilePathPrefix(dir, root) || path != "command-line-arguments" && filepath.Join(root, path) != dir {
1193                 // Look for symlinks before reporting error.
1194                 dir = expandPath(dir)
1195                 root = expandPath(root)
1196         }
1197
1198         if !str.HasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || path != "command-line-arguments" && !build.IsLocalImport(path) && filepath.Join(root, path) != dir {
1199                 debug.PrintStack()
1200                 base.Fatalf("unexpected directory layout:\n"+
1201                         "       import path: %s\n"+
1202                         "       root: %s\n"+
1203                         "       dir: %s\n"+
1204                         "       expand root: %s\n"+
1205                         "       expand dir: %s\n"+
1206                         "       separator: %s",
1207                         path,
1208                         filepath.Join(origRoot, "src"),
1209                         filepath.Clean(origDir),
1210                         origRoot,
1211                         origDir,
1212                         string(filepath.Separator))
1213         }
1214
1215         return dir, root
1216 }
1217
1218 // vendoredImportPath returns the vendor-expansion of path when it appears in parent.
1219 // If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path,
1220 // x/vendor/path, vendor/path, or else stay path if none of those exist.
1221 // vendoredImportPath returns the expanded path or, if no expansion is found, the original.
1222 func vendoredImportPath(path, parentPath, parentDir, parentRoot string) (found string) {
1223         if parentRoot == "" {
1224                 return path
1225         }
1226
1227         dir, root := dirAndRoot(parentPath, parentDir, parentRoot)
1228
1229         vpath := "vendor/" + path
1230         for i := len(dir); i >= len(root); i-- {
1231                 if i < len(dir) && dir[i] != filepath.Separator {
1232                         continue
1233                 }
1234                 // Note: checking for the vendor directory before checking
1235                 // for the vendor/path directory helps us hit the
1236                 // isDir cache more often. It also helps us prepare a more useful
1237                 // list of places we looked, to report when an import is not found.
1238                 if !isDir(filepath.Join(dir[:i], "vendor")) {
1239                         continue
1240                 }
1241                 targ := filepath.Join(dir[:i], vpath)
1242                 if isDir(targ) && hasGoFiles(targ) {
1243                         importPath := parentPath
1244                         if importPath == "command-line-arguments" {
1245                                 // If parent.ImportPath is 'command-line-arguments'.
1246                                 // set to relative directory to root (also chopped root directory)
1247                                 importPath = dir[len(root)+1:]
1248                         }
1249                         // We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy.
1250                         // We know the import path for parent's dir.
1251                         // We chopped off some number of path elements and
1252                         // added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path.
1253                         // Now we want to know the import path for that directory.
1254                         // Construct it by chopping the same number of path elements
1255                         // (actually the same number of bytes) from parent's import path
1256                         // and then append /vendor/path.
1257                         chopped := len(dir) - i
1258                         if chopped == len(importPath)+1 {
1259                                 // We walked up from c:\gopath\src\foo\bar
1260                                 // and found c:\gopath\src\vendor\path.
1261                                 // We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7).
1262                                 // Use "vendor/path" without any prefix.
1263                                 return vpath
1264                         }
1265                         return importPath[:len(importPath)-chopped] + "/" + vpath
1266                 }
1267         }
1268         return path
1269 }
1270
1271 var (
1272         modulePrefix   = []byte("\nmodule ")
1273         goModPathCache par.Cache[string, string]
1274 )
1275
1276 // goModPath returns the module path in the go.mod in dir, if any.
1277 func goModPath(dir string) (path string) {
1278         return goModPathCache.Do(dir, func() string {
1279                 data, err := os.ReadFile(filepath.Join(dir, "go.mod"))
1280                 if err != nil {
1281                         return ""
1282                 }
1283                 var i int
1284                 if bytes.HasPrefix(data, modulePrefix[1:]) {
1285                         i = 0
1286                 } else {
1287                         i = bytes.Index(data, modulePrefix)
1288                         if i < 0 {
1289                                 return ""
1290                         }
1291                         i++
1292                 }
1293                 line := data[i:]
1294
1295                 // Cut line at \n, drop trailing \r if present.
1296                 if j := bytes.IndexByte(line, '\n'); j >= 0 {
1297                         line = line[:j]
1298                 }
1299                 if line[len(line)-1] == '\r' {
1300                         line = line[:len(line)-1]
1301                 }
1302                 line = line[len("module "):]
1303
1304                 // If quoted, unquote.
1305                 path = strings.TrimSpace(string(line))
1306                 if path != "" && path[0] == '"' {
1307                         s, err := strconv.Unquote(path)
1308                         if err != nil {
1309                                 return ""
1310                         }
1311                         path = s
1312                 }
1313                 return path
1314         })
1315 }
1316
1317 // findVersionElement returns the slice indices of the final version element /vN in path.
1318 // If there is no such element, it returns -1, -1.
1319 func findVersionElement(path string) (i, j int) {
1320         j = len(path)
1321         for i = len(path) - 1; i >= 0; i-- {
1322                 if path[i] == '/' {
1323                         if isVersionElement(path[i+1 : j]) {
1324                                 return i, j
1325                         }
1326                         j = i
1327                 }
1328         }
1329         return -1, -1
1330 }
1331
1332 // isVersionElement reports whether s is a well-formed path version element:
1333 // v2, v3, v10, etc, but not v0, v05, v1.
1334 func isVersionElement(s string) bool {
1335         if len(s) < 2 || s[0] != 'v' || s[1] == '0' || s[1] == '1' && len(s) == 2 {
1336                 return false
1337         }
1338         for i := 1; i < len(s); i++ {
1339                 if s[i] < '0' || '9' < s[i] {
1340                         return false
1341                 }
1342         }
1343         return true
1344 }
1345
1346 // moduleImportPath translates import paths found in go modules
1347 // back down to paths that can be resolved in ordinary builds.
1348 //
1349 // Define “new” code as code with a go.mod file in the same directory
1350 // or a parent directory. If an import in new code says x/y/v2/z but
1351 // x/y/v2/z does not exist and x/y/go.mod says “module x/y/v2”,
1352 // then go build will read the import as x/y/z instead.
1353 // See golang.org/issue/25069.
1354 func moduleImportPath(path, parentPath, parentDir, parentRoot string) (found string) {
1355         if parentRoot == "" {
1356                 return path
1357         }
1358
1359         // If there are no vN elements in path, leave it alone.
1360         // (The code below would do the same, but only after
1361         // some other file system accesses that we can avoid
1362         // here by returning early.)
1363         if i, _ := findVersionElement(path); i < 0 {
1364                 return path
1365         }
1366
1367         dir, root := dirAndRoot(parentPath, parentDir, parentRoot)
1368
1369         // Consider dir and parents, up to and including root.
1370         for i := len(dir); i >= len(root); i-- {
1371                 if i < len(dir) && dir[i] != filepath.Separator {
1372                         continue
1373                 }
1374                 if goModPath(dir[:i]) != "" {
1375                         goto HaveGoMod
1376                 }
1377         }
1378         // This code is not in a tree with a go.mod,
1379         // so apply no changes to the path.
1380         return path
1381
1382 HaveGoMod:
1383         // This import is in a tree with a go.mod.
1384         // Allow it to refer to code in GOPATH/src/x/y/z as x/y/v2/z
1385         // if GOPATH/src/x/y/go.mod says module "x/y/v2",
1386
1387         // If x/y/v2/z exists, use it unmodified.
1388         if bp, _ := cfg.BuildContext.Import(path, "", build.IgnoreVendor); bp.Dir != "" {
1389                 return path
1390         }
1391
1392         // Otherwise look for a go.mod supplying a version element.
1393         // Some version-like elements may appear in paths but not
1394         // be module versions; we skip over those to look for module
1395         // versions. For example the module m/v2 might have a
1396         // package m/v2/api/v1/foo.
1397         limit := len(path)
1398         for limit > 0 {
1399                 i, j := findVersionElement(path[:limit])
1400                 if i < 0 {
1401                         return path
1402                 }
1403                 if bp, _ := cfg.BuildContext.Import(path[:i], "", build.IgnoreVendor); bp.Dir != "" {
1404                         if mpath := goModPath(bp.Dir); mpath != "" {
1405                                 // Found a valid go.mod file, so we're stopping the search.
1406                                 // If the path is m/v2/p and we found m/go.mod that says
1407                                 // "module m/v2", then we return "m/p".
1408                                 if mpath == path[:j] {
1409                                         return path[:i] + path[j:]
1410                                 }
1411                                 // Otherwise just return the original path.
1412                                 // We didn't find anything worth rewriting,
1413                                 // and the go.mod indicates that we should
1414                                 // not consider parent directories.
1415                                 return path
1416                         }
1417                 }
1418                 limit = i
1419         }
1420         return path
1421 }
1422
1423 // hasGoFiles reports whether dir contains any files with names ending in .go.
1424 // For a vendor check we must exclude directories that contain no .go files.
1425 // Otherwise it is not possible to vendor just a/b/c and still import the
1426 // non-vendored a/b. See golang.org/issue/13832.
1427 func hasGoFiles(dir string) bool {
1428         files, _ := os.ReadDir(dir)
1429         for _, f := range files {
1430                 if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") {
1431                         return true
1432                 }
1433         }
1434         return false
1435 }
1436
1437 // reusePackage reuses package p to satisfy the import at the top
1438 // of the import stack stk. If this use causes an import loop,
1439 // reusePackage updates p's error information to record the loop.
1440 func reusePackage(p *Package, stk *ImportStack) *Package {
1441         // We use p.Internal.Imports==nil to detect a package that
1442         // is in the midst of its own loadPackage call
1443         // (all the recursion below happens before p.Internal.Imports gets set).
1444         if p.Internal.Imports == nil {
1445                 if p.Error == nil {
1446                         p.Error = &PackageError{
1447                                 ImportStack:   stk.Copy(),
1448                                 Err:           errors.New("import cycle not allowed"),
1449                                 IsImportCycle: true,
1450                         }
1451                 } else if !p.Error.IsImportCycle {
1452                         // If the error is already set, but it does not indicate that
1453                         // we are in an import cycle, set IsImportCycle so that we don't
1454                         // end up stuck in a loop down the road.
1455                         p.Error.IsImportCycle = true
1456                 }
1457                 p.Incomplete = true
1458         }
1459         // Don't rewrite the import stack in the error if we have an import cycle.
1460         // If we do, we'll lose the path that describes the cycle.
1461         if p.Error != nil && !p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack) {
1462                 p.Error.ImportStack = stk.Copy()
1463         }
1464         return p
1465 }
1466
1467 // disallowInternal checks that srcDir (containing package importerPath, if non-empty)
1468 // is allowed to import p.
1469 // If the import is allowed, disallowInternal returns the original package p.
1470 // If not, it returns a new package containing just an appropriate error.
1471 func disallowInternal(ctx context.Context, srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *PackageError {
1472         // golang.org/s/go14internal:
1473         // An import of a path containing the element “internal”
1474         // is disallowed if the importing code is outside the tree
1475         // rooted at the parent of the “internal” directory.
1476
1477         // There was an error loading the package; stop here.
1478         if p.Error != nil {
1479                 return nil
1480         }
1481
1482         // The generated 'testmain' package is allowed to access testing/internal/...,
1483         // as if it were generated into the testing directory tree
1484         // (it's actually in a temporary directory outside any Go tree).
1485         // This cleans up a former kludge in passing functionality to the testing package.
1486         if str.HasPathPrefix(p.ImportPath, "testing/internal") && importerPath == "testmain" {
1487                 return nil
1488         }
1489
1490         // We can't check standard packages with gccgo.
1491         if cfg.BuildContext.Compiler == "gccgo" && p.Standard {
1492                 return nil
1493         }
1494
1495         // The sort package depends on internal/reflectlite, but during bootstrap
1496         // the path rewriting causes the normal internal checks to fail.
1497         // Instead, just ignore the internal rules during bootstrap.
1498         if p.Standard && strings.HasPrefix(importerPath, "bootstrap/") {
1499                 return nil
1500         }
1501
1502         // importerPath is empty: we started
1503         // with a name given on the command line, not an
1504         // import. Anything listed on the command line is fine.
1505         if importerPath == "" {
1506                 return nil
1507         }
1508
1509         // Check for "internal" element: three cases depending on begin of string and/or end of string.
1510         i, ok := findInternal(p.ImportPath)
1511         if !ok {
1512                 return nil
1513         }
1514
1515         // Internal is present.
1516         // Map import path back to directory corresponding to parent of internal.
1517         if i > 0 {
1518                 i-- // rewind over slash in ".../internal"
1519         }
1520
1521         if p.Module == nil {
1522                 parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
1523
1524                 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1525                         return nil
1526                 }
1527
1528                 // Look for symlinks before reporting error.
1529                 srcDir = expandPath(srcDir)
1530                 parent = expandPath(parent)
1531                 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1532                         return nil
1533                 }
1534         } else {
1535                 // p is in a module, so make it available based on the importer's import path instead
1536                 // of the file path (https://golang.org/issue/23970).
1537                 if importer.Internal.CmdlineFiles {
1538                         // The importer is a list of command-line files.
1539                         // Pretend that the import path is the import path of the
1540                         // directory containing them.
1541                         // If the directory is outside the main modules, this will resolve to ".",
1542                         // which is not a prefix of any valid module.
1543                         importerPath, _ = modload.MainModules.DirImportPath(ctx, importer.Dir)
1544                 }
1545                 parentOfInternal := p.ImportPath[:i]
1546                 if str.HasPathPrefix(importerPath, parentOfInternal) {
1547                         return nil
1548                 }
1549         }
1550
1551         // Internal is present, and srcDir is outside parent's tree. Not allowed.
1552         perr := &PackageError{
1553                 alwaysPrintStack: true,
1554                 ImportStack:      stk.Copy(),
1555                 Err:              ImportErrorf(p.ImportPath, "use of internal package "+p.ImportPath+" not allowed"),
1556         }
1557         return perr
1558 }
1559
1560 // findInternal looks for the final "internal" path element in the given import path.
1561 // If there isn't one, findInternal returns ok=false.
1562 // Otherwise, findInternal returns ok=true and the index of the "internal".
1563 func findInternal(path string) (index int, ok bool) {
1564         // Three cases, depending on internal at start/end of string or not.
1565         // The order matters: we must return the index of the final element,
1566         // because the final one produces the most restrictive requirement
1567         // on the importer.
1568         switch {
1569         case strings.HasSuffix(path, "/internal"):
1570                 return len(path) - len("internal"), true
1571         case strings.Contains(path, "/internal/"):
1572                 return strings.LastIndex(path, "/internal/") + 1, true
1573         case path == "internal", strings.HasPrefix(path, "internal/"):
1574                 return 0, true
1575         }
1576         return 0, false
1577 }
1578
1579 // disallowVendor checks that srcDir is allowed to import p as path.
1580 // If the import is allowed, disallowVendor returns the original package p.
1581 // If not, it returns a PackageError.
1582 func disallowVendor(srcDir string, path string, importerPath string, p *Package, stk *ImportStack) *PackageError {
1583         // If the importerPath is empty, we started
1584         // with a name given on the command line, not an
1585         // import. Anything listed on the command line is fine.
1586         if importerPath == "" {
1587                 return nil
1588         }
1589
1590         if perr := disallowVendorVisibility(srcDir, p, importerPath, stk); perr != nil {
1591                 return perr
1592         }
1593
1594         // Paths like x/vendor/y must be imported as y, never as x/vendor/y.
1595         if i, ok := FindVendor(path); ok {
1596                 perr := &PackageError{
1597                         ImportStack: stk.Copy(),
1598                         Err:         ImportErrorf(path, "%s must be imported as %s", path, path[i+len("vendor/"):]),
1599                 }
1600                 return perr
1601         }
1602
1603         return nil
1604 }
1605
1606 // disallowVendorVisibility checks that srcDir is allowed to import p.
1607 // The rules are the same as for /internal/ except that a path ending in /vendor
1608 // is not subject to the rules, only subdirectories of vendor.
1609 // This allows people to have packages and commands named vendor,
1610 // for maximal compatibility with existing source trees.
1611 func disallowVendorVisibility(srcDir string, p *Package, importerPath string, stk *ImportStack) *PackageError {
1612         // The stack does not include p.ImportPath.
1613         // If there's nothing on the stack, we started
1614         // with a name given on the command line, not an
1615         // import. Anything listed on the command line is fine.
1616         if importerPath == "" {
1617                 return nil
1618         }
1619
1620         // Check for "vendor" element.
1621         i, ok := FindVendor(p.ImportPath)
1622         if !ok {
1623                 return nil
1624         }
1625
1626         // Vendor is present.
1627         // Map import path back to directory corresponding to parent of vendor.
1628         if i > 0 {
1629                 i-- // rewind over slash in ".../vendor"
1630         }
1631         truncateTo := i + len(p.Dir) - len(p.ImportPath)
1632         if truncateTo < 0 || len(p.Dir) < truncateTo {
1633                 return nil
1634         }
1635         parent := p.Dir[:truncateTo]
1636         if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1637                 return nil
1638         }
1639
1640         // Look for symlinks before reporting error.
1641         srcDir = expandPath(srcDir)
1642         parent = expandPath(parent)
1643         if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
1644                 return nil
1645         }
1646
1647         // Vendor is present, and srcDir is outside parent's tree. Not allowed.
1648
1649         perr := &PackageError{
1650                 ImportStack: stk.Copy(),
1651                 Err:         errors.New("use of vendored package not allowed"),
1652         }
1653         return perr
1654 }
1655
1656 // FindVendor looks for the last non-terminating "vendor" path element in the given import path.
1657 // If there isn't one, FindVendor returns ok=false.
1658 // Otherwise, FindVendor returns ok=true and the index of the "vendor".
1659 //
1660 // Note that terminating "vendor" elements don't count: "x/vendor" is its own package,
1661 // not the vendored copy of an import "" (the empty import path).
1662 // This will allow people to have packages or commands named vendor.
1663 // This may help reduce breakage, or it may just be confusing. We'll see.
1664 func FindVendor(path string) (index int, ok bool) {
1665         // Two cases, depending on internal at start of string or not.
1666         // The order matters: we must return the index of the final element,
1667         // because the final one is where the effective import path starts.
1668         switch {
1669         case strings.Contains(path, "/vendor/"):
1670                 return strings.LastIndex(path, "/vendor/") + 1, true
1671         case strings.HasPrefix(path, "vendor/"):
1672                 return 0, true
1673         }
1674         return 0, false
1675 }
1676
1677 type TargetDir int
1678
1679 const (
1680         ToTool    TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*)
1681         ToBin                      // to bin dir inside package root (default for non-cmd/*)
1682         StalePath                  // an old import path; fail to build
1683 )
1684
1685 // InstallTargetDir reports the target directory for installing the command p.
1686 func InstallTargetDir(p *Package) TargetDir {
1687         if strings.HasPrefix(p.ImportPath, "code.google.com/p/go.tools/cmd/") {
1688                 return StalePath
1689         }
1690         if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" {
1691                 switch p.ImportPath {
1692                 case "cmd/go", "cmd/gofmt":
1693                         return ToBin
1694                 }
1695                 return ToTool
1696         }
1697         return ToBin
1698 }
1699
1700 var cgoExclude = map[string]bool{
1701         "runtime/cgo": true,
1702 }
1703
1704 var cgoSyscallExclude = map[string]bool{
1705         "runtime/cgo":  true,
1706         "runtime/race": true,
1707         "runtime/msan": true,
1708         "runtime/asan": true,
1709 }
1710
1711 var foldPath = make(map[string]string)
1712
1713 // exeFromImportPath returns an executable name
1714 // for a package using the import path.
1715 //
1716 // The executable name is the last element of the import path.
1717 // In module-aware mode, an additional rule is used on import paths
1718 // consisting of two or more path elements. If the last element is
1719 // a vN path element specifying the major version, then the
1720 // second last element of the import path is used instead.
1721 func (p *Package) exeFromImportPath() string {
1722         _, elem := pathpkg.Split(p.ImportPath)
1723         if cfg.ModulesEnabled {
1724                 // If this is example.com/mycmd/v2, it's more useful to
1725                 // install it as mycmd than as v2. See golang.org/issue/24667.
1726                 if elem != p.ImportPath && isVersionElement(elem) {
1727                         _, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath))
1728                 }
1729         }
1730         return elem
1731 }
1732
1733 // exeFromFiles returns an executable name for a package
1734 // using the first element in GoFiles or CgoFiles collections without the prefix.
1735 //
1736 // Returns empty string in case of empty collection.
1737 func (p *Package) exeFromFiles() string {
1738         var src string
1739         if len(p.GoFiles) > 0 {
1740                 src = p.GoFiles[0]
1741         } else if len(p.CgoFiles) > 0 {
1742                 src = p.CgoFiles[0]
1743         } else {
1744                 return ""
1745         }
1746         _, elem := filepath.Split(src)
1747         return elem[:len(elem)-len(".go")]
1748 }
1749
1750 // DefaultExecName returns the default executable name for a package
1751 func (p *Package) DefaultExecName() string {
1752         if p.Internal.CmdlineFiles {
1753                 return p.exeFromFiles()
1754         }
1755         return p.exeFromImportPath()
1756 }
1757
1758 // load populates p using information from bp, err, which should
1759 // be the result of calling build.Context.Import.
1760 // stk contains the import stack, not including path itself.
1761 func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) {
1762         p.copyBuild(opts, bp)
1763
1764         // The localPrefix is the path we interpret ./ imports relative to,
1765         // if we support them at all (not in module mode!).
1766         // Synthesized main packages sometimes override this.
1767         if p.Internal.Local && !cfg.ModulesEnabled {
1768                 p.Internal.LocalPrefix = dirToImportPath(p.Dir)
1769         }
1770
1771         // setError sets p.Error if it hasn't already been set. We may proceed
1772         // after encountering some errors so that 'go list -e' has more complete
1773         // output. If there's more than one error, we should report the first.
1774         setError := func(err error) {
1775                 if p.Error == nil {
1776                         p.Error = &PackageError{
1777                                 ImportStack: stk.Copy(),
1778                                 Err:         err,
1779                         }
1780                         p.Incomplete = true
1781
1782                         // Add the importer's position information if the import position exists, and
1783                         // the current package being examined is the importer.
1784                         // If we have not yet accepted package p onto the import stack,
1785                         // then the cause of the error is not within p itself: the error
1786                         // must be either in an explicit command-line argument,
1787                         // or on the importer side (indicated by a non-empty importPos).
1788                         if path != stk.Top() && len(importPos) > 0 {
1789                                 p.Error.setPos(importPos)
1790                         }
1791                 }
1792         }
1793
1794         if err != nil {
1795                 p.Incomplete = true
1796                 p.setLoadPackageDataError(err, path, stk, importPos)
1797         }
1798
1799         useBindir := p.Name == "main"
1800         if !p.Standard {
1801                 switch cfg.BuildBuildmode {
1802                 case "c-archive", "c-shared", "plugin":
1803                         useBindir = false
1804                 }
1805         }
1806
1807         if useBindir {
1808                 // Report an error when the old code.google.com/p/go.tools paths are used.
1809                 if InstallTargetDir(p) == StalePath {
1810                         // TODO(matloob): remove this branch, and StalePath itself. code.google.com/p/go is so
1811                         // old, even this code checking for it is stale now!
1812                         newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1)
1813                         e := ImportErrorf(p.ImportPath, "the %v command has moved; use %v instead.", p.ImportPath, newPath)
1814                         setError(e)
1815                         return
1816                 }
1817                 elem := p.DefaultExecName() + cfg.ExeSuffix
1818                 full := filepath.Join(cfg.BuildContext.GOOS+"_"+cfg.BuildContext.GOARCH, elem)
1819                 if cfg.BuildContext.GOOS != runtime.GOOS || cfg.BuildContext.GOARCH != runtime.GOARCH {
1820                         // Install cross-compiled binaries to subdirectories of bin.
1821                         elem = full
1822                 }
1823                 if p.Internal.Build.BinDir == "" && cfg.ModulesEnabled {
1824                         p.Internal.Build.BinDir = modload.BinDir()
1825                 }
1826                 if p.Internal.Build.BinDir != "" {
1827                         // Install to GOBIN or bin of GOPATH entry.
1828                         p.Target = filepath.Join(p.Internal.Build.BinDir, elem)
1829                         if !p.Goroot && strings.Contains(elem, string(filepath.Separator)) && cfg.GOBIN != "" {
1830                                 // Do not create $GOBIN/goos_goarch/elem.
1831                                 p.Target = ""
1832                                 p.Internal.GobinSubdir = true
1833                         }
1834                 }
1835                 if InstallTargetDir(p) == ToTool {
1836                         // This is for 'go tool'.
1837                         // Override all the usual logic and force it into the tool directory.
1838                         if cfg.BuildToolchainName == "gccgo" {
1839                                 p.Target = filepath.Join(build.ToolDir, elem)
1840                         } else {
1841                                 p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full)
1842                         }
1843                 }
1844         } else if p.Internal.Local {
1845                 // Local import turned into absolute path.
1846                 // No permanent install target.
1847                 p.Target = ""
1848         } else if p.Standard && cfg.BuildContext.Compiler == "gccgo" {
1849                 // gccgo has a preinstalled standard library that cmd/go cannot rebuild.
1850                 p.Target = ""
1851         } else {
1852                 p.Target = p.Internal.Build.PkgObj
1853                 if cfg.BuildBuildmode == "shared" && p.Internal.Build.PkgTargetRoot != "" {
1854                         // TODO(matloob): This shouldn't be necessary, but the cmd/cgo/internal/testshared
1855                         // test fails without Target set for this condition. Figure out why and
1856                         // fix it.
1857                         p.Target = filepath.Join(p.Internal.Build.PkgTargetRoot, p.ImportPath+".a")
1858                 }
1859                 if cfg.BuildLinkshared && p.Internal.Build.PkgTargetRoot != "" {
1860                         // TODO(bcmills): The reliance on PkgTargetRoot implies that -linkshared does
1861                         // not work for any package that lacks a PkgTargetRoot — such as a non-main
1862                         // package in module mode. We should probably fix that.
1863                         targetPrefix := filepath.Join(p.Internal.Build.PkgTargetRoot, p.ImportPath)
1864                         p.Target = targetPrefix + ".a"
1865                         shlibnamefile := targetPrefix + ".shlibname"
1866                         shlib, err := os.ReadFile(shlibnamefile)
1867                         if err != nil && !os.IsNotExist(err) {
1868                                 base.Fatalf("reading shlibname: %v", err)
1869                         }
1870                         if err == nil {
1871                                 libname := strings.TrimSpace(string(shlib))
1872                                 if cfg.BuildContext.Compiler == "gccgo" {
1873                                         p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname)
1874                                 } else {
1875                                         p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname)
1876                                 }
1877                         }
1878                 }
1879         }
1880
1881         // Build augmented import list to add implicit dependencies.
1882         // Be careful not to add imports twice, just to avoid confusion.
1883         importPaths := p.Imports
1884         addImport := func(path string, forCompiler bool) {
1885                 for _, p := range importPaths {
1886                         if path == p {
1887                                 return
1888                         }
1889                 }
1890                 importPaths = append(importPaths, path)
1891                 if forCompiler {
1892                         p.Internal.CompiledImports = append(p.Internal.CompiledImports, path)
1893                 }
1894         }
1895
1896         if !opts.IgnoreImports {
1897                 // Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall",
1898                 // except for certain packages, to avoid circular dependencies.
1899                 if p.UsesCgo() {
1900                         addImport("unsafe", true)
1901                 }
1902                 if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {
1903                         addImport("runtime/cgo", true)
1904                 }
1905                 if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
1906                         addImport("syscall", true)
1907                 }
1908
1909                 // SWIG adds imports of some standard packages.
1910                 if p.UsesSwig() {
1911                         addImport("unsafe", true)
1912                         if cfg.BuildContext.Compiler != "gccgo" {
1913                                 addImport("runtime/cgo", true)
1914                         }
1915                         addImport("syscall", true)
1916                         addImport("sync", true)
1917
1918                         // TODO: The .swig and .swigcxx files can use
1919                         // %go_import directives to import other packages.
1920                 }
1921
1922                 // The linker loads implicit dependencies.
1923                 if p.Name == "main" && !p.Internal.ForceLibrary {
1924                         for _, dep := range LinkerDeps(p) {
1925                                 addImport(dep, false)
1926                         }
1927                 }
1928         }
1929
1930         // Check for case-insensitive collisions of import paths.
1931         fold := str.ToFold(p.ImportPath)
1932         if other := foldPath[fold]; other == "" {
1933                 foldPath[fold] = p.ImportPath
1934         } else if other != p.ImportPath {
1935                 setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other))
1936                 return
1937         }
1938
1939         if !SafeArg(p.ImportPath) {
1940                 setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath))
1941                 return
1942         }
1943
1944         // Errors after this point are caused by this package, not the importing
1945         // package. Pushing the path here prevents us from reporting the error
1946         // with the position of the import declaration.
1947         stk.Push(path)
1948         defer stk.Pop()
1949
1950         pkgPath := p.ImportPath
1951         if p.Internal.CmdlineFiles {
1952                 pkgPath = "command-line-arguments"
1953         }
1954         if cfg.ModulesEnabled {
1955                 p.Module = modload.PackageModuleInfo(ctx, pkgPath)
1956         }
1957         p.DefaultGODEBUG = defaultGODEBUG(p, nil, nil, nil)
1958
1959         if !opts.SuppressEmbedFiles {
1960                 p.EmbedFiles, p.Internal.Embed, err = resolveEmbed(p.Dir, p.EmbedPatterns)
1961                 if err != nil {
1962                         p.Incomplete = true
1963                         setError(err)
1964                         embedErr := err.(*EmbedError)
1965                         p.Error.setPos(p.Internal.Build.EmbedPatternPos[embedErr.Pattern])
1966                 }
1967         }
1968
1969         // Check for case-insensitive collision of input files.
1970         // To avoid problems on case-insensitive files, we reject any package
1971         // where two different input files have equal names under a case-insensitive
1972         // comparison.
1973         inputs := p.AllFiles()
1974         f1, f2 := str.FoldDup(inputs)
1975         if f1 != "" {
1976                 setError(fmt.Errorf("case-insensitive file name collision: %q and %q", f1, f2))
1977                 return
1978         }
1979
1980         // If first letter of input file is ASCII, it must be alphanumeric.
1981         // This avoids files turning into flags when invoking commands,
1982         // and other problems we haven't thought of yet.
1983         // Also, _cgo_ files must be generated by us, not supplied.
1984         // They are allowed to have //go:cgo_ldflag directives.
1985         // The directory scan ignores files beginning with _,
1986         // so we shouldn't see any _cgo_ files anyway, but just be safe.
1987         for _, file := range inputs {
1988                 if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") {
1989                         setError(fmt.Errorf("invalid input file name %q", file))
1990                         return
1991                 }
1992         }
1993         if name := pathpkg.Base(p.ImportPath); !SafeArg(name) {
1994                 setError(fmt.Errorf("invalid input directory name %q", name))
1995                 return
1996         }
1997
1998         // Build list of imported packages and full dependency list.
1999         imports := make([]*Package, 0, len(p.Imports))
2000         for i, path := range importPaths {
2001                 if path == "C" {
2002                         continue
2003                 }
2004                 p1, err := LoadImport(ctx, opts, path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport)
2005                 if err != nil && p.Error == nil {
2006                         p.Error = err
2007                         p.Incomplete = true
2008                 }
2009
2010                 path = p1.ImportPath
2011                 importPaths[i] = path
2012                 if i < len(p.Imports) {
2013                         p.Imports[i] = path
2014                 }
2015
2016                 imports = append(imports, p1)
2017                 if p1.Incomplete {
2018                         p.Incomplete = true
2019                 }
2020         }
2021         p.Internal.Imports = imports
2022         if p.Error == nil && p.Name == "main" && !p.Internal.ForceLibrary && !p.Incomplete && !opts.SuppressBuildInfo {
2023                 // TODO(bcmills): loading VCS metadata can be fairly slow.
2024                 // Consider starting this as a background goroutine and retrieving the result
2025                 // asynchronously when we're actually ready to build the package, or when we
2026                 // actually need to evaluate whether the package's metadata is stale.
2027                 p.setBuildInfo(opts.AutoVCS)
2028         }
2029
2030         // If cgo is not enabled, ignore cgo supporting sources
2031         // just as we ignore go files containing import "C".
2032         if !cfg.BuildContext.CgoEnabled {
2033                 p.CFiles = nil
2034                 p.CXXFiles = nil
2035                 p.MFiles = nil
2036                 p.SwigFiles = nil
2037                 p.SwigCXXFiles = nil
2038                 // Note that SFiles are okay (they go to the Go assembler)
2039                 // and HFiles are okay (they might be used by the SFiles).
2040                 // Also Sysofiles are okay (they might not contain object
2041                 // code; see issue #16050).
2042         }
2043
2044         // The gc toolchain only permits C source files with cgo or SWIG.
2045         if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" {
2046                 setError(fmt.Errorf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")))
2047                 return
2048         }
2049
2050         // C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG,
2051         // regardless of toolchain.
2052         if len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
2053                 setError(fmt.Errorf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " ")))
2054                 return
2055         }
2056         if len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
2057                 setError(fmt.Errorf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " ")))
2058                 return
2059         }
2060         if len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
2061                 setError(fmt.Errorf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " ")))
2062                 return
2063         }
2064 }
2065
2066 // An EmbedError indicates a problem with a go:embed directive.
2067 type EmbedError struct {
2068         Pattern string
2069         Err     error
2070 }
2071
2072 func (e *EmbedError) Error() string {
2073         return fmt.Sprintf("pattern %s: %v", e.Pattern, e.Err)
2074 }
2075
2076 func (e *EmbedError) Unwrap() error {
2077         return e.Err
2078 }
2079
2080 // ResolveEmbed resolves //go:embed patterns and returns only the file list.
2081 // For use by go mod vendor to find embedded files it should copy into the
2082 // vendor directory.
2083 // TODO(#42504): Once go mod vendor uses load.PackagesAndErrors, just
2084 // call (*Package).ResolveEmbed
2085 func ResolveEmbed(dir string, patterns []string) ([]string, error) {
2086         files, _, err := resolveEmbed(dir, patterns)
2087         return files, err
2088 }
2089
2090 // resolveEmbed resolves //go:embed patterns to precise file lists.
2091 // It sets files to the list of unique files matched (for go list),
2092 // and it sets pmap to the more precise mapping from
2093 // patterns to files.
2094 func resolveEmbed(pkgdir string, patterns []string) (files []string, pmap map[string][]string, err error) {
2095         var pattern string
2096         defer func() {
2097                 if err != nil {
2098                         err = &EmbedError{
2099                                 Pattern: pattern,
2100                                 Err:     err,
2101                         }
2102                 }
2103         }()
2104
2105         // TODO(rsc): All these messages need position information for better error reports.
2106         pmap = make(map[string][]string)
2107         have := make(map[string]int)
2108         dirOK := make(map[string]bool)
2109         pid := 0 // pattern ID, to allow reuse of have map
2110         for _, pattern = range patterns {
2111                 pid++
2112
2113                 glob := pattern
2114                 all := strings.HasPrefix(pattern, "all:")
2115                 if all {
2116                         glob = pattern[len("all:"):]
2117                 }
2118                 // Check pattern is valid for //go:embed.
2119                 if _, err := pathpkg.Match(glob, ""); err != nil || !validEmbedPattern(glob) {
2120                         return nil, nil, fmt.Errorf("invalid pattern syntax")
2121                 }
2122
2123                 // Glob to find matches.
2124                 match, err := fsys.Glob(str.QuoteGlob(str.WithFilePathSeparator(pkgdir)) + filepath.FromSlash(glob))
2125                 if err != nil {
2126                         return nil, nil, err
2127                 }
2128
2129                 // Filter list of matches down to the ones that will still exist when
2130                 // the directory is packaged up as a module. (If p.Dir is in the module cache,
2131                 // only those files exist already, but if p.Dir is in the current module,
2132                 // then there may be other things lying around, like symbolic links or .git directories.)
2133                 var list []string
2134                 for _, file := range match {
2135                         // relative path to p.Dir which begins without prefix slash
2136                         rel := filepath.ToSlash(str.TrimFilePathPrefix(file, pkgdir))
2137
2138                         what := "file"
2139                         info, err := fsys.Lstat(file)
2140                         if err != nil {
2141                                 return nil, nil, err
2142                         }
2143                         if info.IsDir() {
2144                                 what = "directory"
2145                         }
2146
2147                         // Check that directories along path do not begin a new module
2148                         // (do not contain a go.mod).
2149                         for dir := file; len(dir) > len(pkgdir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) {
2150                                 if _, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil {
2151                                         return nil, nil, fmt.Errorf("cannot embed %s %s: in different module", what, rel)
2152                                 }
2153                                 if dir != file {
2154                                         if info, err := fsys.Lstat(dir); err == nil && !info.IsDir() {
2155                                                 return nil, nil, fmt.Errorf("cannot embed %s %s: in non-directory %s", what, rel, dir[len(pkgdir)+1:])
2156                                         }
2157                                 }
2158                                 dirOK[dir] = true
2159                                 if elem := filepath.Base(dir); isBadEmbedName(elem) {
2160                                         if dir == file {
2161                                                 return nil, nil, fmt.Errorf("cannot embed %s %s: invalid name %s", what, rel, elem)
2162                                         } else {
2163                                                 return nil, nil, fmt.Errorf("cannot embed %s %s: in invalid directory %s", what, rel, elem)
2164                                         }
2165                                 }
2166                         }
2167
2168                         switch {
2169                         default:
2170                                 return nil, nil, fmt.Errorf("cannot embed irregular file %s", rel)
2171
2172                         case info.Mode().IsRegular():
2173                                 if have[rel] != pid {
2174                                         have[rel] = pid
2175                                         list = append(list, rel)
2176                                 }
2177
2178                         case info.IsDir():
2179                                 // Gather all files in the named directory, stopping at module boundaries
2180                                 // and ignoring files that wouldn't be packaged into a module.
2181                                 count := 0
2182                                 err := fsys.Walk(file, func(path string, info os.FileInfo, err error) error {
2183                                         if err != nil {
2184                                                 return err
2185                                         }
2186                                         rel := filepath.ToSlash(str.TrimFilePathPrefix(path, pkgdir))
2187                                         name := info.Name()
2188                                         if path != file && (isBadEmbedName(name) || ((name[0] == '.' || name[0] == '_') && !all)) {
2189                                                 // Ignore bad names, assuming they won't go into modules.
2190                                                 // Also avoid hidden files that user may not know about.
2191                                                 // See golang.org/issue/42328.
2192                                                 if info.IsDir() {
2193                                                         return fs.SkipDir
2194                                                 }
2195                                                 return nil
2196                                         }
2197                                         if info.IsDir() {
2198                                                 if _, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil {
2199                                                         return filepath.SkipDir
2200                                                 }
2201                                                 return nil
2202                                         }
2203                                         if !info.Mode().IsRegular() {
2204                                                 return nil
2205                                         }
2206                                         count++
2207                                         if have[rel] != pid {
2208                                                 have[rel] = pid
2209                                                 list = append(list, rel)
2210                                         }
2211                                         return nil
2212                                 })
2213                                 if err != nil {
2214                                         return nil, nil, err
2215                                 }
2216                                 if count == 0 {
2217                                         return nil, nil, fmt.Errorf("cannot embed directory %s: contains no embeddable files", rel)
2218                                 }
2219                         }
2220                 }
2221
2222                 if len(list) == 0 {
2223                         return nil, nil, fmt.Errorf("no matching files found")
2224                 }
2225                 sort.Strings(list)
2226                 pmap[pattern] = list
2227         }
2228
2229         for file := range have {
2230                 files = append(files, file)
2231         }
2232         sort.Strings(files)
2233         return files, pmap, nil
2234 }
2235
2236 func validEmbedPattern(pattern string) bool {
2237         return pattern != "." && fs.ValidPath(pattern)
2238 }
2239
2240 // isBadEmbedName reports whether name is the base name of a file that
2241 // can't or won't be included in modules and therefore shouldn't be treated
2242 // as existing for embedding.
2243 func isBadEmbedName(name string) bool {
2244         if err := module.CheckFilePath(name); err != nil {
2245                 return true
2246         }
2247         switch name {
2248         // Empty string should be impossible but make it bad.
2249         case "":
2250                 return true
2251         // Version control directories won't be present in module.
2252         case ".bzr", ".hg", ".git", ".svn":
2253                 return true
2254         }
2255         return false
2256 }
2257
2258 // vcsStatusCache maps repository directories (string)
2259 // to their VCS information.
2260 var vcsStatusCache par.ErrCache[string, vcs.Status]
2261
2262 // setBuildInfo gathers build information, formats it as a string to be
2263 // embedded in the binary, then sets p.Internal.BuildInfo to that string.
2264 // setBuildInfo should only be called on a main package with no errors.
2265 //
2266 // This information can be retrieved using debug.ReadBuildInfo.
2267 //
2268 // Note that the GoVersion field is not set here to avoid encoding it twice.
2269 // It is stored separately in the binary, mostly for historical reasons.
2270 func (p *Package) setBuildInfo(autoVCS bool) {
2271         setPkgErrorf := func(format string, args ...any) {
2272                 if p.Error == nil {
2273                         p.Error = &PackageError{Err: fmt.Errorf(format, args...)}
2274                         p.Incomplete = true
2275                 }
2276         }
2277
2278         var debugModFromModinfo func(*modinfo.ModulePublic) *debug.Module
2279         debugModFromModinfo = func(mi *modinfo.ModulePublic) *debug.Module {
2280                 version := mi.Version
2281                 if version == "" {
2282                         version = "(devel)"
2283                 }
2284                 dm := &debug.Module{
2285                         Path:    mi.Path,
2286                         Version: version,
2287                 }
2288                 if mi.Replace != nil {
2289                         dm.Replace = debugModFromModinfo(mi.Replace)
2290                 } else if mi.Version != "" {
2291                         dm.Sum = modfetch.Sum(module.Version{Path: mi.Path, Version: mi.Version})
2292                 }
2293                 return dm
2294         }
2295
2296         var main debug.Module
2297         if p.Module != nil {
2298                 main = *debugModFromModinfo(p.Module)
2299         }
2300
2301         visited := make(map[*Package]bool)
2302         mdeps := make(map[module.Version]*debug.Module)
2303         var q []*Package
2304         q = append(q, p.Internal.Imports...)
2305         for len(q) > 0 {
2306                 p1 := q[0]
2307                 q = q[1:]
2308                 if visited[p1] {
2309                         continue
2310                 }
2311                 visited[p1] = true
2312                 if p1.Module != nil {
2313                         m := module.Version{Path: p1.Module.Path, Version: p1.Module.Version}
2314                         if p1.Module.Path != main.Path && mdeps[m] == nil {
2315                                 mdeps[m] = debugModFromModinfo(p1.Module)
2316                         }
2317                 }
2318                 q = append(q, p1.Internal.Imports...)
2319         }
2320         sortedMods := make([]module.Version, 0, len(mdeps))
2321         for mod := range mdeps {
2322                 sortedMods = append(sortedMods, mod)
2323         }
2324         module.Sort(sortedMods)
2325         deps := make([]*debug.Module, len(sortedMods))
2326         for i, mod := range sortedMods {
2327                 deps[i] = mdeps[mod]
2328         }
2329
2330         pkgPath := p.ImportPath
2331         if p.Internal.CmdlineFiles {
2332                 pkgPath = "command-line-arguments"
2333         }
2334         info := &debug.BuildInfo{
2335                 Path: pkgPath,
2336                 Main: main,
2337                 Deps: deps,
2338         }
2339         appendSetting := func(key, value string) {
2340                 value = strings.ReplaceAll(value, "\n", " ") // make value safe
2341                 info.Settings = append(info.Settings, debug.BuildSetting{Key: key, Value: value})
2342         }
2343
2344         // Add command-line flags relevant to the build.
2345         // This is informational, not an exhaustive list.
2346         // Please keep the list sorted.
2347         if cfg.BuildASan {
2348                 appendSetting("-asan", "true")
2349         }
2350         if BuildAsmflags.present {
2351                 appendSetting("-asmflags", BuildAsmflags.String())
2352         }
2353         buildmode := cfg.BuildBuildmode
2354         if buildmode == "default" {
2355                 if p.Name == "main" {
2356                         buildmode = "exe"
2357                 } else {
2358                         buildmode = "archive"
2359                 }
2360         }
2361         appendSetting("-buildmode", buildmode)
2362         appendSetting("-compiler", cfg.BuildContext.Compiler)
2363         if gccgoflags := BuildGccgoflags.String(); gccgoflags != "" && cfg.BuildContext.Compiler == "gccgo" {
2364                 appendSetting("-gccgoflags", gccgoflags)
2365         }
2366         if gcflags := BuildGcflags.String(); gcflags != "" && cfg.BuildContext.Compiler == "gc" {
2367                 appendSetting("-gcflags", gcflags)
2368         }
2369         if ldflags := BuildLdflags.String(); ldflags != "" {
2370                 // https://go.dev/issue/52372: only include ldflags if -trimpath is not set,
2371                 // since it can include system paths through various linker flags (notably
2372                 // -extar, -extld, and -extldflags).
2373                 //
2374                 // TODO: since we control cmd/link, in theory we can parse ldflags to
2375                 // determine whether they may refer to system paths. If we do that, we can
2376                 // redact only those paths from the recorded -ldflags setting and still
2377                 // record the system-independent parts of the flags.
2378                 if !cfg.BuildTrimpath {
2379                         appendSetting("-ldflags", ldflags)
2380                 }
2381         }
2382         if p.Internal.PGOProfile != "" {
2383                 if cfg.BuildTrimpath {
2384                         appendSetting("-pgo", filepath.Base(p.Internal.PGOProfile))
2385                 } else {
2386                         appendSetting("-pgo", p.Internal.PGOProfile)
2387                 }
2388         }
2389         if cfg.BuildMSan {
2390                 appendSetting("-msan", "true")
2391         }
2392         if cfg.BuildRace {
2393                 appendSetting("-race", "true")
2394         }
2395         if tags := cfg.BuildContext.BuildTags; len(tags) > 0 {
2396                 appendSetting("-tags", strings.Join(tags, ","))
2397         }
2398         if cfg.BuildTrimpath {
2399                 appendSetting("-trimpath", "true")
2400         }
2401         if p.DefaultGODEBUG != "" {
2402                 appendSetting("DefaultGODEBUG", p.DefaultGODEBUG)
2403         }
2404         cgo := "0"
2405         if cfg.BuildContext.CgoEnabled {
2406                 cgo = "1"
2407         }
2408         appendSetting("CGO_ENABLED", cgo)
2409         // https://go.dev/issue/52372: only include CGO flags if -trimpath is not set.
2410         // (If -trimpath is set, it is possible that these flags include system paths.)
2411         // If cgo is involved, reproducibility is already pretty well ruined anyway,
2412         // given that we aren't stamping header or library versions.
2413         //
2414         // TODO(bcmills): perhaps we could at least parse the flags and stamp the
2415         // subset of flags that are known not to be paths?
2416         if cfg.BuildContext.CgoEnabled && !cfg.BuildTrimpath {
2417                 for _, name := range []string{"CGO_CFLAGS", "CGO_CPPFLAGS", "CGO_CXXFLAGS", "CGO_LDFLAGS"} {
2418                         appendSetting(name, cfg.Getenv(name))
2419                 }
2420         }
2421         appendSetting("GOARCH", cfg.BuildContext.GOARCH)
2422         if cfg.RawGOEXPERIMENT != "" {
2423                 appendSetting("GOEXPERIMENT", cfg.RawGOEXPERIMENT)
2424         }
2425         appendSetting("GOOS", cfg.BuildContext.GOOS)
2426         if key, val := cfg.GetArchEnv(); key != "" && val != "" {
2427                 appendSetting(key, val)
2428         }
2429
2430         // Add VCS status if all conditions are true:
2431         //
2432         // - -buildvcs is enabled.
2433         // - p is a non-test contained within a main module (there may be multiple
2434         //   main modules in a workspace, but local replacements don't count).
2435         // - Both the current directory and p's module's root directory are contained
2436         //   in the same local repository.
2437         // - We know the VCS commands needed to get the status.
2438         setVCSError := func(err error) {
2439                 setPkgErrorf("error obtaining VCS status: %v\n\tUse -buildvcs=false to disable VCS stamping.", err)
2440         }
2441
2442         var repoDir string
2443         var vcsCmd *vcs.Cmd
2444         var err error
2445         const allowNesting = true
2446
2447         wantVCS := false
2448         switch cfg.BuildBuildvcs {
2449         case "true":
2450                 wantVCS = true // Include VCS metadata even for tests if requested explicitly; see https://go.dev/issue/52648.
2451         case "auto":
2452                 wantVCS = autoVCS && !p.IsTestOnly()
2453         case "false":
2454         default:
2455                 panic(fmt.Sprintf("unexpected value for cfg.BuildBuildvcs: %q", cfg.BuildBuildvcs))
2456         }
2457
2458         if wantVCS && p.Module != nil && p.Module.Version == "" && !p.Standard {
2459                 if p.Module.Path == "bootstrap" && cfg.GOROOT == os.Getenv("GOROOT_BOOTSTRAP") {
2460                         // During bootstrapping, the bootstrap toolchain is built in module
2461                         // "bootstrap" (instead of "std"), with GOROOT set to GOROOT_BOOTSTRAP
2462                         // (so the bootstrap toolchain packages don't even appear to be in GOROOT).
2463                         goto omitVCS
2464                 }
2465                 repoDir, vcsCmd, err = vcs.FromDir(base.Cwd(), "", allowNesting)
2466                 if err != nil && !errors.Is(err, os.ErrNotExist) {
2467                         setVCSError(err)
2468                         return
2469                 }
2470                 if !str.HasFilePathPrefix(p.Module.Dir, repoDir) &&
2471                         !str.HasFilePathPrefix(repoDir, p.Module.Dir) {
2472                         // The module containing the main package does not overlap with the
2473                         // repository containing the working directory. Don't include VCS info.
2474                         // If the repo contains the module or vice versa, but they are not
2475                         // the same directory, it's likely an error (see below).
2476                         goto omitVCS
2477                 }
2478                 if cfg.BuildBuildvcs == "auto" && vcsCmd != nil && vcsCmd.Cmd != "" {
2479                         if _, err := exec.LookPath(vcsCmd.Cmd); err != nil {
2480                                 // We fould a repository, but the required VCS tool is not present.
2481                                 // "-buildvcs=auto" means that we should silently drop the VCS metadata.
2482                                 goto omitVCS
2483                         }
2484                 }
2485         }
2486         if repoDir != "" && vcsCmd.Status != nil {
2487                 // Check that the current directory, package, and module are in the same
2488                 // repository. vcs.FromDir allows nested Git repositories, but nesting
2489                 // is not allowed for other VCS tools. The current directory may be outside
2490                 // p.Module.Dir when a workspace is used.
2491                 pkgRepoDir, _, err := vcs.FromDir(p.Dir, "", allowNesting)
2492                 if err != nil {
2493                         setVCSError(err)
2494                         return
2495                 }
2496                 if pkgRepoDir != repoDir {
2497                         if cfg.BuildBuildvcs != "auto" {
2498                                 setVCSError(fmt.Errorf("main package is in repository %q but current directory is in repository %q", pkgRepoDir, repoDir))
2499                                 return
2500                         }
2501                         goto omitVCS
2502                 }
2503                 modRepoDir, _, err := vcs.FromDir(p.Module.Dir, "", allowNesting)
2504                 if err != nil {
2505                         setVCSError(err)
2506                         return
2507                 }
2508                 if modRepoDir != repoDir {
2509                         if cfg.BuildBuildvcs != "auto" {
2510                                 setVCSError(fmt.Errorf("main module is in repository %q but current directory is in repository %q", modRepoDir, repoDir))
2511                                 return
2512                         }
2513                         goto omitVCS
2514                 }
2515
2516                 st, err := vcsStatusCache.Do(repoDir, func() (vcs.Status, error) {
2517                         return vcsCmd.Status(vcsCmd, repoDir)
2518                 })
2519                 if err != nil {
2520                         setVCSError(err)
2521                         return
2522                 }
2523
2524                 appendSetting("vcs", vcsCmd.Cmd)
2525                 if st.Revision != "" {
2526                         appendSetting("vcs.revision", st.Revision)
2527                 }
2528                 if !st.CommitTime.IsZero() {
2529                         stamp := st.CommitTime.UTC().Format(time.RFC3339Nano)
2530                         appendSetting("vcs.time", stamp)
2531                 }
2532                 appendSetting("vcs.modified", strconv.FormatBool(st.Uncommitted))
2533         }
2534 omitVCS:
2535
2536         p.Internal.BuildInfo = info.String()
2537 }
2538
2539 // SafeArg reports whether arg is a "safe" command-line argument,
2540 // meaning that when it appears in a command-line, it probably
2541 // doesn't have some special meaning other than its own name.
2542 // Obviously args beginning with - are not safe (they look like flags).
2543 // Less obviously, args beginning with @ are not safe (they look like
2544 // GNU binutils flagfile specifiers, sometimes called "response files").
2545 // To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII.
2546 // We accept leading . _ and / as likely in file system paths.
2547 // There is a copy of this function in cmd/compile/internal/gc/noder.go.
2548 func SafeArg(name string) bool {
2549         if name == "" {
2550                 return false
2551         }
2552         c := name[0]
2553         return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
2554 }
2555
2556 // LinkerDeps returns the list of linker-induced dependencies for main package p.
2557 func LinkerDeps(p *Package) []string {
2558         // Everything links runtime.
2559         deps := []string{"runtime"}
2560
2561         // External linking mode forces an import of runtime/cgo.
2562         if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" {
2563                 deps = append(deps, "runtime/cgo")
2564         }
2565         // On ARM with GOARM=5, it forces an import of math, for soft floating point.
2566         if cfg.Goarch == "arm" {
2567                 deps = append(deps, "math")
2568         }
2569         // Using the race detector forces an import of runtime/race.
2570         if cfg.BuildRace {
2571                 deps = append(deps, "runtime/race")
2572         }
2573         // Using memory sanitizer forces an import of runtime/msan.
2574         if cfg.BuildMSan {
2575                 deps = append(deps, "runtime/msan")
2576         }
2577         // Using address sanitizer forces an import of runtime/asan.
2578         if cfg.BuildASan {
2579                 deps = append(deps, "runtime/asan")
2580         }
2581         // Building for coverage forces an import of runtime/coverage.
2582         if cfg.BuildCover && cfg.Experiment.CoverageRedesign {
2583                 deps = append(deps, "runtime/coverage")
2584         }
2585
2586         return deps
2587 }
2588
2589 // externalLinkingForced reports whether external linking is being
2590 // forced even for programs that do not use cgo.
2591 func externalLinkingForced(p *Package) bool {
2592         if !cfg.BuildContext.CgoEnabled {
2593                 return false
2594         }
2595
2596         // Some targets must use external linking even inside GOROOT.
2597         if platform.MustLinkExternal(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH, false) {
2598                 return true
2599         }
2600
2601         // Some build modes always require external linking.
2602         switch cfg.BuildBuildmode {
2603         case "c-shared", "plugin":
2604                 return true
2605         }
2606
2607         // Using -linkshared always requires external linking.
2608         if cfg.BuildLinkshared {
2609                 return true
2610         }
2611
2612         // Decide whether we are building a PIE,
2613         // bearing in mind that some systems default to PIE.
2614         isPIE := false
2615         if cfg.BuildBuildmode == "pie" {
2616                 isPIE = true
2617         } else if cfg.BuildBuildmode == "default" && platform.DefaultPIE(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH, cfg.BuildRace) {
2618                 isPIE = true
2619         }
2620         // If we are building a PIE, and we are on a system
2621         // that does not support PIE with internal linking mode,
2622         // then we must use external linking.
2623         if isPIE && !platform.InternalLinkPIESupported(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH) {
2624                 return true
2625         }
2626
2627         // Using -ldflags=-linkmode=external forces external linking.
2628         // If there are multiple -linkmode options, the last one wins.
2629         linkmodeExternal := false
2630         if p != nil {
2631                 ldflags := BuildLdflags.For(p)
2632                 for i := len(ldflags) - 1; i >= 0; i-- {
2633                         a := ldflags[i]
2634                         if a == "-linkmode=external" ||
2635                                 a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" {
2636                                 linkmodeExternal = true
2637                                 break
2638                         } else if a == "-linkmode=internal" ||
2639                                 a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "internal" {
2640                                 break
2641                         }
2642                 }
2643         }
2644         return linkmodeExternal
2645 }
2646
2647 // mkAbs rewrites list, which must be paths relative to p.Dir,
2648 // into a sorted list of absolute paths. It edits list in place but for
2649 // convenience also returns list back to its caller.
2650 func (p *Package) mkAbs(list []string) []string {
2651         for i, f := range list {
2652                 list[i] = filepath.Join(p.Dir, f)
2653         }
2654         sort.Strings(list)
2655         return list
2656 }
2657
2658 // InternalGoFiles returns the list of Go files being built for the package,
2659 // using absolute paths.
2660 func (p *Package) InternalGoFiles() []string {
2661         return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles))
2662 }
2663
2664 // InternalXGoFiles returns the list of Go files being built for the XTest package,
2665 // using absolute paths.
2666 func (p *Package) InternalXGoFiles() []string {
2667         return p.mkAbs(p.XTestGoFiles)
2668 }
2669
2670 // InternalAllGoFiles returns the list of all Go files possibly relevant for the package,
2671 // using absolute paths. "Possibly relevant" means that files are not excluded
2672 // due to build tags, but files with names beginning with . or _ are still excluded.
2673 func (p *Package) InternalAllGoFiles() []string {
2674         return p.mkAbs(str.StringList(p.IgnoredGoFiles, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
2675 }
2676
2677 // UsesSwig reports whether the package needs to run SWIG.
2678 func (p *Package) UsesSwig() bool {
2679         return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0
2680 }
2681
2682 // UsesCgo reports whether the package needs to run cgo
2683 func (p *Package) UsesCgo() bool {
2684         return len(p.CgoFiles) > 0
2685 }
2686
2687 // PackageList returns the list of packages in the dag rooted at roots
2688 // as visited in a depth-first post-order traversal.
2689 func PackageList(roots []*Package) []*Package {
2690         seen := map[*Package]bool{}
2691         all := []*Package{}
2692         var walk func(*Package)
2693         walk = func(p *Package) {
2694                 if seen[p] {
2695                         return
2696                 }
2697                 seen[p] = true
2698                 for _, p1 := range p.Internal.Imports {
2699                         walk(p1)
2700                 }
2701                 all = append(all, p)
2702         }
2703         for _, root := range roots {
2704                 walk(root)
2705         }
2706         return all
2707 }
2708
2709 // TestPackageList returns the list of packages in the dag rooted at roots
2710 // as visited in a depth-first post-order traversal, including the test
2711 // imports of the roots. This ignores errors in test packages.
2712 func TestPackageList(ctx context.Context, opts PackageOpts, roots []*Package) []*Package {
2713         seen := map[*Package]bool{}
2714         all := []*Package{}
2715         var walk func(*Package)
2716         walk = func(p *Package) {
2717                 if seen[p] {
2718                         return
2719                 }
2720                 seen[p] = true
2721                 for _, p1 := range p.Internal.Imports {
2722                         walk(p1)
2723                 }
2724                 all = append(all, p)
2725         }
2726         walkTest := func(root *Package, path string) {
2727                 var stk ImportStack
2728                 p1, err := LoadImport(ctx, opts, path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport)
2729                 if err != nil && root.Error == nil {
2730                         // Assign error importing the package to the importer.
2731                         root.Error = err
2732                         root.Incomplete = true
2733                 }
2734                 if p1.Error == nil {
2735                         walk(p1)
2736                 }
2737         }
2738         for _, root := range roots {
2739                 walk(root)
2740                 for _, path := range root.TestImports {
2741                         walkTest(root, path)
2742                 }
2743                 for _, path := range root.XTestImports {
2744                         walkTest(root, path)
2745                 }
2746         }
2747         return all
2748 }
2749
2750 // LoadImportWithFlags loads the package with the given import path and
2751 // sets tool flags on that package. This function is useful loading implicit
2752 // dependencies (like sync/atomic for coverage).
2753 // TODO(jayconrod): delete this function and set flags automatically
2754 // in LoadImport instead.
2755 func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) (*Package, *PackageError) {
2756         p, err := LoadImport(context.TODO(), PackageOpts{}, path, srcDir, parent, stk, importPos, mode)
2757         setToolFlags(p)
2758         return p, err
2759 }
2760
2761 // LoadPackageWithFlags is the same as LoadImportWithFlags but without a parent.
2762 // It's then guaranteed to not return an error
2763 func LoadPackageWithFlags(path, srcDir string, stk *ImportStack, importPos []token.Position, mode int) *Package {
2764         p := LoadPackage(context.TODO(), PackageOpts{}, path, srcDir, stk, importPos, mode)
2765         setToolFlags(p)
2766         return p
2767 }
2768
2769 // PackageOpts control the behavior of PackagesAndErrors and other package
2770 // loading functions.
2771 type PackageOpts struct {
2772         // IgnoreImports controls whether we ignore explicit and implicit imports
2773         // when loading packages.  Implicit imports are added when supporting Cgo
2774         // or SWIG and when linking main packages.
2775         IgnoreImports bool
2776
2777         // ModResolveTests indicates whether calls to the module loader should also
2778         // resolve test dependencies of the requested packages.
2779         //
2780         // If ModResolveTests is true, then the module loader needs to resolve test
2781         // dependencies at the same time as packages; otherwise, the test dependencies
2782         // of those packages could be missing, and resolving those missing dependencies
2783         // could change the selected versions of modules that provide other packages.
2784         ModResolveTests bool
2785
2786         // MainOnly is true if the caller only wants to load main packages.
2787         // For a literal argument matching a non-main package, a stub may be returned
2788         // with an error. For a non-literal argument (with "..."), non-main packages
2789         // are not be matched, and their dependencies may not be loaded. A warning
2790         // may be printed for non-literal arguments that match no main packages.
2791         MainOnly bool
2792
2793         // AutoVCS controls whether we also load version-control metadata for main packages
2794         // when -buildvcs=auto (the default).
2795         AutoVCS bool
2796
2797         // SuppressBuildInfo is true if the caller does not need p.Stale, p.StaleReason, or p.Internal.BuildInfo
2798         // to be populated on the package.
2799         SuppressBuildInfo bool
2800
2801         // SuppressEmbedFiles is true if the caller does not need any embed files to be populated on the
2802         // package.
2803         SuppressEmbedFiles bool
2804 }
2805
2806 // PackagesAndErrors returns the packages named by the command line arguments
2807 // 'patterns'. If a named package cannot be loaded, PackagesAndErrors returns
2808 // a *Package with the Error field describing the failure. If errors are found
2809 // loading imported packages, the DepsErrors field is set. The Incomplete field
2810 // may be set as well.
2811 //
2812 // To obtain a flat list of packages, use PackageList.
2813 // To report errors loading packages, use ReportPackageErrors.
2814 func PackagesAndErrors(ctx context.Context, opts PackageOpts, patterns []string) []*Package {
2815         ctx, span := trace.StartSpan(ctx, "load.PackagesAndErrors")
2816         defer span.Done()
2817
2818         for _, p := range patterns {
2819                 // Listing is only supported with all patterns referring to either:
2820                 // - Files that are part of the same directory.
2821                 // - Explicit package paths or patterns.
2822                 if strings.HasSuffix(p, ".go") {
2823                         // We need to test whether the path is an actual Go file and not a
2824                         // package path or pattern ending in '.go' (see golang.org/issue/34653).
2825                         if fi, err := fsys.Stat(p); err == nil && !fi.IsDir() {
2826                                 pkgs := []*Package{GoFilesPackage(ctx, opts, patterns)}
2827                                 setPGOProfilePath(pkgs)
2828                                 return pkgs
2829                         }
2830                 }
2831         }
2832
2833         var matches []*search.Match
2834         if modload.Init(); cfg.ModulesEnabled {
2835                 modOpts := modload.PackageOpts{
2836                         ResolveMissingImports: true,
2837                         LoadTests:             opts.ModResolveTests,
2838                         SilencePackageErrors:  true,
2839                 }
2840                 matches, _ = modload.LoadPackages(ctx, modOpts, patterns...)
2841         } else {
2842                 noModRoots := []string{}
2843                 matches = search.ImportPaths(patterns, noModRoots)
2844         }
2845
2846         var (
2847                 pkgs    []*Package
2848                 stk     ImportStack
2849                 seenPkg = make(map[*Package]bool)
2850         )
2851
2852         pre := newPreload()
2853         defer pre.flush()
2854         pre.preloadMatches(ctx, opts, matches)
2855
2856         for _, m := range matches {
2857                 for _, pkg := range m.Pkgs {
2858                         if pkg == "" {
2859                                 panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern()))
2860                         }
2861                         mode := cmdlinePkg
2862                         if m.IsLiteral() {
2863                                 // Note: do not set = m.IsLiteral unconditionally
2864                                 // because maybe we'll see p matching both
2865                                 // a literal and also a non-literal pattern.
2866                                 mode |= cmdlinePkgLiteral
2867                         }
2868                         p, perr := loadImport(ctx, opts, pre, pkg, base.Cwd(), nil, &stk, nil, mode)
2869                         if perr != nil {
2870                                 base.Fatalf("internal error: loadImport of %q with nil parent returned an error", pkg)
2871                         }
2872                         p.Match = append(p.Match, m.Pattern())
2873                         if seenPkg[p] {
2874                                 continue
2875                         }
2876                         seenPkg[p] = true
2877                         pkgs = append(pkgs, p)
2878                 }
2879
2880                 if len(m.Errs) > 0 {
2881                         // In addition to any packages that were actually resolved from the
2882                         // pattern, there was some error in resolving the pattern itself.
2883                         // Report it as a synthetic package.
2884                         p := new(Package)
2885                         p.ImportPath = m.Pattern()
2886                         // Pass an empty ImportStack and nil importPos: the error arose from a pattern, not an import.
2887                         var stk ImportStack
2888                         var importPos []token.Position
2889                         p.setLoadPackageDataError(m.Errs[0], m.Pattern(), &stk, importPos)
2890                         p.Incomplete = true
2891                         p.Match = append(p.Match, m.Pattern())
2892                         p.Internal.CmdlinePkg = true
2893                         if m.IsLiteral() {
2894                                 p.Internal.CmdlinePkgLiteral = true
2895                         }
2896                         pkgs = append(pkgs, p)
2897                 }
2898         }
2899
2900         if opts.MainOnly {
2901                 pkgs = mainPackagesOnly(pkgs, matches)
2902         }
2903
2904         // Now that CmdlinePkg is set correctly,
2905         // compute the effective flags for all loaded packages
2906         // (not just the ones matching the patterns but also
2907         // their dependencies).
2908         setToolFlags(pkgs...)
2909
2910         setPGOProfilePath(pkgs)
2911
2912         return pkgs
2913 }
2914
2915 // setPGOProfilePath sets the PGO profile path for pkgs.
2916 // In -pgo=auto mode, it finds the default PGO profile.
2917 func setPGOProfilePath(pkgs []*Package) {
2918         switch cfg.BuildPGO {
2919         case "off":
2920                 return
2921
2922         case "auto":
2923                 // Locate PGO profiles from the main packages, and
2924                 // attach the profile to the main package and its
2925                 // dependencies.
2926                 // If we're builing multiple main packages, they may
2927                 // have different profiles. We may need to split (unshare)
2928                 // the dependency graph so they can attach different
2929                 // profiles.
2930                 for _, p := range pkgs {
2931                         if p.Name != "main" {
2932                                 continue
2933                         }
2934                         pmain := p
2935                         file := filepath.Join(pmain.Dir, "default.pgo")
2936                         if _, err := os.Stat(file); err != nil {
2937                                 continue // no profile
2938                         }
2939
2940                         copied := make(map[*Package]*Package)
2941                         var split func(p *Package) *Package
2942                         split = func(p *Package) *Package {
2943                                 if len(pkgs) > 1 && p != pmain {
2944                                         // Make a copy, then attach profile.
2945                                         // No need to copy if there is only one root package (we can
2946                                         // attach profile directly in-place).
2947                                         // Also no need to copy the main package.
2948                                         if p1 := copied[p]; p1 != nil {
2949                                                 return p1
2950                                         }
2951                                         if p.Internal.PGOProfile != "" {
2952                                                 panic("setPGOProfilePath: already have profile")
2953                                         }
2954                                         p1 := new(Package)
2955                                         *p1 = *p
2956                                         // Unalias the Internal.Imports slice, which is we're going to
2957                                         // modify. We don't copy other slices as we don't change them.
2958                                         p1.Internal.Imports = slices.Clone(p.Internal.Imports)
2959                                         copied[p] = p1
2960                                         p = p1
2961                                         p.Internal.ForMain = pmain.ImportPath
2962                                 }
2963                                 p.Internal.PGOProfile = file
2964                                 // Recurse to dependencies.
2965                                 for i, pp := range p.Internal.Imports {
2966                                         p.Internal.Imports[i] = split(pp)
2967                                 }
2968                                 return p
2969                         }
2970
2971                         // Replace the package and imports with the PGO version.
2972                         split(pmain)
2973                 }
2974
2975         default:
2976                 // Profile specified from the command line.
2977                 // Make it absolute path, as the compiler runs on various directories.
2978                 file, err := filepath.Abs(cfg.BuildPGO)
2979                 if err != nil {
2980                         base.Fatalf("fail to get absolute path of PGO file %s: %v", cfg.BuildPGO, err)
2981                 }
2982
2983                 for _, p := range PackageList(pkgs) {
2984                         p.Internal.PGOProfile = file
2985                 }
2986         }
2987 }
2988
2989 // CheckPackageErrors prints errors encountered loading pkgs and their
2990 // dependencies, then exits with a non-zero status if any errors were found.
2991 func CheckPackageErrors(pkgs []*Package) {
2992         var anyIncomplete bool
2993         for _, pkg := range pkgs {
2994                 if pkg.Incomplete {
2995                         anyIncomplete = true
2996                 }
2997         }
2998         if anyIncomplete {
2999                 all := PackageList(pkgs)
3000                 for _, p := range all {
3001                         if p.Error != nil {
3002                                 base.Errorf("%v", p.Error)
3003                         }
3004                 }
3005         }
3006         base.ExitIfErrors()
3007
3008         // Check for duplicate loads of the same package.
3009         // That should be impossible, but if it does happen then
3010         // we end up trying to build the same package twice,
3011         // usually in parallel overwriting the same files,
3012         // which doesn't work very well.
3013         seen := map[string]bool{}
3014         reported := map[string]bool{}
3015         for _, pkg := range PackageList(pkgs) {
3016                 // -pgo=auto with multiple main packages can cause a package being
3017                 // built multiple times (with different profiles).
3018                 // We check that package import path + profile path is unique.
3019                 key := pkg.ImportPath
3020                 if pkg.Internal.PGOProfile != "" {
3021                         key += " pgo:" + pkg.Internal.PGOProfile
3022                 }
3023                 if seen[key] && !reported[key] {
3024                         reported[key] = true
3025                         base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath)
3026                 }
3027                 seen[key] = true
3028         }
3029         base.ExitIfErrors()
3030 }
3031
3032 // mainPackagesOnly filters out non-main packages matched only by arguments
3033 // containing "..." and returns the remaining main packages.
3034 //
3035 // Packages with missing, invalid, or ambiguous names may be treated as
3036 // possibly-main packages.
3037 //
3038 // mainPackagesOnly sets a non-main package's Error field and returns it if it
3039 // is named by a literal argument.
3040 //
3041 // mainPackagesOnly prints warnings for non-literal arguments that only match
3042 // non-main packages.
3043 func mainPackagesOnly(pkgs []*Package, matches []*search.Match) []*Package {
3044         treatAsMain := map[string]bool{}
3045         for _, m := range matches {
3046                 if m.IsLiteral() {
3047                         for _, path := range m.Pkgs {
3048                                 treatAsMain[path] = true
3049                         }
3050                 }
3051         }
3052
3053         var mains []*Package
3054         for _, pkg := range pkgs {
3055                 if pkg.Name == "main" || (pkg.Name == "" && pkg.Error != nil) {
3056                         treatAsMain[pkg.ImportPath] = true
3057                         mains = append(mains, pkg)
3058                         continue
3059                 }
3060
3061                 if len(pkg.InvalidGoFiles) > 0 { // TODO(#45999): && pkg.Name == "", but currently go/build sets pkg.Name arbitrarily if it is ambiguous.
3062                         // The package has (or may have) conflicting names, and we can't easily
3063                         // tell whether one of them is "main". So assume that it could be, and
3064                         // report an error for the package.
3065                         treatAsMain[pkg.ImportPath] = true
3066                 }
3067                 if treatAsMain[pkg.ImportPath] {
3068                         if pkg.Error == nil {
3069                                 pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
3070                                 pkg.Incomplete = true
3071                         }
3072                         mains = append(mains, pkg)
3073                 }
3074         }
3075
3076         for _, m := range matches {
3077                 if m.IsLiteral() || len(m.Pkgs) == 0 {
3078                         continue
3079                 }
3080                 foundMain := false
3081                 for _, path := range m.Pkgs {
3082                         if treatAsMain[path] {
3083                                 foundMain = true
3084                                 break
3085                         }
3086                 }
3087                 if !foundMain {
3088                         fmt.Fprintf(os.Stderr, "go: warning: %q matched only non-main packages\n", m.Pattern())
3089                 }
3090         }
3091
3092         return mains
3093 }
3094
3095 type mainPackageError struct {
3096         importPath string
3097 }
3098
3099 func (e *mainPackageError) Error() string {
3100         return fmt.Sprintf("package %s is not a main package", e.importPath)
3101 }
3102
3103 func (e *mainPackageError) ImportPath() string {
3104         return e.importPath
3105 }
3106
3107 func setToolFlags(pkgs ...*Package) {
3108         for _, p := range PackageList(pkgs) {
3109                 p.Internal.Asmflags = BuildAsmflags.For(p)
3110                 p.Internal.Gcflags = BuildGcflags.For(p)
3111                 p.Internal.Ldflags = BuildLdflags.For(p)
3112                 p.Internal.Gccgoflags = BuildGccgoflags.For(p)
3113         }
3114 }
3115
3116 // GoFilesPackage creates a package for building a collection of Go files
3117 // (typically named on the command line). The target is named p.a for
3118 // package p or named after the first Go file for package main.
3119 func GoFilesPackage(ctx context.Context, opts PackageOpts, gofiles []string) *Package {
3120         modload.Init()
3121
3122         for _, f := range gofiles {
3123                 if !strings.HasSuffix(f, ".go") {
3124                         pkg := new(Package)
3125                         pkg.Internal.Local = true
3126                         pkg.Internal.CmdlineFiles = true
3127                         pkg.Name = f
3128                         pkg.Error = &PackageError{
3129                                 Err: fmt.Errorf("named files must be .go files: %s", pkg.Name),
3130                         }
3131                         pkg.Incomplete = true
3132                         return pkg
3133                 }
3134         }
3135
3136         var stk ImportStack
3137         ctxt := cfg.BuildContext
3138         ctxt.UseAllFiles = true
3139
3140         // Synthesize fake "directory" that only shows the named files,
3141         // to make it look like this is a standard package or
3142         // command directory. So that local imports resolve
3143         // consistently, the files must all be in the same directory.
3144         var dirent []fs.FileInfo
3145         var dir string
3146         for _, file := range gofiles {
3147                 fi, err := fsys.Stat(file)
3148                 if err != nil {
3149                         base.Fatalf("%s", err)
3150                 }
3151                 if fi.IsDir() {
3152                         base.Fatalf("%s is a directory, should be a Go file", file)
3153                 }
3154                 dir1 := filepath.Dir(file)
3155                 if dir == "" {
3156                         dir = dir1
3157                 } else if dir != dir1 {
3158                         base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
3159                 }
3160                 dirent = append(dirent, fi)
3161         }
3162         ctxt.ReadDir = func(string) ([]fs.FileInfo, error) { return dirent, nil }
3163
3164         if cfg.ModulesEnabled {
3165                 modload.ImportFromFiles(ctx, gofiles)
3166         }
3167
3168         var err error
3169         if dir == "" {
3170                 dir = base.Cwd()
3171         }
3172         dir, err = filepath.Abs(dir)
3173         if err != nil {
3174                 base.Fatalf("%s", err)
3175         }
3176
3177         bp, err := ctxt.ImportDir(dir, 0)
3178         pkg := new(Package)
3179         pkg.Internal.Local = true
3180         pkg.Internal.CmdlineFiles = true
3181         pkg.load(ctx, opts, "command-line-arguments", &stk, nil, bp, err)
3182         if !cfg.ModulesEnabled {
3183                 pkg.Internal.LocalPrefix = dirToImportPath(dir)
3184         }
3185         pkg.ImportPath = "command-line-arguments"
3186         pkg.Target = ""
3187         pkg.Match = gofiles
3188
3189         if pkg.Name == "main" {
3190                 exe := pkg.DefaultExecName() + cfg.ExeSuffix
3191
3192                 if cfg.GOBIN != "" {
3193                         pkg.Target = filepath.Join(cfg.GOBIN, exe)
3194                 } else if cfg.ModulesEnabled {
3195                         pkg.Target = filepath.Join(modload.BinDir(), exe)
3196                 }
3197         }
3198
3199         if opts.MainOnly && pkg.Name != "main" && pkg.Error == nil {
3200                 pkg.Error = &PackageError{Err: &mainPackageError{importPath: pkg.ImportPath}}
3201                 pkg.Incomplete = true
3202         }
3203         setToolFlags(pkg)
3204
3205         return pkg
3206 }
3207
3208 // PackagesAndErrorsOutsideModule is like PackagesAndErrors but runs in
3209 // module-aware mode and ignores the go.mod file in the current directory or any
3210 // parent directory, if there is one. This is used in the implementation of 'go
3211 // install pkg@version' and other commands that support similar forms.
3212 //
3213 // modload.ForceUseModules must be true, and modload.RootMode must be NoRoot
3214 // before calling this function.
3215 //
3216 // PackagesAndErrorsOutsideModule imposes several constraints to avoid
3217 // ambiguity. All arguments must have the same version suffix (not just a suffix
3218 // that resolves to the same version). They must refer to packages in the same
3219 // module, which must not be std or cmd. That module is not considered the main
3220 // module, but its go.mod file (if it has one) must not contain directives that
3221 // would cause it to be interpreted differently if it were the main module
3222 // (replace, exclude).
3223 func PackagesAndErrorsOutsideModule(ctx context.Context, opts PackageOpts, args []string) ([]*Package, error) {
3224         if !modload.ForceUseModules {
3225                 panic("modload.ForceUseModules must be true")
3226         }
3227         if modload.RootMode != modload.NoRoot {
3228                 panic("modload.RootMode must be NoRoot")
3229         }
3230
3231         // Check that the arguments satisfy syntactic constraints.
3232         var version string
3233         for _, arg := range args {
3234                 if i := strings.Index(arg, "@"); i >= 0 {
3235                         version = arg[i+1:]
3236                         if version == "" {
3237                                 return nil, fmt.Errorf("%s: version must not be empty", arg)
3238                         }
3239                         break
3240                 }
3241         }
3242         patterns := make([]string, len(args))
3243         for i, arg := range args {
3244                 p, found := strings.CutSuffix(arg, "@"+version)
3245                 if !found {
3246                         return nil, fmt.Errorf("%s: all arguments must refer to packages in the same module at the same version (@%s)", arg, version)
3247                 }
3248                 switch {
3249                 case build.IsLocalImport(p):
3250                         return nil, fmt.Errorf("%s: argument must be a package path, not a relative path", arg)
3251                 case filepath.IsAbs(p):
3252                         return nil, fmt.Errorf("%s: argument must be a package path, not an absolute path", arg)
3253                 case search.IsMetaPackage(p):
3254                         return nil, fmt.Errorf("%s: argument must be a package path, not a meta-package", arg)
3255                 case pathpkg.Clean(p) != p:
3256                         return nil, fmt.Errorf("%s: argument must be a clean package path", arg)
3257                 case !strings.Contains(p, "...") && search.IsStandardImportPath(p) && modindex.IsStandardPackage(cfg.GOROOT, cfg.BuildContext.Compiler, p):
3258                         return nil, fmt.Errorf("%s: argument must not be a package in the standard library", arg)
3259                 default:
3260                         patterns[i] = p
3261                 }
3262         }
3263
3264         // Query the module providing the first argument, load its go.mod file, and
3265         // check that it doesn't contain directives that would cause it to be
3266         // interpreted differently if it were the main module.
3267         //
3268         // If multiple modules match the first argument, accept the longest match
3269         // (first result). It's possible this module won't provide packages named by
3270         // later arguments, and other modules would. Let's not try to be too
3271         // magical though.
3272         allowed := modload.CheckAllowed
3273         if modload.IsRevisionQuery(version) {
3274                 // Don't check for retractions if a specific revision is requested.
3275                 allowed = nil
3276         }
3277         noneSelected := func(path string) (version string) { return "none" }
3278         qrs, err := modload.QueryPackages(ctx, patterns[0], version, noneSelected, allowed)
3279         if err != nil {
3280                 return nil, fmt.Errorf("%s: %w", args[0], err)
3281         }
3282         rootMod := qrs[0].Mod
3283         data, err := modfetch.GoMod(rootMod.Path, rootMod.Version)
3284         if err != nil {
3285                 return nil, fmt.Errorf("%s: %w", args[0], err)
3286         }
3287         f, err := modfile.Parse("go.mod", data, nil)
3288         if err != nil {
3289                 return nil, fmt.Errorf("%s (in %s): %w", args[0], rootMod, err)
3290         }
3291         directiveFmt := "%s (in %s):\n" +
3292                 "\tThe go.mod file for the module providing named packages contains one or\n" +
3293                 "\tmore %s directives. It must not contain directives that would cause\n" +
3294                 "\tit to be interpreted differently than if it were the main module."
3295         if len(f.Replace) > 0 {
3296                 return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "replace")
3297         }
3298         if len(f.Exclude) > 0 {
3299                 return nil, fmt.Errorf(directiveFmt, args[0], rootMod, "exclude")
3300         }
3301
3302         // Since we are in NoRoot mode, the build list initially contains only
3303         // the dummy command-line-arguments module. Add a requirement on the
3304         // module that provides the packages named on the command line.
3305         if _, err := modload.EditBuildList(ctx, nil, []module.Version{rootMod}); err != nil {
3306                 return nil, fmt.Errorf("%s: %w", args[0], err)
3307         }
3308
3309         // Load packages for all arguments.
3310         pkgs := PackagesAndErrors(ctx, opts, patterns)
3311
3312         // Check that named packages are all provided by the same module.
3313         for _, pkg := range pkgs {
3314                 var pkgErr error
3315                 if pkg.Module == nil {
3316                         // Packages in std, cmd, and their vendored dependencies
3317                         // don't have this field set.
3318                         pkgErr = fmt.Errorf("package %s not provided by module %s", pkg.ImportPath, rootMod)
3319                 } else if pkg.Module.Path != rootMod.Path || pkg.Module.Version != rootMod.Version {
3320                         pkgErr = fmt.Errorf("package %s provided by module %s@%s\n\tAll packages must be provided by the same module (%s).", pkg.ImportPath, pkg.Module.Path, pkg.Module.Version, rootMod)
3321                 }
3322                 if pkgErr != nil && pkg.Error == nil {
3323                         pkg.Error = &PackageError{Err: pkgErr}
3324                         pkg.Incomplete = true
3325                 }
3326         }
3327
3328         matchers := make([]func(string) bool, len(patterns))
3329         for i, p := range patterns {
3330                 if strings.Contains(p, "...") {
3331                         matchers[i] = pkgpattern.MatchPattern(p)
3332                 }
3333         }
3334         return pkgs, nil
3335 }
3336
3337 // EnsureImport ensures that package p imports the named package.
3338 func EnsureImport(p *Package, pkg string) {
3339         for _, d := range p.Internal.Imports {
3340                 if d.Name == pkg {
3341                         return
3342                 }
3343         }
3344
3345         p1, err := LoadImportWithFlags(pkg, p.Dir, p, &ImportStack{}, nil, 0)
3346         if err != nil {
3347                 base.Fatalf("load %s: %v", pkg, err)
3348         }
3349         if p1.Error != nil {
3350                 base.Fatalf("load %s: %v", pkg, p1.Error)
3351         }
3352
3353         p.Internal.Imports = append(p.Internal.Imports, p1)
3354 }
3355
3356 // PrepareForCoverageBuild is a helper invoked for "go install
3357 // -cover", "go run -cover", and "go build -cover" (but not used by
3358 // "go test -cover"). It walks through the packages being built (and
3359 // dependencies) and marks them for coverage instrumentation when
3360 // appropriate, and possibly adding additional deps where needed.
3361 func PrepareForCoverageBuild(pkgs []*Package) {
3362         var match []func(*Package) bool
3363
3364         matchMainModAndCommandLine := func(p *Package) bool {
3365                 // note that p.Standard implies p.Module == nil below.
3366                 return p.Internal.CmdlineFiles || p.Internal.CmdlinePkg || (p.Module != nil && p.Module.Main)
3367         }
3368
3369         if len(cfg.BuildCoverPkg) != 0 {
3370                 // If -coverpkg has been specified, then we instrument only
3371                 // the specific packages selected by the user-specified pattern(s).
3372                 match = make([]func(*Package) bool, len(cfg.BuildCoverPkg))
3373                 for i := range cfg.BuildCoverPkg {
3374                         match[i] = MatchPackage(cfg.BuildCoverPkg[i], base.Cwd())
3375                 }
3376         } else {
3377                 // Without -coverpkg, instrument only packages in the main module
3378                 // (if any), as well as packages/files specifically named on the
3379                 // command line.
3380                 match = []func(*Package) bool{matchMainModAndCommandLine}
3381         }
3382
3383         // Visit the packages being built or installed, along with all of
3384         // their dependencies, and mark them to be instrumented, taking
3385         // into account the matchers we've set up in the sequence above.
3386         SelectCoverPackages(PackageList(pkgs), match, "build")
3387 }
3388
3389 func SelectCoverPackages(roots []*Package, match []func(*Package) bool, op string) []*Package {
3390         var warntag string
3391         var includeMain bool
3392         switch op {
3393         case "build":
3394                 warntag = "built"
3395                 includeMain = true
3396         case "test":
3397                 warntag = "tested"
3398         default:
3399                 panic("internal error, bad mode passed to SelectCoverPackages")
3400         }
3401
3402         covered := []*Package{}
3403         matched := make([]bool, len(match))
3404         for _, p := range roots {
3405                 haveMatch := false
3406                 for i := range match {
3407                         if match[i](p) {
3408                                 matched[i] = true
3409                                 haveMatch = true
3410                         }
3411                 }
3412                 if !haveMatch {
3413                         continue
3414                 }
3415
3416                 // There is nothing to cover in package unsafe; it comes from
3417                 // the compiler.
3418                 if p.ImportPath == "unsafe" {
3419                         continue
3420                 }
3421
3422                 // A package which only has test files can't be imported as a
3423                 // dependency, and at the moment we don't try to instrument it
3424                 // for coverage. There isn't any technical reason why
3425                 // *_test.go files couldn't be instrumented, but it probably
3426                 // doesn't make much sense to lump together coverage metrics
3427                 // (ex: percent stmts covered) of *_test.go files with
3428                 // non-test Go code.
3429                 if len(p.GoFiles)+len(p.CgoFiles) == 0 {
3430                         continue
3431                 }
3432
3433                 // Silently ignore attempts to run coverage on sync/atomic
3434                 // and/or runtime/internal/atomic when using atomic coverage
3435                 // mode. Atomic coverage mode uses sync/atomic, so we can't
3436                 // also do coverage on it.
3437                 if cfg.BuildCoverMode == "atomic" && p.Standard &&
3438                         (p.ImportPath == "sync/atomic" || p.ImportPath == "runtime/internal/atomic") {
3439                         continue
3440                 }
3441
3442                 // If using the race detector, silently ignore attempts to run
3443                 // coverage on the runtime packages. It will cause the race
3444                 // detector to be invoked before it has been initialized. Note
3445                 // the use of "regonly" instead of just ignoring the package
3446                 // completely-- we do this due to the requirements of the
3447                 // package ID numbering scheme. See the comment in
3448                 // $GOROOT/src/internal/coverage/pkid.go dealing with
3449                 // hard-coding of runtime package IDs.
3450                 cmode := cfg.BuildCoverMode
3451                 if cfg.BuildRace && p.Standard && (p.ImportPath == "runtime" || strings.HasPrefix(p.ImportPath, "runtime/internal")) {
3452                         cmode = "regonly"
3453                 }
3454
3455                 // If -coverpkg is in effect and for some reason we don't want
3456                 // coverage data for the main package, make sure that we at
3457                 // least process it for registration hooks.
3458                 if includeMain && p.Name == "main" && !haveMatch {
3459                         haveMatch = true
3460                         cmode = "regonly"
3461                 }
3462
3463                 // Mark package for instrumentation.
3464                 p.Internal.CoverMode = cmode
3465                 covered = append(covered, p)
3466
3467                 // Force import of sync/atomic into package if atomic mode.
3468                 if cfg.BuildCoverMode == "atomic" {
3469                         EnsureImport(p, "sync/atomic")
3470                 }
3471
3472                 // Generate covervars if using legacy coverage design.
3473                 if !cfg.Experiment.CoverageRedesign {
3474                         var coverFiles []string
3475                         coverFiles = append(coverFiles, p.GoFiles...)
3476                         coverFiles = append(coverFiles, p.CgoFiles...)
3477                         p.Internal.CoverVars = DeclareCoverVars(p, coverFiles...)
3478                 }
3479         }
3480
3481         // Warn about -coverpkg arguments that are not actually used.
3482         for i := range cfg.BuildCoverPkg {
3483                 if !matched[i] {
3484                         fmt.Fprintf(os.Stderr, "warning: no packages being %s depend on matches for pattern %s\n", warntag, cfg.BuildCoverPkg[i])
3485                 }
3486         }
3487
3488         return covered
3489 }
3490
3491 // DeclareCoverVars attaches the required cover variables names
3492 // to the files, to be used when annotating the files. This
3493 // function only called when using legacy coverage test/build
3494 // (e.g. GOEXPERIMENT=coverageredesign is off).
3495 func DeclareCoverVars(p *Package, files ...string) map[string]*CoverVar {
3496         coverVars := make(map[string]*CoverVar)
3497         coverIndex := 0
3498         // We create the cover counters as new top-level variables in the package.
3499         // We need to avoid collisions with user variables (GoCover_0 is unlikely but still)
3500         // and more importantly with dot imports of other covered packages,
3501         // so we append 12 hex digits from the SHA-256 of the import path.
3502         // The point is only to avoid accidents, not to defeat users determined to
3503         // break things.
3504         sum := sha256.Sum256([]byte(p.ImportPath))
3505         h := fmt.Sprintf("%x", sum[:6])
3506         for _, file := range files {
3507                 if base.IsTestFile(file) {
3508                         continue
3509                 }
3510                 // For a package that is "local" (imported via ./ import or command line, outside GOPATH),
3511                 // we record the full path to the file name.
3512                 // Otherwise we record the import path, then a forward slash, then the file name.
3513                 // This makes profiles within GOPATH file system-independent.
3514                 // These names appear in the cmd/cover HTML interface.
3515                 var longFile string
3516                 if p.Internal.Local {
3517                         longFile = filepath.Join(p.Dir, file)
3518                 } else {
3519                         longFile = pathpkg.Join(p.ImportPath, file)
3520                 }
3521                 coverVars[file] = &CoverVar{
3522                         File: longFile,
3523                         Var:  fmt.Sprintf("GoCover_%d_%x", coverIndex, h),
3524                 }
3525                 coverIndex++
3526         }
3527         return coverVars
3528 }