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