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