github.com/akaros/go-akaros@v0.0.0-20181004170632-85005d477eab/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 "runtime/parlib": true, 449 } 450 451 // load populates p using information from bp, err, which should 452 // be the result of calling build.Context.Import. 453 func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package { 454 p.copyBuild(bp) 455 456 // The localPrefix is the path we interpret ./ imports relative to. 457 // Synthesized main packages sometimes override this. 458 p.localPrefix = dirToImportPath(p.Dir) 459 460 if err != nil { 461 p.Incomplete = true 462 err = expandScanner(err) 463 p.Error = &PackageError{ 464 ImportStack: stk.copy(), 465 Err: err.Error(), 466 } 467 return p 468 } 469 470 if p.Name == "main" { 471 // Report an error when the old code.google.com/p/go.tools paths are used. 472 if goTools[p.ImportPath] == stalePath { 473 newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1) 474 e := fmt.Sprintf("the %v command has moved; use %v instead.", p.ImportPath, newPath) 475 p.Error = &PackageError{Err: e} 476 return p 477 } 478 _, elem := filepath.Split(p.Dir) 479 full := buildContext.GOOS + "_" + buildContext.GOARCH + "/" + elem 480 if buildContext.GOOS != toolGOOS || buildContext.GOARCH != toolGOARCH { 481 // Install cross-compiled binaries to subdirectories of bin. 482 elem = full 483 } 484 if p.build.BinDir != gobin && goTools[p.ImportPath] == toBin { 485 // Override BinDir. 486 // This is from a subrepo but installs to $GOROOT/bin 487 // by default anyway (like godoc). 488 p.target = filepath.Join(gorootBin, elem) 489 } else if p.build.BinDir != "" { 490 // Install to GOBIN or bin of GOPATH entry. 491 p.target = filepath.Join(p.build.BinDir, elem) 492 } 493 if goTools[p.ImportPath] == toTool { 494 // This is for 'go tool'. 495 // Override all the usual logic and force it into the tool directory. 496 p.target = filepath.Join(gorootPkg, "tool", full) 497 } 498 if p.target != "" && buildContext.GOOS == "windows" { 499 p.target += ".exe" 500 } 501 } else if p.local { 502 // Local import turned into absolute path. 503 // No permanent install target. 504 p.target = "" 505 } else { 506 p.target = p.build.PkgObj 507 } 508 509 importPaths := p.Imports 510 // Packages that use cgo import runtime/cgo implicitly. 511 // Packages that use cgo also import syscall implicitly, 512 // to wrap errno. 513 // Exclude certain packages to avoid circular dependencies. 514 if len(p.CgoFiles) > 0 && (!p.Standard || !cgoExclude[p.ImportPath]) { 515 importPaths = append(importPaths, "runtime/cgo") 516 } 517 if len(p.CgoFiles) > 0 && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) { 518 importPaths = append(importPaths, "syscall") 519 } 520 // Everything depends on runtime, except runtime and unsafe. 521 if !p.Standard || (p.ImportPath != "runtime" && p.ImportPath != "unsafe") { 522 importPaths = append(importPaths, "runtime") 523 // When race detection enabled everything depends on runtime/race. 524 // Exclude certain packages to avoid circular dependencies. 525 if buildRace && (!p.Standard || !raceExclude[p.ImportPath]) { 526 importPaths = append(importPaths, "runtime/race") 527 } 528 } 529 530 // Build list of full paths to all Go files in the package, 531 // for use by commands like go fmt. 532 p.gofiles = stringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles) 533 for i := range p.gofiles { 534 p.gofiles[i] = filepath.Join(p.Dir, p.gofiles[i]) 535 } 536 sort.Strings(p.gofiles) 537 538 p.sfiles = stringList(p.SFiles) 539 for i := range p.sfiles { 540 p.sfiles[i] = filepath.Join(p.Dir, p.sfiles[i]) 541 } 542 sort.Strings(p.sfiles) 543 544 p.allgofiles = stringList(p.IgnoredGoFiles) 545 for i := range p.allgofiles { 546 p.allgofiles[i] = filepath.Join(p.Dir, p.allgofiles[i]) 547 } 548 p.allgofiles = append(p.allgofiles, p.gofiles...) 549 sort.Strings(p.allgofiles) 550 551 // Check for case-insensitive collision of input files. 552 // To avoid problems on case-insensitive files, we reject any package 553 // where two different input files have equal names under a case-insensitive 554 // comparison. 555 f1, f2 := foldDup(stringList( 556 p.GoFiles, 557 p.CgoFiles, 558 p.IgnoredGoFiles, 559 p.CFiles, 560 p.CXXFiles, 561 p.MFiles, 562 p.HFiles, 563 p.SFiles, 564 p.SysoFiles, 565 p.SwigFiles, 566 p.SwigCXXFiles, 567 p.TestGoFiles, 568 p.XTestGoFiles, 569 )) 570 if f1 != "" { 571 p.Error = &PackageError{ 572 ImportStack: stk.copy(), 573 Err: fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2), 574 } 575 return p 576 } 577 578 // Build list of imported packages and full dependency list. 579 imports := make([]*Package, 0, len(p.Imports)) 580 deps := make(map[string]*Package) 581 for i, path := range importPaths { 582 if path == "C" { 583 continue 584 } 585 p1 := loadImport(path, p.Dir, stk, p.build.ImportPos[path]) 586 if p1.local { 587 if !p.local && p.Error == nil { 588 p.Error = &PackageError{ 589 ImportStack: stk.copy(), 590 Err: fmt.Sprintf("local import %q in non-local package", path), 591 } 592 pos := p.build.ImportPos[path] 593 if len(pos) > 0 { 594 p.Error.Pos = pos[0].String() 595 } 596 } 597 path = p1.ImportPath 598 importPaths[i] = path 599 } 600 deps[path] = p1 601 imports = append(imports, p1) 602 for _, dep := range p1.deps { 603 deps[dep.ImportPath] = dep 604 } 605 if p1.Incomplete { 606 p.Incomplete = true 607 } 608 } 609 p.imports = imports 610 611 p.Deps = make([]string, 0, len(deps)) 612 for dep := range deps { 613 p.Deps = append(p.Deps, dep) 614 } 615 sort.Strings(p.Deps) 616 for _, dep := range p.Deps { 617 p1 := deps[dep] 618 if p1 == nil { 619 panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath) 620 } 621 p.deps = append(p.deps, p1) 622 if p1.Error != nil { 623 p.DepsErrors = append(p.DepsErrors, p1.Error) 624 } 625 } 626 627 // unsafe is a fake package. 628 if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") { 629 p.target = "" 630 } 631 p.Target = p.target 632 633 // Check for C code compiled with Plan 9 C compiler. 634 // No longer allowed except in runtime, runtime/cgo, or runtime/parlib, for now. 635 if len(p.CFiles) > 0 && !p.usesCgo() && (!p.Standard || (p.ImportPath != "runtime" && p.ImportPath != "runtime/parlib")) { 636 p.Error = &PackageError{ 637 ImportStack: stk.copy(), 638 Err: fmt.Sprintf("C source files not allowed when not using cgo: %s", strings.Join(p.CFiles, " ")), 639 } 640 return p 641 } 642 643 // In the absence of errors lower in the dependency tree, 644 // check for case-insensitive collisions of import paths. 645 if len(p.DepsErrors) == 0 { 646 dep1, dep2 := foldDup(p.Deps) 647 if dep1 != "" { 648 p.Error = &PackageError{ 649 ImportStack: stk.copy(), 650 Err: fmt.Sprintf("case-insensitive import collision: %q and %q", dep1, dep2), 651 } 652 return p 653 } 654 } 655 656 return p 657 } 658 659 // usesSwig reports whether the package needs to run SWIG. 660 func (p *Package) usesSwig() bool { 661 return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0 662 } 663 664 // usesCgo reports whether the package needs to run cgo 665 func (p *Package) usesCgo() bool { 666 return len(p.CgoFiles) > 0 667 } 668 669 // packageList returns the list of packages in the dag rooted at roots 670 // as visited in a depth-first post-order traversal. 671 func packageList(roots []*Package) []*Package { 672 seen := map[*Package]bool{} 673 all := []*Package{} 674 var walk func(*Package) 675 walk = func(p *Package) { 676 if seen[p] { 677 return 678 } 679 seen[p] = true 680 for _, p1 := range p.imports { 681 walk(p1) 682 } 683 all = append(all, p) 684 } 685 for _, root := range roots { 686 walk(root) 687 } 688 return all 689 } 690 691 // computeStale computes the Stale flag in the package dag that starts 692 // at the named pkgs (command-line arguments). 693 func computeStale(pkgs ...*Package) { 694 topRoot := map[string]bool{} 695 for _, p := range pkgs { 696 topRoot[p.Root] = true 697 } 698 699 for _, p := range packageList(pkgs) { 700 p.Stale = isStale(p, topRoot) 701 } 702 } 703 704 // The runtime version string takes one of two forms: 705 // "go1.X[.Y]" for Go releases, and "devel +hash" at tip. 706 // Determine whether we are in a released copy by 707 // inspecting the version. 708 var isGoRelease = strings.HasPrefix(runtime.Version(), "go1") 709 710 // isStale reports whether package p needs to be rebuilt. 711 func isStale(p *Package, topRoot map[string]bool) bool { 712 if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") { 713 // fake, builtin package 714 return false 715 } 716 if p.Error != nil { 717 return true 718 } 719 720 // A package without Go sources means we only found 721 // the installed .a file. Since we don't know how to rebuild 722 // it, it can't be stale, even if -a is set. This enables binary-only 723 // distributions of Go packages, although such binaries are 724 // only useful with the specific version of the toolchain that 725 // created them. 726 if len(p.gofiles) == 0 && !p.usesSwig() { 727 return false 728 } 729 730 // If we are running a release copy of Go, do not rebuild the standard packages. 731 // They may not be writable anyway, but they are certainly not changing. 732 // This makes 'go build -a' skip the standard packages when using an official release. 733 // See issue 4106 and issue 8290. 734 pkgBuildA := buildA 735 if p.Standard && isGoRelease { 736 pkgBuildA = false 737 } 738 739 if pkgBuildA || p.target == "" || p.Stale { 740 return true 741 } 742 743 // Package is stale if completely unbuilt. 744 var built time.Time 745 if fi, err := os.Stat(p.target); err == nil { 746 built = fi.ModTime() 747 } 748 if built.IsZero() { 749 return true 750 } 751 752 olderThan := func(file string) bool { 753 fi, err := os.Stat(file) 754 return err != nil || fi.ModTime().After(built) 755 } 756 757 // Package is stale if a dependency is, or if a dependency is newer. 758 for _, p1 := range p.deps { 759 if p1.Stale || p1.target != "" && olderThan(p1.target) { 760 return true 761 } 762 } 763 764 // As a courtesy to developers installing new versions of the compiler 765 // frequently, define that packages are stale if they are 766 // older than the compiler, and commands if they are older than 767 // the linker. This heuristic will not work if the binaries are 768 // back-dated, as some binary distributions may do, but it does handle 769 // a very common case. 770 // See issue 3036. 771 // Assume code in $GOROOT is up to date, since it may not be writeable. 772 // See issue 4106. 773 if p.Root != goroot { 774 if olderThan(buildToolchain.compiler()) { 775 return true 776 } 777 if p.build.IsCommand() && olderThan(buildToolchain.linker()) { 778 return true 779 } 780 } 781 782 // Have installed copy, probably built using current compilers, 783 // and built after its imported packages. The only reason now 784 // that we'd have to rebuild it is if the sources were newer than 785 // the package. If a package p is not in the same tree as any 786 // package named on the command-line, assume it is up-to-date 787 // no matter what the modification times on the source files indicate. 788 // This avoids rebuilding $GOROOT packages when people are 789 // working outside the Go root, and it effectively makes each tree 790 // listed in $GOPATH a separate compilation world. 791 // See issue 3149. 792 if p.Root != "" && !topRoot[p.Root] { 793 return false 794 } 795 796 srcs := stringList(p.GoFiles, p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.SFiles, p.CgoFiles, p.SysoFiles, p.SwigFiles, p.SwigCXXFiles) 797 for _, src := range srcs { 798 if olderThan(filepath.Join(p.Dir, src)) { 799 return true 800 } 801 } 802 803 return false 804 } 805 806 var cwd, _ = os.Getwd() 807 808 var cmdCache = map[string]*Package{} 809 810 // loadPackage is like loadImport but is used for command-line arguments, 811 // not for paths found in import statements. In addition to ordinary import paths, 812 // loadPackage accepts pseudo-paths beginning with cmd/ to denote commands 813 // in the Go command directory, as well as paths to those directories. 814 func loadPackage(arg string, stk *importStack) *Package { 815 if build.IsLocalImport(arg) { 816 dir := arg 817 if !filepath.IsAbs(dir) { 818 if abs, err := filepath.Abs(dir); err == nil { 819 // interpret relative to current directory 820 dir = abs 821 } 822 } 823 if sub, ok := hasSubdir(gorootSrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") { 824 arg = sub 825 } 826 } 827 if strings.HasPrefix(arg, "cmd/") && !strings.Contains(arg[4:], "/") { 828 if p := cmdCache[arg]; p != nil { 829 return p 830 } 831 stk.push(arg) 832 defer stk.pop() 833 834 bp, err := buildContext.ImportDir(filepath.Join(gorootSrc, arg), 0) 835 bp.ImportPath = arg 836 bp.Goroot = true 837 bp.BinDir = gorootBin 838 if gobin != "" { 839 bp.BinDir = gobin 840 } 841 bp.Root = goroot 842 bp.SrcRoot = gorootSrc 843 p := new(Package) 844 cmdCache[arg] = p 845 p.load(stk, bp, err) 846 if p.Error == nil && p.Name != "main" { 847 p.Error = &PackageError{ 848 ImportStack: stk.copy(), 849 Err: fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir), 850 } 851 } 852 return p 853 } 854 855 // Wasn't a command; must be a package. 856 // If it is a local import path but names a standard package, 857 // we treat it as if the user specified the standard package. 858 // This lets you run go test ./ioutil in package io and be 859 // referring to io/ioutil rather than a hypothetical import of 860 // "./ioutil". 861 if build.IsLocalImport(arg) { 862 bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly) 863 if bp.ImportPath != "" && bp.ImportPath != "." { 864 arg = bp.ImportPath 865 } 866 } 867 868 return loadImport(arg, cwd, stk, nil) 869 } 870 871 // packages returns the packages named by the 872 // command line arguments 'args'. If a named package 873 // cannot be loaded at all (for example, if the directory does not exist), 874 // then packages prints an error and does not include that 875 // package in the results. However, if errors occur trying 876 // to load dependencies of a named package, the named 877 // package is still returned, with p.Incomplete = true 878 // and details in p.DepsErrors. 879 func packages(args []string) []*Package { 880 var pkgs []*Package 881 for _, pkg := range packagesAndErrors(args) { 882 if pkg.Error != nil { 883 errorf("can't load package: %s", pkg.Error) 884 continue 885 } 886 pkgs = append(pkgs, pkg) 887 } 888 return pkgs 889 } 890 891 // packagesAndErrors is like 'packages' but returns a 892 // *Package for every argument, even the ones that 893 // cannot be loaded at all. 894 // The packages that fail to load will have p.Error != nil. 895 func packagesAndErrors(args []string) []*Package { 896 if len(args) > 0 && strings.HasSuffix(args[0], ".go") { 897 return []*Package{goFilesPackage(args)} 898 } 899 900 args = importPaths(args) 901 var pkgs []*Package 902 var stk importStack 903 var set = make(map[string]bool) 904 905 for _, arg := range args { 906 if !set[arg] { 907 pkgs = append(pkgs, loadPackage(arg, &stk)) 908 set[arg] = true 909 } 910 } 911 computeStale(pkgs...) 912 913 return pkgs 914 } 915 916 // packagesForBuild is like 'packages' but fails if any of 917 // the packages or their dependencies have errors 918 // (cannot be built). 919 func packagesForBuild(args []string) []*Package { 920 pkgs := packagesAndErrors(args) 921 printed := map[*PackageError]bool{} 922 for _, pkg := range pkgs { 923 if pkg.Error != nil { 924 errorf("can't load package: %s", pkg.Error) 925 } 926 for _, err := range pkg.DepsErrors { 927 // Since these are errors in dependencies, 928 // the same error might show up multiple times, 929 // once in each package that depends on it. 930 // Only print each once. 931 if !printed[err] { 932 printed[err] = true 933 errorf("%s", err) 934 } 935 } 936 } 937 exitIfErrors() 938 return pkgs 939 } 940 941 // hasSubdir reports whether dir is a subdirectory of 942 // (possibly multiple levels below) root. 943 // If so, it sets rel to the path fragment that must be 944 // appended to root to reach dir. 945 func hasSubdir(root, dir string) (rel string, ok bool) { 946 if p, err := filepath.EvalSymlinks(root); err == nil { 947 root = p 948 } 949 if p, err := filepath.EvalSymlinks(dir); err == nil { 950 dir = p 951 } 952 const sep = string(filepath.Separator) 953 root = filepath.Clean(root) 954 if !strings.HasSuffix(root, sep) { 955 root += sep 956 } 957 dir = filepath.Clean(dir) 958 if !strings.HasPrefix(dir, root) { 959 return "", false 960 } 961 return filepath.ToSlash(dir[len(root):]), true 962 }