github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/src/cmd/go/internal/load/pkg.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Package load loads packages. 6 package load 7 8 import ( 9 "fmt" 10 "go/build" 11 "go/token" 12 "io/ioutil" 13 "os" 14 pathpkg "path" 15 "path/filepath" 16 "sort" 17 "strings" 18 "unicode" 19 20 "cmd/go/internal/base" 21 "cmd/go/internal/cfg" 22 "cmd/go/internal/str" 23 ) 24 25 var IgnoreImports bool // control whether we ignore imports in packages 26 27 // A Package describes a single package found in a directory. 28 type Package struct { 29 PackagePublic // visible in 'go list' 30 Internal PackageInternal // for use inside go command only 31 } 32 33 type PackagePublic struct { 34 // Note: These fields are part of the go command's public API. 35 // See list.go. It is okay to add fields, but not to change or 36 // remove existing ones. Keep in sync with list.go 37 Dir string `json:",omitempty"` // directory containing package sources 38 ImportPath string `json:",omitempty"` // import path of package in dir 39 ImportComment string `json:",omitempty"` // path in import comment on package statement 40 Name string `json:",omitempty"` // package name 41 Doc string `json:",omitempty"` // package documentation string 42 Target string `json:",omitempty"` // installed target for this package (may be executable) 43 Shlib string `json:",omitempty"` // the shared library that contains this package (only set when -linkshared) 44 Goroot bool `json:",omitempty"` // is this package found in the Go root? 45 Standard bool `json:",omitempty"` // is this package part of the standard Go library? 46 Root string `json:",omitempty"` // Go root or Go path dir containing this package 47 ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory 48 BinaryOnly bool `json:",omitempty"` // package cannot be recompiled 49 50 // Stale and StaleReason remain here *only* for the list command. 51 // They are only initialized in preparation for list execution. 52 // The regular build determines staleness on the fly during action execution. 53 Stale bool `json:",omitempty"` // would 'go install' do anything for this package? 54 StaleReason string `json:",omitempty"` // why is Stale true? 55 56 // Source files 57 GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) 58 CgoFiles []string `json:",omitempty"` // .go sources files that import "C" 59 IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints 60 CFiles []string `json:",omitempty"` // .c source files 61 CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files 62 MFiles []string `json:",omitempty"` // .m source files 63 HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files 64 FFiles []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files 65 SFiles []string `json:",omitempty"` // .s source files 66 SwigFiles []string `json:",omitempty"` // .swig files 67 SwigCXXFiles []string `json:",omitempty"` // .swigcxx files 68 SysoFiles []string `json:",omitempty"` // .syso system object files added to package 69 70 // Cgo directives 71 CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler 72 CgoCPPFLAGS []string `json:",omitempty"` // cgo: flags for C preprocessor 73 CgoCXXFLAGS []string `json:",omitempty"` // cgo: flags for C++ compiler 74 CgoFFLAGS []string `json:",omitempty"` // cgo: flags for Fortran compiler 75 CgoLDFLAGS []string `json:",omitempty"` // cgo: flags for linker 76 CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names 77 78 // Dependency information 79 Imports []string `json:",omitempty"` // import paths used by this package 80 Deps []string `json:",omitempty"` // all (recursively) imported dependencies 81 82 // Error information 83 Incomplete bool `json:",omitempty"` // was there an error loading this package or dependencies? 84 Error *PackageError `json:",omitempty"` // error loading this package (not dependencies) 85 DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies 86 87 // Test information 88 TestGoFiles []string `json:",omitempty"` // _test.go files in package 89 TestImports []string `json:",omitempty"` // imports from TestGoFiles 90 XTestGoFiles []string `json:",omitempty"` // _test.go files outside package 91 XTestImports []string `json:",omitempty"` // imports from XTestGoFiles 92 } 93 94 type PackageInternal struct { 95 // Unexported fields are not part of the public API. 96 Build *build.Package 97 Imports []*Package // this package's direct imports 98 RawImports []string // this package's original imports as they appear in the text of the program 99 ForceLibrary bool // this package is a library (even if named "main") 100 CmdlineFiles bool // package built from files listed on command line 101 CmdlinePkg bool // package listed on command line 102 Local bool // imported via local path (./ or ../) 103 LocalPrefix string // interpret ./ and ../ imports relative to this prefix 104 ExeName string // desired name for temporary executable 105 CoverMode string // preprocess Go source files with the coverage tool in this mode 106 CoverVars map[string]*CoverVar // variables created by coverage analysis 107 OmitDebug bool // tell linker not to write debug information 108 GobinSubdir bool // install target would be subdir of GOBIN 109 110 Asmflags []string // -asmflags for this package 111 Gcflags []string // -gcflags for this package 112 Ldflags []string // -ldflags for this package 113 Gccgoflags []string // -gccgoflags for this package 114 } 115 116 type NoGoError struct { 117 Package *Package 118 } 119 120 func (e *NoGoError) Error() string { 121 // Count files beginning with _ and ., which we will pretend don't exist at all. 122 dummy := 0 123 for _, name := range e.Package.IgnoredGoFiles { 124 if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") { 125 dummy++ 126 } 127 } 128 129 if len(e.Package.IgnoredGoFiles) > dummy { 130 // Go files exist, but they were ignored due to build constraints. 131 return "build constraints exclude all Go files in " + e.Package.Dir 132 } 133 if len(e.Package.TestGoFiles)+len(e.Package.XTestGoFiles) > 0 { 134 // Test Go files exist, but we're not interested in them. 135 // The double-negative is unfortunate but we want e.Package.Dir 136 // to appear at the end of error message. 137 return "no non-test Go files in " + e.Package.Dir 138 } 139 return "no Go files in " + e.Package.Dir 140 } 141 142 // Vendored returns the vendor-resolved version of imports, 143 // which should be p.TestImports or p.XTestImports, NOT p.Imports. 144 // The imports in p.TestImports and p.XTestImports are not recursively 145 // loaded during the initial load of p, so they list the imports found in 146 // the source file, but most processing should be over the vendor-resolved 147 // import paths. We do this resolution lazily both to avoid file system work 148 // and because the eventual real load of the test imports (during 'go test') 149 // can produce better error messages if it starts with the original paths. 150 // The initial load of p loads all the non-test imports and rewrites 151 // the vendored paths, so nothing should ever call p.vendored(p.Imports). 152 func (p *Package) Vendored(imports []string) []string { 153 if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] { 154 panic("internal error: p.vendored(p.Imports) called") 155 } 156 seen := make(map[string]bool) 157 var all []string 158 for _, path := range imports { 159 path = VendoredImportPath(p, path) 160 if !seen[path] { 161 seen[path] = true 162 all = append(all, path) 163 } 164 } 165 sort.Strings(all) 166 return all 167 } 168 169 // CoverVar holds the name of the generated coverage variables targeting the named file. 170 type CoverVar struct { 171 File string // local file name 172 Var string // name of count struct 173 } 174 175 func (p *Package) copyBuild(pp *build.Package) { 176 p.Internal.Build = pp 177 178 if pp.PkgTargetRoot != "" && cfg.BuildPkgdir != "" { 179 old := pp.PkgTargetRoot 180 pp.PkgRoot = cfg.BuildPkgdir 181 pp.PkgTargetRoot = cfg.BuildPkgdir 182 pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old)) 183 } 184 185 p.Dir = pp.Dir 186 p.ImportPath = pp.ImportPath 187 p.ImportComment = pp.ImportComment 188 p.Name = pp.Name 189 p.Doc = pp.Doc 190 p.Root = pp.Root 191 p.ConflictDir = pp.ConflictDir 192 p.BinaryOnly = pp.BinaryOnly 193 194 // TODO? Target 195 p.Goroot = pp.Goroot 196 p.Standard = p.Goroot && p.ImportPath != "" && isStandardImportPath(p.ImportPath) 197 p.GoFiles = pp.GoFiles 198 p.CgoFiles = pp.CgoFiles 199 p.IgnoredGoFiles = pp.IgnoredGoFiles 200 p.CFiles = pp.CFiles 201 p.CXXFiles = pp.CXXFiles 202 p.MFiles = pp.MFiles 203 p.HFiles = pp.HFiles 204 p.FFiles = pp.FFiles 205 p.SFiles = pp.SFiles 206 p.SwigFiles = pp.SwigFiles 207 p.SwigCXXFiles = pp.SwigCXXFiles 208 p.SysoFiles = pp.SysoFiles 209 p.CgoCFLAGS = pp.CgoCFLAGS 210 p.CgoCPPFLAGS = pp.CgoCPPFLAGS 211 p.CgoCXXFLAGS = pp.CgoCXXFLAGS 212 p.CgoFFLAGS = pp.CgoFFLAGS 213 p.CgoLDFLAGS = pp.CgoLDFLAGS 214 p.CgoPkgConfig = pp.CgoPkgConfig 215 // We modify p.Imports in place, so make copy now. 216 p.Imports = make([]string, len(pp.Imports)) 217 copy(p.Imports, pp.Imports) 218 p.Internal.RawImports = pp.Imports 219 p.TestGoFiles = pp.TestGoFiles 220 p.TestImports = pp.TestImports 221 p.XTestGoFiles = pp.XTestGoFiles 222 p.XTestImports = pp.XTestImports 223 if IgnoreImports { 224 p.Imports = nil 225 p.TestImports = nil 226 p.XTestImports = nil 227 } 228 } 229 230 // isStandardImportPath reports whether $GOROOT/src/path should be considered 231 // part of the standard distribution. For historical reasons we allow people to add 232 // their own code to $GOROOT instead of using $GOPATH, but we assume that 233 // code will start with a domain name (dot in the first element). 234 func isStandardImportPath(path string) bool { 235 i := strings.Index(path, "/") 236 if i < 0 { 237 i = len(path) 238 } 239 elem := path[:i] 240 return !strings.Contains(elem, ".") 241 } 242 243 // A PackageError describes an error loading information about a package. 244 type PackageError struct { 245 ImportStack []string // shortest path from package named on command line to this one 246 Pos string // position of error 247 Err string // the error itself 248 IsImportCycle bool `json:"-"` // the error is an import cycle 249 Hard bool `json:"-"` // whether the error is soft or hard; soft errors are ignored in some places 250 } 251 252 func (p *PackageError) Error() string { 253 // Import cycles deserve special treatment. 254 if p.IsImportCycle { 255 return fmt.Sprintf("%s\npackage %s\n", p.Err, strings.Join(p.ImportStack, "\n\timports ")) 256 } 257 if p.Pos != "" { 258 // Omit import stack. The full path to the file where the error 259 // is the most important thing. 260 return p.Pos + ": " + p.Err 261 } 262 if len(p.ImportStack) == 0 { 263 return p.Err 264 } 265 return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err 266 } 267 268 // An ImportStack is a stack of import paths. 269 type ImportStack []string 270 271 func (s *ImportStack) Push(p string) { 272 *s = append(*s, p) 273 } 274 275 func (s *ImportStack) Pop() { 276 *s = (*s)[0 : len(*s)-1] 277 } 278 279 func (s *ImportStack) Copy() []string { 280 return append([]string{}, *s...) 281 } 282 283 // shorterThan reports whether sp is shorter than t. 284 // We use this to record the shortest import sequence 285 // that leads to a particular package. 286 func (sp *ImportStack) shorterThan(t []string) bool { 287 s := *sp 288 if len(s) != len(t) { 289 return len(s) < len(t) 290 } 291 // If they are the same length, settle ties using string ordering. 292 for i := range s { 293 if s[i] != t[i] { 294 return s[i] < t[i] 295 } 296 } 297 return false // they are equal 298 } 299 300 // packageCache is a lookup cache for loadPackage, 301 // so that if we look up a package multiple times 302 // we return the same pointer each time. 303 var packageCache = map[string]*Package{} 304 305 func ClearPackageCache() { 306 for name := range packageCache { 307 delete(packageCache, name) 308 } 309 } 310 311 func ClearPackageCachePartial(args []string) { 312 for _, arg := range args { 313 p := packageCache[arg] 314 if p != nil { 315 delete(packageCache, p.Dir) 316 delete(packageCache, p.ImportPath) 317 } 318 } 319 } 320 321 // reloadPackage is like loadPackage but makes sure 322 // not to use the package cache. 323 func ReloadPackage(arg string, stk *ImportStack) *Package { 324 p := packageCache[arg] 325 if p != nil { 326 delete(packageCache, p.Dir) 327 delete(packageCache, p.ImportPath) 328 } 329 return LoadPackage(arg, stk) 330 } 331 332 // dirToImportPath returns the pseudo-import path we use for a package 333 // outside the Go path. It begins with _/ and then contains the full path 334 // to the directory. If the package lives in c:\home\gopher\my\pkg then 335 // the pseudo-import path is _/c_/home/gopher/my/pkg. 336 // Using a pseudo-import path like this makes the ./ imports no longer 337 // a special case, so that all the code to deal with ordinary imports works 338 // automatically. 339 func dirToImportPath(dir string) string { 340 return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir))) 341 } 342 343 func makeImportValid(r rune) rune { 344 // Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport. 345 const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" 346 if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { 347 return '_' 348 } 349 return r 350 } 351 352 // Mode flags for loadImport and download (in get.go). 353 const ( 354 // UseVendor means that loadImport should do vendor expansion 355 // (provided the vendoring experiment is enabled). 356 // That is, useVendor means that the import path came from 357 // a source file and has not been vendor-expanded yet. 358 // Every import path should be loaded initially with useVendor, 359 // and then the expanded version (with the /vendor/ in it) gets 360 // recorded as the canonical import path. At that point, future loads 361 // of that package must not pass useVendor, because 362 // disallowVendor will reject direct use of paths containing /vendor/. 363 UseVendor = 1 << iota 364 365 // GetTestDeps is for download (part of "go get") and indicates 366 // that test dependencies should be fetched too. 367 GetTestDeps 368 ) 369 370 // LoadImport scans the directory named by path, which must be an import path, 371 // but possibly a local import path (an absolute file system path or one beginning 372 // with ./ or ../). A local relative path is interpreted relative to srcDir. 373 // It returns a *Package describing the package found in that directory. 374 func LoadImport(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package { 375 stk.Push(path) 376 defer stk.Pop() 377 378 // Determine canonical identifier for this package. 379 // For a local import the identifier is the pseudo-import path 380 // we create from the full directory to the package. 381 // Otherwise it is the usual import path. 382 // For vendored imports, it is the expanded form. 383 importPath := path 384 origPath := path 385 isLocal := build.IsLocalImport(path) 386 var debugDeprecatedImportcfgDir string 387 if isLocal { 388 importPath = dirToImportPath(filepath.Join(srcDir, path)) 389 } else if DebugDeprecatedImportcfg.enabled { 390 if d, i := DebugDeprecatedImportcfg.lookup(parent, path); d != "" { 391 debugDeprecatedImportcfgDir = d 392 importPath = i 393 } 394 } else if mode&UseVendor != 0 { 395 // We do our own vendor resolution, because we want to 396 // find out the key to use in packageCache without the 397 // overhead of repeated calls to buildContext.Import. 398 // The code is also needed in a few other places anyway. 399 path = VendoredImportPath(parent, path) 400 importPath = path 401 } 402 403 p := packageCache[importPath] 404 if p != nil { 405 p = reusePackage(p, stk) 406 } else { 407 p = new(Package) 408 p.Internal.Local = isLocal 409 p.ImportPath = importPath 410 packageCache[importPath] = p 411 412 // Load package. 413 // Import always returns bp != nil, even if an error occurs, 414 // in order to return partial information. 415 var bp *build.Package 416 var err error 417 if debugDeprecatedImportcfgDir != "" { 418 bp, err = cfg.BuildContext.ImportDir(debugDeprecatedImportcfgDir, 0) 419 } else { 420 buildMode := build.ImportComment 421 if mode&UseVendor == 0 || path != origPath { 422 // Not vendoring, or we already found the vendored path. 423 buildMode |= build.IgnoreVendor 424 } 425 bp, err = cfg.BuildContext.Import(path, srcDir, buildMode) 426 } 427 bp.ImportPath = importPath 428 if cfg.GOBIN != "" { 429 bp.BinDir = cfg.GOBIN 430 } 431 if debugDeprecatedImportcfgDir == "" && err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path && 432 !strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") { 433 err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment) 434 } 435 p.load(stk, bp, err) 436 if p.Error != nil && p.Error.Pos == "" { 437 p = setErrorPos(p, importPos) 438 } 439 440 if debugDeprecatedImportcfgDir == "" && origPath != cleanImport(origPath) { 441 p.Error = &PackageError{ 442 ImportStack: stk.Copy(), 443 Err: fmt.Sprintf("non-canonical import path: %q should be %q", origPath, pathpkg.Clean(origPath)), 444 } 445 p.Incomplete = true 446 } 447 } 448 449 // Checked on every import because the rules depend on the code doing the importing. 450 if perr := disallowInternal(srcDir, p, stk); perr != p { 451 return setErrorPos(perr, importPos) 452 } 453 if mode&UseVendor != 0 { 454 if perr := disallowVendor(srcDir, origPath, p, stk); perr != p { 455 return setErrorPos(perr, importPos) 456 } 457 } 458 459 if p.Name == "main" && parent != nil && parent.Dir != p.Dir { 460 perr := *p 461 perr.Error = &PackageError{ 462 ImportStack: stk.Copy(), 463 Err: fmt.Sprintf("import %q is a program, not an importable package", path), 464 } 465 return setErrorPos(&perr, importPos) 466 } 467 468 if p.Internal.Local && parent != nil && !parent.Internal.Local { 469 perr := *p 470 perr.Error = &PackageError{ 471 ImportStack: stk.Copy(), 472 Err: fmt.Sprintf("local import %q in non-local package", path), 473 } 474 return setErrorPos(&perr, importPos) 475 } 476 477 return p 478 } 479 480 func setErrorPos(p *Package, importPos []token.Position) *Package { 481 if len(importPos) > 0 { 482 pos := importPos[0] 483 pos.Filename = base.ShortPath(pos.Filename) 484 p.Error.Pos = pos.String() 485 } 486 return p 487 } 488 489 func cleanImport(path string) string { 490 orig := path 491 path = pathpkg.Clean(path) 492 if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") { 493 path = "./" + path 494 } 495 return path 496 } 497 498 var isDirCache = map[string]bool{} 499 500 func isDir(path string) bool { 501 result, ok := isDirCache[path] 502 if ok { 503 return result 504 } 505 506 fi, err := os.Stat(path) 507 result = err == nil && fi.IsDir() 508 isDirCache[path] = result 509 return result 510 } 511 512 // VendoredImportPath returns the expansion of path when it appears in parent. 513 // If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path, 514 // x/vendor/path, vendor/path, or else stay path if none of those exist. 515 // VendoredImportPath returns the expanded path or, if no expansion is found, the original. 516 func VendoredImportPath(parent *Package, path string) (found string) { 517 if parent == nil || parent.Root == "" { 518 return path 519 } 520 521 dir := filepath.Clean(parent.Dir) 522 root := filepath.Join(parent.Root, "src") 523 if !str.HasFilePathPrefix(dir, root) || parent.ImportPath != "command-line-arguments" && filepath.Join(root, parent.ImportPath) != dir { 524 // Look for symlinks before reporting error. 525 dir = expandPath(dir) 526 root = expandPath(root) 527 } 528 529 if !str.HasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || parent.ImportPath != "command-line-arguments" && !parent.Internal.Local && filepath.Join(root, parent.ImportPath) != dir { 530 base.Fatalf("unexpected directory layout:\n"+ 531 " import path: %s\n"+ 532 " root: %s\n"+ 533 " dir: %s\n"+ 534 " expand root: %s\n"+ 535 " expand dir: %s\n"+ 536 " separator: %s", 537 parent.ImportPath, 538 filepath.Join(parent.Root, "src"), 539 filepath.Clean(parent.Dir), 540 root, 541 dir, 542 string(filepath.Separator)) 543 } 544 545 vpath := "vendor/" + path 546 for i := len(dir); i >= len(root); i-- { 547 if i < len(dir) && dir[i] != filepath.Separator { 548 continue 549 } 550 // Note: checking for the vendor directory before checking 551 // for the vendor/path directory helps us hit the 552 // isDir cache more often. It also helps us prepare a more useful 553 // list of places we looked, to report when an import is not found. 554 if !isDir(filepath.Join(dir[:i], "vendor")) { 555 continue 556 } 557 targ := filepath.Join(dir[:i], vpath) 558 if isDir(targ) && hasGoFiles(targ) { 559 importPath := parent.ImportPath 560 if importPath == "command-line-arguments" { 561 // If parent.ImportPath is 'command-line-arguments'. 562 // set to relative directory to root (also chopped root directory) 563 importPath = dir[len(root)+1:] 564 } 565 // We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy. 566 // We know the import path for parent's dir. 567 // We chopped off some number of path elements and 568 // added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path. 569 // Now we want to know the import path for that directory. 570 // Construct it by chopping the same number of path elements 571 // (actually the same number of bytes) from parent's import path 572 // and then append /vendor/path. 573 chopped := len(dir) - i 574 if chopped == len(importPath)+1 { 575 // We walked up from c:\gopath\src\foo\bar 576 // and found c:\gopath\src\vendor\path. 577 // We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7). 578 // Use "vendor/path" without any prefix. 579 return vpath 580 } 581 return importPath[:len(importPath)-chopped] + "/" + vpath 582 } 583 } 584 return path 585 } 586 587 // hasGoFiles reports whether dir contains any files with names ending in .go. 588 // For a vendor check we must exclude directories that contain no .go files. 589 // Otherwise it is not possible to vendor just a/b/c and still import the 590 // non-vendored a/b. See golang.org/issue/13832. 591 func hasGoFiles(dir string) bool { 592 fis, _ := ioutil.ReadDir(dir) 593 for _, fi := range fis { 594 if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".go") { 595 return true 596 } 597 } 598 return false 599 } 600 601 // reusePackage reuses package p to satisfy the import at the top 602 // of the import stack stk. If this use causes an import loop, 603 // reusePackage updates p's error information to record the loop. 604 func reusePackage(p *Package, stk *ImportStack) *Package { 605 // We use p.Internal.Imports==nil to detect a package that 606 // is in the midst of its own loadPackage call 607 // (all the recursion below happens before p.Internal.Imports gets set). 608 if p.Internal.Imports == nil { 609 if p.Error == nil { 610 p.Error = &PackageError{ 611 ImportStack: stk.Copy(), 612 Err: "import cycle not allowed", 613 IsImportCycle: true, 614 } 615 } 616 p.Incomplete = true 617 } 618 // Don't rewrite the import stack in the error if we have an import cycle. 619 // If we do, we'll lose the path that describes the cycle. 620 if p.Error != nil && !p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack) { 621 p.Error.ImportStack = stk.Copy() 622 } 623 return p 624 } 625 626 // disallowInternal checks that srcDir is allowed to import p. 627 // If the import is allowed, disallowInternal returns the original package p. 628 // If not, it returns a new package containing just an appropriate error. 629 func disallowInternal(srcDir string, p *Package, stk *ImportStack) *Package { 630 // golang.org/s/go14internal: 631 // An import of a path containing the element “internal” 632 // is disallowed if the importing code is outside the tree 633 // rooted at the parent of the “internal” directory. 634 635 // There was an error loading the package; stop here. 636 if p.Error != nil { 637 return p 638 } 639 640 // The generated 'testmain' package is allowed to access testing/internal/..., 641 // as if it were generated into the testing directory tree 642 // (it's actually in a temporary directory outside any Go tree). 643 // This cleans up a former kludge in passing functionality to the testing package. 644 if strings.HasPrefix(p.ImportPath, "testing/internal") && len(*stk) >= 2 && (*stk)[len(*stk)-2] == "testmain" { 645 return p 646 } 647 648 // We can't check standard packages with gccgo. 649 if cfg.BuildContext.Compiler == "gccgo" && p.Standard { 650 return p 651 } 652 653 // The stack includes p.ImportPath. 654 // If that's the only thing on the stack, we started 655 // with a name given on the command line, not an 656 // import. Anything listed on the command line is fine. 657 if len(*stk) == 1 { 658 return p 659 } 660 661 // Check for "internal" element: three cases depending on begin of string and/or end of string. 662 i, ok := findInternal(p.ImportPath) 663 if !ok { 664 return p 665 } 666 667 // Internal is present. 668 // Map import path back to directory corresponding to parent of internal. 669 if i > 0 { 670 i-- // rewind over slash in ".../internal" 671 } 672 parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)] 673 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 674 return p 675 } 676 677 // Look for symlinks before reporting error. 678 srcDir = expandPath(srcDir) 679 parent = expandPath(parent) 680 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 681 return p 682 } 683 684 // Internal is present, and srcDir is outside parent's tree. Not allowed. 685 perr := *p 686 perr.Error = &PackageError{ 687 ImportStack: stk.Copy(), 688 Err: "use of internal package not allowed", 689 } 690 perr.Incomplete = true 691 return &perr 692 } 693 694 // findInternal looks for the final "internal" path element in the given import path. 695 // If there isn't one, findInternal returns ok=false. 696 // Otherwise, findInternal returns ok=true and the index of the "internal". 697 func findInternal(path string) (index int, ok bool) { 698 // Three cases, depending on internal at start/end of string or not. 699 // The order matters: we must return the index of the final element, 700 // because the final one produces the most restrictive requirement 701 // on the importer. 702 switch { 703 case strings.HasSuffix(path, "/internal"): 704 return len(path) - len("internal"), true 705 case strings.Contains(path, "/internal/"): 706 return strings.LastIndex(path, "/internal/") + 1, true 707 case path == "internal", strings.HasPrefix(path, "internal/"): 708 return 0, true 709 } 710 return 0, false 711 } 712 713 // disallowVendor checks that srcDir is allowed to import p as path. 714 // If the import is allowed, disallowVendor returns the original package p. 715 // If not, it returns a new package containing just an appropriate error. 716 func disallowVendor(srcDir, path string, p *Package, stk *ImportStack) *Package { 717 // The stack includes p.ImportPath. 718 // If that's the only thing on the stack, we started 719 // with a name given on the command line, not an 720 // import. Anything listed on the command line is fine. 721 if len(*stk) == 1 { 722 return p 723 } 724 725 if perr := disallowVendorVisibility(srcDir, p, stk); perr != p { 726 return perr 727 } 728 729 // Paths like x/vendor/y must be imported as y, never as x/vendor/y. 730 if i, ok := FindVendor(path); ok { 731 perr := *p 732 perr.Error = &PackageError{ 733 ImportStack: stk.Copy(), 734 Err: "must be imported as " + path[i+len("vendor/"):], 735 } 736 perr.Incomplete = true 737 return &perr 738 } 739 740 return p 741 } 742 743 // disallowVendorVisibility checks that srcDir is allowed to import p. 744 // The rules are the same as for /internal/ except that a path ending in /vendor 745 // is not subject to the rules, only subdirectories of vendor. 746 // This allows people to have packages and commands named vendor, 747 // for maximal compatibility with existing source trees. 748 func disallowVendorVisibility(srcDir string, p *Package, stk *ImportStack) *Package { 749 // The stack includes p.ImportPath. 750 // If that's the only thing on the stack, we started 751 // with a name given on the command line, not an 752 // import. Anything listed on the command line is fine. 753 if len(*stk) == 1 { 754 return p 755 } 756 757 // Check for "vendor" element. 758 i, ok := FindVendor(p.ImportPath) 759 if !ok { 760 return p 761 } 762 763 // Vendor is present. 764 // Map import path back to directory corresponding to parent of vendor. 765 if i > 0 { 766 i-- // rewind over slash in ".../vendor" 767 } 768 truncateTo := i + len(p.Dir) - len(p.ImportPath) 769 if truncateTo < 0 || len(p.Dir) < truncateTo { 770 return p 771 } 772 parent := p.Dir[:truncateTo] 773 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 774 return p 775 } 776 777 // Look for symlinks before reporting error. 778 srcDir = expandPath(srcDir) 779 parent = expandPath(parent) 780 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 781 return p 782 } 783 784 // Vendor is present, and srcDir is outside parent's tree. Not allowed. 785 perr := *p 786 perr.Error = &PackageError{ 787 ImportStack: stk.Copy(), 788 Err: "use of vendored package not allowed", 789 } 790 perr.Incomplete = true 791 return &perr 792 } 793 794 // FindVendor looks for the last non-terminating "vendor" path element in the given import path. 795 // If there isn't one, FindVendor returns ok=false. 796 // Otherwise, FindVendor returns ok=true and the index of the "vendor". 797 // 798 // Note that terminating "vendor" elements don't count: "x/vendor" is its own package, 799 // not the vendored copy of an import "" (the empty import path). 800 // This will allow people to have packages or commands named vendor. 801 // This may help reduce breakage, or it may just be confusing. We'll see. 802 func FindVendor(path string) (index int, ok bool) { 803 // Two cases, depending on internal at start of string or not. 804 // The order matters: we must return the index of the final element, 805 // because the final one is where the effective import path starts. 806 switch { 807 case strings.Contains(path, "/vendor/"): 808 return strings.LastIndex(path, "/vendor/") + 1, true 809 case strings.HasPrefix(path, "vendor/"): 810 return 0, true 811 } 812 return 0, false 813 } 814 815 type TargetDir int 816 817 const ( 818 ToTool TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*) 819 ToBin // to bin dir inside package root (default for non-cmd/*) 820 StalePath // an old import path; fail to build 821 ) 822 823 // InstallTargetDir reports the target directory for installing the command p. 824 func InstallTargetDir(p *Package) TargetDir { 825 if strings.HasPrefix(p.ImportPath, "code.google.com/p/go.tools/cmd/") { 826 return StalePath 827 } 828 if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" { 829 switch p.ImportPath { 830 case "cmd/go", "cmd/gofmt": 831 return ToBin 832 } 833 return ToTool 834 } 835 return ToBin 836 } 837 838 var cgoExclude = map[string]bool{ 839 "runtime/cgo": true, 840 } 841 842 var cgoSyscallExclude = map[string]bool{ 843 "runtime/cgo": true, 844 "runtime/race": true, 845 "runtime/msan": true, 846 } 847 848 var foldPath = make(map[string]string) 849 850 // load populates p using information from bp, err, which should 851 // be the result of calling build.Context.Import. 852 func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { 853 p.copyBuild(bp) 854 855 // Decide whether p was listed on the command line. 856 // Given that load is called while processing the command line, 857 // you might think we could simply pass a flag down into load 858 // saying whether we are loading something named on the command 859 // line or something to satisfy an import. But the first load of a 860 // package named on the command line may be as a dependency 861 // of an earlier package named on the command line, not when we 862 // get to that package during command line processing. 863 // For example "go test fmt reflect" will load reflect as a dependency 864 // of fmt before it attempts to load as a command-line argument. 865 // Because loads are cached, the later load will be a no-op, 866 // so it is important that the first load can fill in CmdlinePkg correctly. 867 // Hence the call to an explicit matching check here. 868 p.Internal.CmdlinePkg = isCmdlinePkg(p) 869 870 p.Internal.Asmflags = BuildAsmflags.For(p) 871 p.Internal.Gcflags = BuildGcflags.For(p) 872 p.Internal.Ldflags = BuildLdflags.For(p) 873 p.Internal.Gccgoflags = BuildGccgoflags.For(p) 874 875 // The localPrefix is the path we interpret ./ imports relative to. 876 // Synthesized main packages sometimes override this. 877 if p.Internal.Local { 878 p.Internal.LocalPrefix = dirToImportPath(p.Dir) 879 } 880 881 if err != nil { 882 if _, ok := err.(*build.NoGoError); ok { 883 err = &NoGoError{Package: p} 884 } 885 p.Incomplete = true 886 err = base.ExpandScanner(err) 887 p.Error = &PackageError{ 888 ImportStack: stk.Copy(), 889 Err: err.Error(), 890 } 891 return 892 } 893 894 useBindir := p.Name == "main" 895 if !p.Standard { 896 switch cfg.BuildBuildmode { 897 case "c-archive", "c-shared", "plugin": 898 useBindir = false 899 } 900 } 901 902 if useBindir { 903 // Report an error when the old code.google.com/p/go.tools paths are used. 904 if InstallTargetDir(p) == StalePath { 905 newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1) 906 e := fmt.Sprintf("the %v command has moved; use %v instead.", p.ImportPath, newPath) 907 p.Error = &PackageError{Err: e} 908 return 909 } 910 _, elem := filepath.Split(p.Dir) 911 full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem 912 if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH { 913 // Install cross-compiled binaries to subdirectories of bin. 914 elem = full 915 } 916 if p.Internal.Build.BinDir != "" { 917 // Install to GOBIN or bin of GOPATH entry. 918 p.Target = filepath.Join(p.Internal.Build.BinDir, elem) 919 if !p.Goroot && strings.Contains(elem, "/") && cfg.GOBIN != "" { 920 // Do not create $GOBIN/goos_goarch/elem. 921 p.Target = "" 922 p.Internal.GobinSubdir = true 923 } 924 } 925 if InstallTargetDir(p) == ToTool { 926 // This is for 'go tool'. 927 // Override all the usual logic and force it into the tool directory. 928 p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full) 929 } 930 if p.Target != "" && cfg.BuildContext.GOOS == "windows" { 931 p.Target += ".exe" 932 } 933 } else if p.Internal.Local { 934 // Local import turned into absolute path. 935 // No permanent install target. 936 p.Target = "" 937 } else { 938 p.Target = p.Internal.Build.PkgObj 939 if cfg.BuildLinkshared { 940 shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname" 941 shlib, err := ioutil.ReadFile(shlibnamefile) 942 if err != nil && !os.IsNotExist(err) { 943 base.Fatalf("reading shlibname: %v", err) 944 } 945 if err == nil { 946 libname := strings.TrimSpace(string(shlib)) 947 if cfg.BuildContext.Compiler == "gccgo" { 948 p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname) 949 } else { 950 p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname) 951 } 952 } 953 } 954 } 955 956 // Build augmented import list to add implicit dependencies. 957 // Be careful not to add imports twice, just to avoid confusion. 958 importPaths := p.Imports 959 addImport := func(path string) { 960 for _, p := range importPaths { 961 if path == p { 962 return 963 } 964 } 965 importPaths = append(importPaths, path) 966 } 967 968 // Cgo translation adds imports of "runtime/cgo" and "syscall", 969 // except for certain packages, to avoid circular dependencies. 970 if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) { 971 addImport("runtime/cgo") 972 } 973 if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) { 974 addImport("syscall") 975 } 976 977 // SWIG adds imports of some standard packages. 978 if p.UsesSwig() { 979 addImport("runtime/cgo") 980 addImport("syscall") 981 addImport("sync") 982 983 // TODO: The .swig and .swigcxx files can use 984 // %go_import directives to import other packages. 985 } 986 987 // The linker loads implicit dependencies. 988 if p.Name == "main" && !p.Internal.ForceLibrary { 989 for _, dep := range LinkerDeps(p) { 990 addImport(dep) 991 } 992 } 993 994 // Check for case-insensitive collision of input files. 995 // To avoid problems on case-insensitive files, we reject any package 996 // where two different input files have equal names under a case-insensitive 997 // comparison. 998 f1, f2 := str.FoldDup(str.StringList( 999 p.GoFiles, 1000 p.CgoFiles, 1001 p.IgnoredGoFiles, 1002 p.CFiles, 1003 p.CXXFiles, 1004 p.MFiles, 1005 p.HFiles, 1006 p.FFiles, 1007 p.SFiles, 1008 p.SysoFiles, 1009 p.SwigFiles, 1010 p.SwigCXXFiles, 1011 p.TestGoFiles, 1012 p.XTestGoFiles, 1013 )) 1014 if f1 != "" { 1015 p.Error = &PackageError{ 1016 ImportStack: stk.Copy(), 1017 Err: fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2), 1018 } 1019 return 1020 } 1021 1022 // Build list of imported packages and full dependency list. 1023 imports := make([]*Package, 0, len(p.Imports)) 1024 for i, path := range importPaths { 1025 if path == "C" { 1026 continue 1027 } 1028 p1 := LoadImport(path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], UseVendor) 1029 if p.Standard && p.Error == nil && !p1.Standard && p1.Error == nil { 1030 p.Error = &PackageError{ 1031 ImportStack: stk.Copy(), 1032 Err: fmt.Sprintf("non-standard import %q in standard package %q", path, p.ImportPath), 1033 } 1034 pos := p.Internal.Build.ImportPos[path] 1035 if len(pos) > 0 { 1036 p.Error.Pos = pos[0].String() 1037 } 1038 } 1039 1040 path = p1.ImportPath 1041 importPaths[i] = path 1042 if i < len(p.Imports) { 1043 p.Imports[i] = path 1044 } 1045 1046 imports = append(imports, p1) 1047 if p1.Incomplete { 1048 p.Incomplete = true 1049 } 1050 } 1051 p.Internal.Imports = imports 1052 1053 deps := make(map[string]*Package) 1054 var q []*Package 1055 q = append(q, imports...) 1056 for i := 0; i < len(q); i++ { 1057 p1 := q[i] 1058 path := p1.ImportPath 1059 // The same import path could produce an error or not, 1060 // depending on what tries to import it. 1061 // Prefer to record entries with errors, so we can report them. 1062 p0 := deps[path] 1063 if p0 == nil || p1.Error != nil && (p0.Error == nil || len(p0.Error.ImportStack) > len(p1.Error.ImportStack)) { 1064 deps[path] = p1 1065 for _, p2 := range p1.Internal.Imports { 1066 if deps[p2.ImportPath] != p2 { 1067 q = append(q, p2) 1068 } 1069 } 1070 } 1071 } 1072 1073 p.Deps = make([]string, 0, len(deps)) 1074 for dep := range deps { 1075 p.Deps = append(p.Deps, dep) 1076 } 1077 sort.Strings(p.Deps) 1078 for _, dep := range p.Deps { 1079 p1 := deps[dep] 1080 if p1 == nil { 1081 panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath) 1082 } 1083 if p1.Error != nil { 1084 p.DepsErrors = append(p.DepsErrors, p1.Error) 1085 } 1086 } 1087 1088 // unsafe is a fake package. 1089 if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") { 1090 p.Target = "" 1091 } 1092 1093 // If cgo is not enabled, ignore cgo supporting sources 1094 // just as we ignore go files containing import "C". 1095 if !cfg.BuildContext.CgoEnabled { 1096 p.CFiles = nil 1097 p.CXXFiles = nil 1098 p.MFiles = nil 1099 p.SwigFiles = nil 1100 p.SwigCXXFiles = nil 1101 // Note that SFiles are okay (they go to the Go assembler) 1102 // and HFiles are okay (they might be used by the SFiles). 1103 // Also Sysofiles are okay (they might not contain object 1104 // code; see issue #16050). 1105 } 1106 1107 setError := func(msg string) { 1108 p.Error = &PackageError{ 1109 ImportStack: stk.Copy(), 1110 Err: msg, 1111 } 1112 } 1113 1114 // The gc toolchain only permits C source files with cgo or SWIG. 1115 if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" { 1116 setError(fmt.Sprintf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " "))) 1117 return 1118 } 1119 1120 // C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG, 1121 // regardless of toolchain. 1122 if len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { 1123 setError(fmt.Sprintf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " "))) 1124 return 1125 } 1126 if len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { 1127 setError(fmt.Sprintf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " "))) 1128 return 1129 } 1130 if len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { 1131 setError(fmt.Sprintf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " "))) 1132 return 1133 } 1134 1135 // Check for case-insensitive collisions of import paths. 1136 fold := str.ToFold(p.ImportPath) 1137 if other := foldPath[fold]; other == "" { 1138 foldPath[fold] = p.ImportPath 1139 } else if other != p.ImportPath { 1140 setError(fmt.Sprintf("case-insensitive import collision: %q and %q", p.ImportPath, other)) 1141 return 1142 } 1143 } 1144 1145 // LinkerDeps returns the list of linker-induced dependencies for main package p. 1146 func LinkerDeps(p *Package) []string { 1147 // Everything links runtime. 1148 deps := []string{"runtime"} 1149 1150 // External linking mode forces an import of runtime/cgo. 1151 if externalLinkingForced(p) { 1152 deps = append(deps, "runtime/cgo") 1153 } 1154 // On ARM with GOARM=5, it forces an import of math, for soft floating point. 1155 if cfg.Goarch == "arm" { 1156 deps = append(deps, "math") 1157 } 1158 // Using the race detector forces an import of runtime/race. 1159 if cfg.BuildRace { 1160 deps = append(deps, "runtime/race") 1161 } 1162 // Using memory sanitizer forces an import of runtime/msan. 1163 if cfg.BuildMSan { 1164 deps = append(deps, "runtime/msan") 1165 } 1166 1167 return deps 1168 } 1169 1170 // externalLinkingForced reports whether external linking is being 1171 // forced even for programs that do not use cgo. 1172 func externalLinkingForced(p *Package) bool { 1173 // Some targets must use external linking even inside GOROOT. 1174 switch cfg.BuildContext.GOOS { 1175 case "android": 1176 return true 1177 case "darwin": 1178 switch cfg.BuildContext.GOARCH { 1179 case "arm", "arm64": 1180 return true 1181 } 1182 } 1183 1184 if !cfg.BuildContext.CgoEnabled { 1185 return false 1186 } 1187 // Currently build modes c-shared, pie (on systems that do not 1188 // support PIE with internal linking mode (currently all 1189 // systems: issue #18968)), plugin, and -linkshared force 1190 // external linking mode, as of course does 1191 // -ldflags=-linkmode=external. External linking mode forces 1192 // an import of runtime/cgo. 1193 pieCgo := cfg.BuildBuildmode == "pie" 1194 linkmodeExternal := false 1195 if p != nil { 1196 ldflags := BuildLdflags.For(p) 1197 for i, a := range ldflags { 1198 if a == "-linkmode=external" { 1199 linkmodeExternal = true 1200 } 1201 if a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" { 1202 linkmodeExternal = true 1203 } 1204 } 1205 } 1206 1207 return cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" || pieCgo || cfg.BuildLinkshared || linkmodeExternal 1208 } 1209 1210 // mkAbs rewrites list, which must be paths relative to p.Dir, 1211 // into a sorted list of absolute paths. It edits list in place but for 1212 // convenience also returns list back to its caller. 1213 func (p *Package) mkAbs(list []string) []string { 1214 for i, f := range list { 1215 list[i] = filepath.Join(p.Dir, f) 1216 } 1217 sort.Strings(list) 1218 return list 1219 } 1220 1221 // InternalGoFiles returns the list of Go files being built for the package, 1222 // using absolute paths. 1223 func (p *Package) InternalGoFiles() []string { 1224 return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) 1225 } 1226 1227 // InternalGoFiles returns the list of all Go files possibly relevant for the package, 1228 // using absolute paths. "Possibly relevant" means that files are not excluded 1229 // due to build tags, but files with names beginning with . or _ are still excluded. 1230 func (p *Package) InternalAllGoFiles() []string { 1231 var extra []string 1232 for _, f := range p.IgnoredGoFiles { 1233 if f != "" && f[0] != '.' || f[0] != '_' { 1234 extra = append(extra, f) 1235 } 1236 } 1237 return p.mkAbs(str.StringList(extra, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) 1238 } 1239 1240 // usesSwig reports whether the package needs to run SWIG. 1241 func (p *Package) UsesSwig() bool { 1242 return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0 1243 } 1244 1245 // usesCgo reports whether the package needs to run cgo 1246 func (p *Package) UsesCgo() bool { 1247 return len(p.CgoFiles) > 0 1248 } 1249 1250 // packageList returns the list of packages in the dag rooted at roots 1251 // as visited in a depth-first post-order traversal. 1252 func PackageList(roots []*Package) []*Package { 1253 seen := map[*Package]bool{} 1254 all := []*Package{} 1255 var walk func(*Package) 1256 walk = func(p *Package) { 1257 if seen[p] { 1258 return 1259 } 1260 seen[p] = true 1261 for _, p1 := range p.Internal.Imports { 1262 walk(p1) 1263 } 1264 all = append(all, p) 1265 } 1266 for _, root := range roots { 1267 walk(root) 1268 } 1269 return all 1270 } 1271 1272 var cmdCache = map[string]*Package{} 1273 1274 func ClearCmdCache() { 1275 for name := range cmdCache { 1276 delete(cmdCache, name) 1277 } 1278 } 1279 1280 // loadPackage is like loadImport but is used for command-line arguments, 1281 // not for paths found in import statements. In addition to ordinary import paths, 1282 // loadPackage accepts pseudo-paths beginning with cmd/ to denote commands 1283 // in the Go command directory, as well as paths to those directories. 1284 func LoadPackage(arg string, stk *ImportStack) *Package { 1285 if build.IsLocalImport(arg) { 1286 dir := arg 1287 if !filepath.IsAbs(dir) { 1288 if abs, err := filepath.Abs(dir); err == nil { 1289 // interpret relative to current directory 1290 dir = abs 1291 } 1292 } 1293 if sub, ok := hasSubdir(cfg.GOROOTsrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") { 1294 arg = sub 1295 } 1296 } 1297 if strings.HasPrefix(arg, "cmd/") && !strings.Contains(arg[4:], "/") { 1298 if p := cmdCache[arg]; p != nil { 1299 return p 1300 } 1301 stk.Push(arg) 1302 defer stk.Pop() 1303 1304 bp, err := cfg.BuildContext.ImportDir(filepath.Join(cfg.GOROOTsrc, arg), 0) 1305 bp.ImportPath = arg 1306 bp.Goroot = true 1307 bp.BinDir = cfg.GOROOTbin 1308 if cfg.GOROOTbin != "" { 1309 bp.BinDir = cfg.GOROOTbin 1310 } 1311 bp.Root = cfg.GOROOT 1312 bp.SrcRoot = cfg.GOROOTsrc 1313 p := new(Package) 1314 cmdCache[arg] = p 1315 p.load(stk, bp, err) 1316 if p.Error == nil && p.Name != "main" { 1317 p.Error = &PackageError{ 1318 ImportStack: stk.Copy(), 1319 Err: fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir), 1320 } 1321 } 1322 return p 1323 } 1324 1325 // Wasn't a command; must be a package. 1326 // If it is a local import path but names a standard package, 1327 // we treat it as if the user specified the standard package. 1328 // This lets you run go test ./ioutil in package io and be 1329 // referring to io/ioutil rather than a hypothetical import of 1330 // "./ioutil". 1331 if build.IsLocalImport(arg) { 1332 bp, _ := cfg.BuildContext.ImportDir(filepath.Join(base.Cwd, arg), build.FindOnly) 1333 if bp.ImportPath != "" && bp.ImportPath != "." { 1334 arg = bp.ImportPath 1335 } 1336 } 1337 1338 return LoadImport(arg, base.Cwd, nil, stk, nil, 0) 1339 } 1340 1341 // packages returns the packages named by the 1342 // command line arguments 'args'. If a named package 1343 // cannot be loaded at all (for example, if the directory does not exist), 1344 // then packages prints an error and does not include that 1345 // package in the results. However, if errors occur trying 1346 // to load dependencies of a named package, the named 1347 // package is still returned, with p.Incomplete = true 1348 // and details in p.DepsErrors. 1349 func Packages(args []string) []*Package { 1350 var pkgs []*Package 1351 for _, pkg := range PackagesAndErrors(args) { 1352 if pkg.Error != nil { 1353 base.Errorf("can't load package: %s", pkg.Error) 1354 continue 1355 } 1356 pkgs = append(pkgs, pkg) 1357 } 1358 return pkgs 1359 } 1360 1361 // packagesAndErrors is like 'packages' but returns a 1362 // *Package for every argument, even the ones that 1363 // cannot be loaded at all. 1364 // The packages that fail to load will have p.Error != nil. 1365 func PackagesAndErrors(args []string) []*Package { 1366 if len(args) > 0 && strings.HasSuffix(args[0], ".go") { 1367 return []*Package{GoFilesPackage(args)} 1368 } 1369 1370 args = ImportPaths(args) 1371 var ( 1372 pkgs []*Package 1373 stk ImportStack 1374 seenArg = make(map[string]bool) 1375 seenPkg = make(map[*Package]bool) 1376 ) 1377 1378 for _, arg := range args { 1379 if seenArg[arg] { 1380 continue 1381 } 1382 seenArg[arg] = true 1383 pkg := LoadPackage(arg, &stk) 1384 if seenPkg[pkg] { 1385 continue 1386 } 1387 seenPkg[pkg] = true 1388 pkgs = append(pkgs, pkg) 1389 } 1390 1391 return pkgs 1392 } 1393 1394 // packagesForBuild is like 'packages' but fails if any of 1395 // the packages or their dependencies have errors 1396 // (cannot be built). 1397 func PackagesForBuild(args []string) []*Package { 1398 pkgs := PackagesAndErrors(args) 1399 printed := map[*PackageError]bool{} 1400 for _, pkg := range pkgs { 1401 if pkg.Error != nil { 1402 base.Errorf("can't load package: %s", pkg.Error) 1403 } 1404 for _, err := range pkg.DepsErrors { 1405 // Since these are errors in dependencies, 1406 // the same error might show up multiple times, 1407 // once in each package that depends on it. 1408 // Only print each once. 1409 if !printed[err] { 1410 printed[err] = true 1411 base.Errorf("%s", err) 1412 } 1413 } 1414 } 1415 base.ExitIfErrors() 1416 1417 // Check for duplicate loads of the same package. 1418 // That should be impossible, but if it does happen then 1419 // we end up trying to build the same package twice, 1420 // usually in parallel overwriting the same files, 1421 // which doesn't work very well. 1422 seen := map[string]bool{} 1423 reported := map[string]bool{} 1424 for _, pkg := range PackageList(pkgs) { 1425 if seen[pkg.ImportPath] && !reported[pkg.ImportPath] { 1426 reported[pkg.ImportPath] = true 1427 base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath) 1428 } 1429 seen[pkg.ImportPath] = true 1430 } 1431 base.ExitIfErrors() 1432 1433 return pkgs 1434 } 1435 1436 // GoFilesPackage creates a package for building a collection of Go files 1437 // (typically named on the command line). The target is named p.a for 1438 // package p or named after the first Go file for package main. 1439 func GoFilesPackage(gofiles []string) *Package { 1440 // TODO: Remove this restriction. 1441 for _, f := range gofiles { 1442 if !strings.HasSuffix(f, ".go") { 1443 base.Fatalf("named files must be .go files") 1444 } 1445 } 1446 1447 var stk ImportStack 1448 ctxt := cfg.BuildContext 1449 ctxt.UseAllFiles = true 1450 1451 // Synthesize fake "directory" that only shows the named files, 1452 // to make it look like this is a standard package or 1453 // command directory. So that local imports resolve 1454 // consistently, the files must all be in the same directory. 1455 var dirent []os.FileInfo 1456 var dir string 1457 for _, file := range gofiles { 1458 fi, err := os.Stat(file) 1459 if err != nil { 1460 base.Fatalf("%s", err) 1461 } 1462 if fi.IsDir() { 1463 base.Fatalf("%s is a directory, should be a Go file", file) 1464 } 1465 dir1, _ := filepath.Split(file) 1466 if dir1 == "" { 1467 dir1 = "./" 1468 } 1469 if dir == "" { 1470 dir = dir1 1471 } else if dir != dir1 { 1472 base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1) 1473 } 1474 dirent = append(dirent, fi) 1475 } 1476 ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil } 1477 1478 var err error 1479 if dir == "" { 1480 dir = base.Cwd 1481 } 1482 dir, err = filepath.Abs(dir) 1483 if err != nil { 1484 base.Fatalf("%s", err) 1485 } 1486 1487 bp, err := ctxt.ImportDir(dir, 0) 1488 pkg := new(Package) 1489 pkg.Internal.Local = true 1490 pkg.Internal.CmdlineFiles = true 1491 stk.Push("main") 1492 pkg.load(&stk, bp, err) 1493 stk.Pop() 1494 pkg.Internal.LocalPrefix = dirToImportPath(dir) 1495 pkg.ImportPath = "command-line-arguments" 1496 pkg.Target = "" 1497 1498 if pkg.Name == "main" { 1499 _, elem := filepath.Split(gofiles[0]) 1500 exe := elem[:len(elem)-len(".go")] + cfg.ExeSuffix 1501 if cfg.BuildO == "" { 1502 cfg.BuildO = exe 1503 } 1504 if cfg.GOBIN != "" { 1505 pkg.Target = filepath.Join(cfg.GOBIN, exe) 1506 } 1507 } 1508 1509 return pkg 1510 }