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