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