github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/src/cmd/go/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 main 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 "go/build" 12 "go/scanner" 13 "go/token" 14 "os" 15 pathpkg "path" 16 "path/filepath" 17 "runtime" 18 "sort" 19 "strings" 20 "time" 21 "unicode" 22 ) 23 24 // A Package describes a single package found in a directory. 25 type Package struct { 26 // Note: These fields are part of the go command's public API. 27 // See list.go. It is okay to add fields, but not to change or 28 // remove existing ones. Keep in sync with list.go 29 Dir string `json:",omitempty"` // directory containing package sources 30 ImportPath string `json:",omitempty"` // import path of package in dir 31 ImportComment string `json:",omitempty"` // path in import comment on package statement 32 Name string `json:",omitempty"` // package name 33 Doc string `json:",omitempty"` // package documentation string 34 Target string `json:",omitempty"` // install path 35 Goroot bool `json:",omitempty"` // is this package found in the Go root? 36 Standard bool `json:",omitempty"` // is this package part of the standard Go library? 37 Stale bool `json:",omitempty"` // would 'go install' do anything for this package? 38 Root string `json:",omitempty"` // Go root or Go path dir containing this package 39 ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory 40 41 // Source files 42 GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) 43 CgoFiles []string `json:",omitempty"` // .go sources files that import "C" 44 IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints 45 CFiles []string `json:",omitempty"` // .c source files 46 CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files 47 MFiles []string `json:",omitempty"` // .m source files 48 HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files 49 SFiles []string `json:",omitempty"` // .s source files 50 SwigFiles []string `json:",omitempty"` // .swig files 51 SwigCXXFiles []string `json:",omitempty"` // .swigcxx files 52 SysoFiles []string `json:",omitempty"` // .syso system object files added to package 53 54 // Cgo directives 55 CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler 56 CgoCPPFLAGS []string `json:",omitempty"` // cgo: flags for C preprocessor 57 CgoCXXFLAGS []string `json:",omitempty"` // cgo: flags for C++ compiler 58 CgoLDFLAGS []string `json:",omitempty"` // cgo: flags for linker 59 CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names 60 61 // Dependency information 62 Imports []string `json:",omitempty"` // import paths used by this package 63 Deps []string `json:",omitempty"` // all (recursively) imported dependencies 64 65 // Error information 66 Incomplete bool `json:",omitempty"` // was there an error loading this package or dependencies? 67 Error *PackageError `json:",omitempty"` // error loading this package (not dependencies) 68 DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies 69 70 // Test information 71 TestGoFiles []string `json:",omitempty"` // _test.go files in package 72 TestImports []string `json:",omitempty"` // imports from TestGoFiles 73 XTestGoFiles []string `json:",omitempty"` // _test.go files outside package 74 XTestImports []string `json:",omitempty"` // imports from XTestGoFiles 75 76 // Unexported fields are not part of the public API. 77 build *build.Package 78 pkgdir string // overrides build.PkgDir 79 imports []*Package 80 deps []*Package 81 gofiles []string // GoFiles+CgoFiles+TestGoFiles+XTestGoFiles files, absolute paths 82 sfiles []string 83 allgofiles []string // gofiles + IgnoredGoFiles, absolute paths 84 target string // installed file for this package (may be executable) 85 fake bool // synthesized package 86 forceBuild bool // this package must be rebuilt 87 forceLibrary bool // this package is a library (even if named "main") 88 cmdline bool // defined by files listed on command line 89 local bool // imported via local path (./ or ../) 90 localPrefix string // interpret ./ and ../ imports relative to this prefix 91 exeName string // desired name for temporary executable 92 coverMode string // preprocess Go source files with the coverage tool in this mode 93 coverVars map[string]*CoverVar // variables created by coverage analysis 94 omitDWARF bool // tell linker not to write DWARF information 95 } 96 97 // CoverVar holds the name of the generated coverage variables targeting the named file. 98 type CoverVar struct { 99 File string // local file name 100 Var string // name of count struct 101 } 102 103 func (p *Package) copyBuild(pp *build.Package) { 104 p.build = pp 105 106 p.Dir = pp.Dir 107 p.ImportPath = pp.ImportPath 108 p.ImportComment = pp.ImportComment 109 p.Name = pp.Name 110 p.Doc = pp.Doc 111 p.Root = pp.Root 112 p.ConflictDir = pp.ConflictDir 113 // TODO? Target 114 p.Goroot = pp.Goroot 115 p.Standard = p.Goroot && p.ImportPath != "" && !strings.Contains(p.ImportPath, ".") 116 p.GoFiles = pp.GoFiles 117 p.CgoFiles = pp.CgoFiles 118 p.IgnoredGoFiles = pp.IgnoredGoFiles 119 p.CFiles = pp.CFiles 120 p.CXXFiles = pp.CXXFiles 121 p.MFiles = pp.MFiles 122 p.HFiles = pp.HFiles 123 p.SFiles = pp.SFiles 124 p.SwigFiles = pp.SwigFiles 125 p.SwigCXXFiles = pp.SwigCXXFiles 126 p.SysoFiles = pp.SysoFiles 127 p.CgoCFLAGS = pp.CgoCFLAGS 128 p.CgoCPPFLAGS = pp.CgoCPPFLAGS 129 p.CgoCXXFLAGS = pp.CgoCXXFLAGS 130 p.CgoLDFLAGS = pp.CgoLDFLAGS 131 p.CgoPkgConfig = pp.CgoPkgConfig 132 p.Imports = pp.Imports 133 p.TestGoFiles = pp.TestGoFiles 134 p.TestImports = pp.TestImports 135 p.XTestGoFiles = pp.XTestGoFiles 136 p.XTestImports = pp.XTestImports 137 } 138 139 // A PackageError describes an error loading information about a package. 140 type PackageError struct { 141 ImportStack []string // shortest path from package named on command line to this one 142 Pos string // position of error 143 Err string // the error itself 144 isImportCycle bool // the error is an import cycle 145 hard bool // whether the error is soft or hard; soft errors are ignored in some places 146 } 147 148 func (p *PackageError) Error() string { 149 // Import cycles deserve special treatment. 150 if p.isImportCycle { 151 return fmt.Sprintf("%s\npackage %s\n", p.Err, strings.Join(p.ImportStack, "\n\timports ")) 152 } 153 if p.Pos != "" { 154 // Omit import stack. The full path to the file where the error 155 // is the most important thing. 156 return p.Pos + ": " + p.Err 157 } 158 if len(p.ImportStack) == 0 { 159 return p.Err 160 } 161 return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err 162 } 163 164 // An importStack is a stack of import paths. 165 type importStack []string 166 167 func (s *importStack) push(p string) { 168 *s = append(*s, p) 169 } 170 171 func (s *importStack) pop() { 172 *s = (*s)[0 : len(*s)-1] 173 } 174 175 func (s *importStack) copy() []string { 176 return append([]string{}, *s...) 177 } 178 179 // shorterThan returns true if sp is shorter than t. 180 // We use this to record the shortest import sequence 181 // that leads to a particular package. 182 func (sp *importStack) shorterThan(t []string) bool { 183 s := *sp 184 if len(s) != len(t) { 185 return len(s) < len(t) 186 } 187 // If they are the same length, settle ties using string ordering. 188 for i := range s { 189 if s[i] != t[i] { 190 return s[i] < t[i] 191 } 192 } 193 return false // they are equal 194 } 195 196 // packageCache is a lookup cache for loadPackage, 197 // so that if we look up a package multiple times 198 // we return the same pointer each time. 199 var packageCache = map[string]*Package{} 200 201 // reloadPackage is like loadPackage but makes sure 202 // not to use the package cache. 203 func reloadPackage(arg string, stk *importStack) *Package { 204 p := packageCache[arg] 205 if p != nil { 206 delete(packageCache, p.Dir) 207 delete(packageCache, p.ImportPath) 208 } 209 return loadPackage(arg, stk) 210 } 211 212 // dirToImportPath returns the pseudo-import path we use for a package 213 // outside the Go path. It begins with _/ and then contains the full path 214 // to the directory. If the package lives in c:\home\gopher\my\pkg then 215 // the pseudo-import path is _/c_/home/gopher/my/pkg. 216 // Using a pseudo-import path like this makes the ./ imports no longer 217 // a special case, so that all the code to deal with ordinary imports works 218 // automatically. 219 func dirToImportPath(dir string) string { 220 return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir))) 221 } 222 223 func makeImportValid(r rune) rune { 224 // Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport. 225 const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" 226 if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { 227 return '_' 228 } 229 return r 230 } 231 232 // loadImport scans the directory named by path, which must be an import path, 233 // but possibly a local import path (an absolute file system path or one beginning 234 // with ./ or ../). A local relative path is interpreted relative to srcDir. 235 // It returns a *Package describing the package found in that directory. 236 func loadImport(path string, srcDir string, stk *importStack, importPos []token.Position) *Package { 237 stk.push(path) 238 defer stk.pop() 239 240 // Determine canonical identifier for this package. 241 // For a local import the identifier is the pseudo-import path 242 // we create from the full directory to the package. 243 // Otherwise it is the usual import path. 244 importPath := path 245 isLocal := build.IsLocalImport(path) 246 if isLocal { 247 importPath = dirToImportPath(filepath.Join(srcDir, path)) 248 } 249 if p := packageCache[importPath]; p != nil { 250 if perr := disallowInternal(srcDir, p, stk); perr != p { 251 return perr 252 } 253 return reusePackage(p, stk) 254 } 255 256 p := new(Package) 257 p.local = isLocal 258 p.ImportPath = importPath 259 packageCache[importPath] = p 260 261 // Load package. 262 // Import always returns bp != nil, even if an error occurs, 263 // in order to return partial information. 264 // 265 // TODO: After Go 1, decide when to pass build.AllowBinary here. 266 // See issue 3268 for mistakes to avoid. 267 bp, err := buildContext.Import(path, srcDir, build.ImportComment) 268 bp.ImportPath = importPath 269 if gobin != "" { 270 bp.BinDir = gobin 271 } 272 if err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path { 273 err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment) 274 } 275 p.load(stk, bp, err) 276 if p.Error != nil && len(importPos) > 0 { 277 pos := importPos[0] 278 pos.Filename = shortPath(pos.Filename) 279 p.Error.Pos = pos.String() 280 } 281 282 if perr := disallowInternal(srcDir, p, stk); perr != p { 283 return perr 284 } 285 286 return p 287 } 288 289 // reusePackage reuses package p to satisfy the import at the top 290 // of the import stack stk. If this use causes an import loop, 291 // reusePackage updates p's error information to record the loop. 292 func reusePackage(p *Package, stk *importStack) *Package { 293 // We use p.imports==nil to detect a package that 294 // is in the midst of its own loadPackage call 295 // (all the recursion below happens before p.imports gets set). 296 if p.imports == nil { 297 if p.Error == nil { 298 p.Error = &PackageError{ 299 ImportStack: stk.copy(), 300 Err: "import cycle not allowed", 301 isImportCycle: true, 302 } 303 } 304 p.Incomplete = true 305 } 306 // Don't rewrite the import stack in the error if we have an import cycle. 307 // If we do, we'll lose the path that describes the cycle. 308 if p.Error != nil && !p.Error.isImportCycle && stk.shorterThan(p.Error.ImportStack) { 309 p.Error.ImportStack = stk.copy() 310 } 311 return p 312 } 313 314 // disallowInternal checks that srcDir is allowed to import p. 315 // If the import is allowed, disallowInternal returns the original package p. 316 // If not, it returns a new package containing just an appropriate error. 317 func disallowInternal(srcDir string, p *Package, stk *importStack) *Package { 318 // golang.org/s/go14internal: 319 // An import of a path containing the element “internal” 320 // is disallowed if the importing code is outside the tree 321 // rooted at the parent of the “internal” directory. 322 // 323 // ... For Go 1.4, we will implement the rule first for $GOROOT, but not $GOPATH. 324 325 // Only applies to $GOROOT. 326 if !p.Standard { 327 return p 328 } 329 330 // The stack includes p.ImportPath. 331 // If that's the only thing on the stack, we started 332 // with a name given on the command line, not an 333 // import. Anything listed on the command line is fine. 334 if len(*stk) == 1 { 335 return p 336 } 337 338 // Check for "internal" element: four cases depending on begin of string and/or end of string. 339 i, ok := findInternal(p.ImportPath) 340 if !ok { 341 return p 342 } 343 344 // Internal is present. 345 // Map import path back to directory corresponding to parent of internal. 346 if i > 0 { 347 i-- // rewind over slash in ".../internal" 348 } 349 parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)] 350 if hasPathPrefix(filepath.ToSlash(srcDir), filepath.ToSlash(parent)) { 351 return p 352 } 353 354 // Internal is present, and srcDir is outside parent's tree. Not allowed. 355 perr := *p 356 perr.Error = &PackageError{ 357 ImportStack: stk.copy(), 358 Err: "use of internal package not allowed", 359 } 360 perr.Incomplete = true 361 return &perr 362 } 363 364 // findInternal looks for the final "internal" path element in the given import path. 365 // If there isn't one, findInternal returns ok=false. 366 // Otherwise, findInternal returns ok=true and the index of the "internal". 367 func findInternal(path string) (index int, ok bool) { 368 // Four cases, depending on internal at start/end of string or not. 369 // The order matters: we must return the index of the final element, 370 // because the final one produces the most restrictive requirement 371 // on the importer. 372 switch { 373 case strings.HasSuffix(path, "/internal"): 374 return len(path) - len("internal"), true 375 case strings.Contains(path, "/internal/"): 376 return strings.LastIndex(path, "/internal/") + 1, true 377 case path == "internal", strings.HasPrefix(path, "internal/"): 378 return 0, true 379 } 380 return 0, false 381 } 382 383 type targetDir int 384 385 const ( 386 toRoot targetDir = iota // to bin dir inside package root (default) 387 toTool // GOROOT/pkg/tool 388 toBin // GOROOT/bin 389 stalePath // the old import path; fail to build 390 ) 391 392 // goTools is a map of Go program import path to install target directory. 393 var goTools = map[string]targetDir{ 394 "cmd/addr2line": toTool, 395 "cmd/api": toTool, 396 "cmd/cgo": toTool, 397 "cmd/fix": toTool, 398 "cmd/link": toTool, 399 "cmd/nm": toTool, 400 "cmd/objdump": toTool, 401 "cmd/pack": toTool, 402 "cmd/pprof": toTool, 403 "cmd/yacc": toTool, 404 "golang.org/x/tools/cmd/cover": toTool, 405 "golang.org/x/tools/cmd/godoc": toBin, 406 "golang.org/x/tools/cmd/vet": toTool, 407 "code.google.com/p/go.tools/cmd/cover": stalePath, 408 "code.google.com/p/go.tools/cmd/godoc": stalePath, 409 "code.google.com/p/go.tools/cmd/vet": stalePath, 410 } 411 412 // expandScanner expands a scanner.List error into all the errors in the list. 413 // The default Error method only shows the first error. 414 func expandScanner(err error) error { 415 // Look for parser errors. 416 if err, ok := err.(scanner.ErrorList); ok { 417 // Prepare error with \n before each message. 418 // When printed in something like context: %v 419 // this will put the leading file positions each on 420 // its own line. It will also show all the errors 421 // instead of just the first, as err.Error does. 422 var buf bytes.Buffer 423 for _, e := range err { 424 e.Pos.Filename = shortPath(e.Pos.Filename) 425 buf.WriteString("\n") 426 buf.WriteString(e.Error()) 427 } 428 return errors.New(buf.String()) 429 } 430 return err 431 } 432 433 var raceExclude = map[string]bool{ 434 "runtime/race": true, 435 "runtime/cgo": true, 436 "cmd/cgo": true, 437 "syscall": true, 438 "errors": true, 439 } 440 441 var cgoExclude = map[string]bool{ 442 "runtime/cgo": true, 443 } 444 445 var cgoSyscallExclude = map[string]bool{ 446 "runtime/cgo": true, 447 "runtime/race": true, 448 } 449 450 // load populates p using information from bp, err, which should 451 // be the result of calling build.Context.Import. 452 func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package { 453 p.copyBuild(bp) 454 455 // The localPrefix is the path we interpret ./ imports relative to. 456 // Synthesized main packages sometimes override this. 457 p.localPrefix = dirToImportPath(p.Dir) 458 459 if err != nil { 460 p.Incomplete = true 461 err = expandScanner(err) 462 p.Error = &PackageError{ 463 ImportStack: stk.copy(), 464 Err: err.Error(), 465 } 466 return p 467 } 468 469 if p.Name == "main" { 470 // Report an error when the old code.google.com/p/go.tools paths are used. 471 if goTools[p.ImportPath] == stalePath { 472 newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1) 473 e := fmt.Sprintf("the %v command has moved; use %v instead.", p.ImportPath, newPath) 474 p.Error = &PackageError{Err: e} 475 return p 476 } 477 _, elem := filepath.Split(p.Dir) 478 full := buildContext.GOOS + "_" + buildContext.GOARCH + "/" + elem 479 if buildContext.GOOS != toolGOOS || buildContext.GOARCH != toolGOARCH { 480 // Install cross-compiled binaries to subdirectories of bin. 481 elem = full 482 } 483 if p.build.BinDir != gobin && goTools[p.ImportPath] == toBin { 484 // Override BinDir. 485 // This is from a subrepo but installs to $GOROOT/bin 486 // by default anyway (like godoc). 487 p.target = filepath.Join(gorootBin, elem) 488 } else if p.build.BinDir != "" { 489 // Install to GOBIN or bin of GOPATH entry. 490 p.target = filepath.Join(p.build.BinDir, elem) 491 } 492 if goTools[p.ImportPath] == toTool { 493 // This is for 'go tool'. 494 // Override all the usual logic and force it into the tool directory. 495 p.target = filepath.Join(gorootPkg, "tool", full) 496 } 497 if p.target != "" && buildContext.GOOS == "windows" { 498 p.target += ".exe" 499 } 500 } else if p.local { 501 // Local import turned into absolute path. 502 // No permanent install target. 503 p.target = "" 504 } else { 505 p.target = p.build.PkgObj 506 } 507 508 importPaths := p.Imports 509 // Packages that use cgo import runtime/cgo implicitly. 510 // Packages that use cgo also import syscall implicitly, 511 // to wrap errno. 512 // Exclude certain packages to avoid circular dependencies. 513 if len(p.CgoFiles) > 0 && (!p.Standard || !cgoExclude[p.ImportPath]) { 514 importPaths = append(importPaths, "runtime/cgo") 515 } 516 if len(p.CgoFiles) > 0 && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) { 517 importPaths = append(importPaths, "syscall") 518 } 519 // Everything depends on runtime, except runtime and unsafe. 520 if !p.Standard || (p.ImportPath != "runtime" && p.ImportPath != "unsafe") { 521 importPaths = append(importPaths, "runtime") 522 // When race detection enabled everything depends on runtime/race. 523 // Exclude certain packages to avoid circular dependencies. 524 if buildRace && (!p.Standard || !raceExclude[p.ImportPath]) { 525 importPaths = append(importPaths, "runtime/race") 526 } 527 } 528 529 // Build list of full paths to all Go files in the package, 530 // for use by commands like go fmt. 531 p.gofiles = stringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles) 532 for i := range p.gofiles { 533 p.gofiles[i] = filepath.Join(p.Dir, p.gofiles[i]) 534 } 535 sort.Strings(p.gofiles) 536 537 p.sfiles = stringList(p.SFiles) 538 for i := range p.sfiles { 539 p.sfiles[i] = filepath.Join(p.Dir, p.sfiles[i]) 540 } 541 sort.Strings(p.sfiles) 542 543 p.allgofiles = stringList(p.IgnoredGoFiles) 544 for i := range p.allgofiles { 545 p.allgofiles[i] = filepath.Join(p.Dir, p.allgofiles[i]) 546 } 547 p.allgofiles = append(p.allgofiles, p.gofiles...) 548 sort.Strings(p.allgofiles) 549 550 // Check for case-insensitive collision of input files. 551 // To avoid problems on case-insensitive files, we reject any package 552 // where two different input files have equal names under a case-insensitive 553 // comparison. 554 f1, f2 := foldDup(stringList( 555 p.GoFiles, 556 p.CgoFiles, 557 p.IgnoredGoFiles, 558 p.CFiles, 559 p.CXXFiles, 560 p.MFiles, 561 p.HFiles, 562 p.SFiles, 563 p.SysoFiles, 564 p.SwigFiles, 565 p.SwigCXXFiles, 566 p.TestGoFiles, 567 p.XTestGoFiles, 568 )) 569 if f1 != "" { 570 p.Error = &PackageError{ 571 ImportStack: stk.copy(), 572 Err: fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2), 573 } 574 return p 575 } 576 577 // Build list of imported packages and full dependency list. 578 imports := make([]*Package, 0, len(p.Imports)) 579 deps := make(map[string]*Package) 580 for i, path := range importPaths { 581 if path == "C" { 582 continue 583 } 584 p1 := loadImport(path, p.Dir, stk, p.build.ImportPos[path]) 585 if p1.local { 586 if !p.local && p.Error == nil { 587 p.Error = &PackageError{ 588 ImportStack: stk.copy(), 589 Err: fmt.Sprintf("local import %q in non-local package", path), 590 } 591 pos := p.build.ImportPos[path] 592 if len(pos) > 0 { 593 p.Error.Pos = pos[0].String() 594 } 595 } 596 path = p1.ImportPath 597 importPaths[i] = path 598 } 599 deps[path] = p1 600 imports = append(imports, p1) 601 for _, dep := range p1.deps { 602 deps[dep.ImportPath] = dep 603 } 604 if p1.Incomplete { 605 p.Incomplete = true 606 } 607 } 608 p.imports = imports 609 610 p.Deps = make([]string, 0, len(deps)) 611 for dep := range deps { 612 p.Deps = append(p.Deps, dep) 613 } 614 sort.Strings(p.Deps) 615 for _, dep := range p.Deps { 616 p1 := deps[dep] 617 if p1 == nil { 618 panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath) 619 } 620 p.deps = append(p.deps, p1) 621 if p1.Error != nil { 622 p.DepsErrors = append(p.DepsErrors, p1.Error) 623 } 624 } 625 626 // unsafe is a fake package. 627 if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") { 628 p.target = "" 629 } 630 p.Target = p.target 631 632 // Check for C code compiled with Plan 9 C compiler. 633 // No longer allowed except in runtime and runtime/cgo, for now. 634 if len(p.CFiles) > 0 && !p.usesCgo() && (!p.Standard || p.ImportPath != "runtime") { 635 p.Error = &PackageError{ 636 ImportStack: stk.copy(), 637 Err: fmt.Sprintf("C source files not allowed when not using cgo: %s", strings.Join(p.CFiles, " ")), 638 } 639 return p 640 } 641 642 // In the absence of errors lower in the dependency tree, 643 // check for case-insensitive collisions of import paths. 644 if len(p.DepsErrors) == 0 { 645 dep1, dep2 := foldDup(p.Deps) 646 if dep1 != "" { 647 p.Error = &PackageError{ 648 ImportStack: stk.copy(), 649 Err: fmt.Sprintf("case-insensitive import collision: %q and %q", dep1, dep2), 650 } 651 return p 652 } 653 } 654 655 return p 656 } 657 658 // usesSwig reports whether the package needs to run SWIG. 659 func (p *Package) usesSwig() bool { 660 return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0 661 } 662 663 // usesCgo reports whether the package needs to run cgo 664 func (p *Package) usesCgo() bool { 665 return len(p.CgoFiles) > 0 666 } 667 668 // packageList returns the list of packages in the dag rooted at roots 669 // as visited in a depth-first post-order traversal. 670 func packageList(roots []*Package) []*Package { 671 seen := map[*Package]bool{} 672 all := []*Package{} 673 var walk func(*Package) 674 walk = func(p *Package) { 675 if seen[p] { 676 return 677 } 678 seen[p] = true 679 for _, p1 := range p.imports { 680 walk(p1) 681 } 682 all = append(all, p) 683 } 684 for _, root := range roots { 685 walk(root) 686 } 687 return all 688 } 689 690 // computeStale computes the Stale flag in the package dag that starts 691 // at the named pkgs (command-line arguments). 692 func computeStale(pkgs ...*Package) { 693 topRoot := map[string]bool{} 694 for _, p := range pkgs { 695 topRoot[p.Root] = true 696 } 697 698 for _, p := range packageList(pkgs) { 699 p.Stale = isStale(p, topRoot) 700 } 701 } 702 703 // The runtime version string takes one of two forms: 704 // "go1.X[.Y]" for Go releases, and "devel +hash" at tip. 705 // Determine whether we are in a released copy by 706 // inspecting the version. 707 var isGoRelease = strings.HasPrefix(runtime.Version(), "go1") 708 709 // isStale reports whether package p needs to be rebuilt. 710 func isStale(p *Package, topRoot map[string]bool) bool { 711 if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") { 712 // fake, builtin package 713 return false 714 } 715 if p.Error != nil { 716 return true 717 } 718 719 // A package without Go sources means we only found 720 // the installed .a file. Since we don't know how to rebuild 721 // it, it can't be stale, even if -a is set. This enables binary-only 722 // distributions of Go packages, although such binaries are 723 // only useful with the specific version of the toolchain that 724 // created them. 725 if len(p.gofiles) == 0 && !p.usesSwig() { 726 return false 727 } 728 729 // If we are running a release copy of Go, do not rebuild the standard packages. 730 // They may not be writable anyway, but they are certainly not changing. 731 // This makes 'go build -a' skip the standard packages when using an official release. 732 // See issue 4106 and issue 8290. 733 pkgBuildA := buildA 734 if p.Standard && isGoRelease { 735 pkgBuildA = false 736 } 737 738 if pkgBuildA || p.target == "" || p.Stale { 739 return true 740 } 741 742 // Package is stale if completely unbuilt. 743 var built time.Time 744 if fi, err := os.Stat(p.target); err == nil { 745 built = fi.ModTime() 746 } 747 if built.IsZero() { 748 return true 749 } 750 751 olderThan := func(file string) bool { 752 fi, err := os.Stat(file) 753 return err != nil || fi.ModTime().After(built) 754 } 755 756 // Package is stale if a dependency is, or if a dependency is newer. 757 for _, p1 := range p.deps { 758 if p1.Stale || p1.target != "" && olderThan(p1.target) { 759 return true 760 } 761 } 762 763 // As a courtesy to developers installing new versions of the compiler 764 // frequently, define that packages are stale if they are 765 // older than the compiler, and commands if they are older than 766 // the linker. This heuristic will not work if the binaries are 767 // back-dated, as some binary distributions may do, but it does handle 768 // a very common case. 769 // See issue 3036. 770 // Assume code in $GOROOT is up to date, since it may not be writeable. 771 // See issue 4106. 772 if p.Root != goroot { 773 if olderThan(buildToolchain.compiler()) { 774 return true 775 } 776 if p.build.IsCommand() && olderThan(buildToolchain.linker()) { 777 return true 778 } 779 } 780 781 // Have installed copy, probably built using current compilers, 782 // and built after its imported packages. The only reason now 783 // that we'd have to rebuild it is if the sources were newer than 784 // the package. If a package p is not in the same tree as any 785 // package named on the command-line, assume it is up-to-date 786 // no matter what the modification times on the source files indicate. 787 // This avoids rebuilding $GOROOT packages when people are 788 // working outside the Go root, and it effectively makes each tree 789 // listed in $GOPATH a separate compilation world. 790 // See issue 3149. 791 if p.Root != "" && !topRoot[p.Root] { 792 return false 793 } 794 795 srcs := stringList(p.GoFiles, p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.SFiles, p.CgoFiles, p.SysoFiles, p.SwigFiles, p.SwigCXXFiles) 796 for _, src := range srcs { 797 if olderThan(filepath.Join(p.Dir, src)) { 798 return true 799 } 800 } 801 802 return false 803 } 804 805 var cwd, _ = os.Getwd() 806 807 var cmdCache = map[string]*Package{} 808 809 // loadPackage is like loadImport but is used for command-line arguments, 810 // not for paths found in import statements. In addition to ordinary import paths, 811 // loadPackage accepts pseudo-paths beginning with cmd/ to denote commands 812 // in the Go command directory, as well as paths to those directories. 813 func loadPackage(arg string, stk *importStack) *Package { 814 if build.IsLocalImport(arg) { 815 dir := arg 816 if !filepath.IsAbs(dir) { 817 if abs, err := filepath.Abs(dir); err == nil { 818 // interpret relative to current directory 819 dir = abs 820 } 821 } 822 if sub, ok := hasSubdir(gorootSrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") { 823 arg = sub 824 } 825 } 826 if strings.HasPrefix(arg, "cmd/") && !strings.Contains(arg[4:], "/") { 827 if p := cmdCache[arg]; p != nil { 828 return p 829 } 830 stk.push(arg) 831 defer stk.pop() 832 833 bp, err := buildContext.ImportDir(filepath.Join(gorootSrc, arg), 0) 834 bp.ImportPath = arg 835 bp.Goroot = true 836 bp.BinDir = gorootBin 837 if gobin != "" { 838 bp.BinDir = gobin 839 } 840 bp.Root = goroot 841 bp.SrcRoot = gorootSrc 842 p := new(Package) 843 cmdCache[arg] = p 844 p.load(stk, bp, err) 845 if p.Error == nil && p.Name != "main" { 846 p.Error = &PackageError{ 847 ImportStack: stk.copy(), 848 Err: fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir), 849 } 850 } 851 return p 852 } 853 854 // Wasn't a command; must be a package. 855 // If it is a local import path but names a standard package, 856 // we treat it as if the user specified the standard package. 857 // This lets you run go test ./ioutil in package io and be 858 // referring to io/ioutil rather than a hypothetical import of 859 // "./ioutil". 860 if build.IsLocalImport(arg) { 861 bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly) 862 if bp.ImportPath != "" && bp.ImportPath != "." { 863 arg = bp.ImportPath 864 } 865 } 866 867 return loadImport(arg, cwd, stk, nil) 868 } 869 870 // packages returns the packages named by the 871 // command line arguments 'args'. If a named package 872 // cannot be loaded at all (for example, if the directory does not exist), 873 // then packages prints an error and does not include that 874 // package in the results. However, if errors occur trying 875 // to load dependencies of a named package, the named 876 // package is still returned, with p.Incomplete = true 877 // and details in p.DepsErrors. 878 func packages(args []string) []*Package { 879 var pkgs []*Package 880 for _, pkg := range packagesAndErrors(args) { 881 if pkg.Error != nil { 882 errorf("can't load package: %s", pkg.Error) 883 continue 884 } 885 pkgs = append(pkgs, pkg) 886 } 887 return pkgs 888 } 889 890 // packagesAndErrors is like 'packages' but returns a 891 // *Package for every argument, even the ones that 892 // cannot be loaded at all. 893 // The packages that fail to load will have p.Error != nil. 894 func packagesAndErrors(args []string) []*Package { 895 if len(args) > 0 && strings.HasSuffix(args[0], ".go") { 896 return []*Package{goFilesPackage(args)} 897 } 898 899 args = importPaths(args) 900 var pkgs []*Package 901 var stk importStack 902 var set = make(map[string]bool) 903 904 for _, arg := range args { 905 if !set[arg] { 906 pkgs = append(pkgs, loadPackage(arg, &stk)) 907 set[arg] = true 908 } 909 } 910 computeStale(pkgs...) 911 912 return pkgs 913 } 914 915 // packagesForBuild is like 'packages' but fails if any of 916 // the packages or their dependencies have errors 917 // (cannot be built). 918 func packagesForBuild(args []string) []*Package { 919 pkgs := packagesAndErrors(args) 920 printed := map[*PackageError]bool{} 921 for _, pkg := range pkgs { 922 if pkg.Error != nil { 923 errorf("can't load package: %s", pkg.Error) 924 } 925 for _, err := range pkg.DepsErrors { 926 // Since these are errors in dependencies, 927 // the same error might show up multiple times, 928 // once in each package that depends on it. 929 // Only print each once. 930 if !printed[err] { 931 printed[err] = true 932 errorf("%s", err) 933 } 934 } 935 } 936 exitIfErrors() 937 return pkgs 938 } 939 940 // hasSubdir reports whether dir is a subdirectory of 941 // (possibly multiple levels below) root. 942 // If so, it sets rel to the path fragment that must be 943 // appended to root to reach dir. 944 func hasSubdir(root, dir string) (rel string, ok bool) { 945 if p, err := filepath.EvalSymlinks(root); err == nil { 946 root = p 947 } 948 if p, err := filepath.EvalSymlinks(dir); err == nil { 949 dir = p 950 } 951 const sep = string(filepath.Separator) 952 root = filepath.Clean(root) 953 if !strings.HasSuffix(root, sep) { 954 root += sep 955 } 956 dir = filepath.Clean(dir) 957 if !strings.HasPrefix(dir, root) { 958 return "", false 959 } 960 return filepath.ToSlash(dir[len(root):]), true 961 }