github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/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 if isLocal { 387 importPath = dirToImportPath(filepath.Join(srcDir, path)) 388 } else if mode&UseVendor != 0 { 389 // We do our own vendor resolution, because we want to 390 // find out the key to use in packageCache without the 391 // overhead of repeated calls to buildContext.Import. 392 // The code is also needed in a few other places anyway. 393 path = VendoredImportPath(parent, path) 394 importPath = path 395 } 396 397 p := packageCache[importPath] 398 if p != nil { 399 p = reusePackage(p, stk) 400 } else { 401 p = new(Package) 402 p.Internal.Local = isLocal 403 p.ImportPath = importPath 404 packageCache[importPath] = p 405 406 // Load package. 407 // Import always returns bp != nil, even if an error occurs, 408 // in order to return partial information. 409 // 410 // TODO: After Go 1, decide when to pass build.AllowBinary here. 411 // See issue 3268 for mistakes to avoid. 412 buildMode := build.ImportComment 413 if mode&UseVendor == 0 || path != origPath { 414 // Not vendoring, or we already found the vendored path. 415 buildMode |= build.IgnoreVendor 416 } 417 bp, err := cfg.BuildContext.Import(path, srcDir, buildMode) 418 bp.ImportPath = importPath 419 if cfg.GOBIN != "" { 420 bp.BinDir = cfg.GOBIN 421 } 422 if err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path && 423 !strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") { 424 err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment) 425 } 426 p.load(stk, bp, err) 427 if p.Error != nil && p.Error.Pos == "" { 428 p = setErrorPos(p, importPos) 429 } 430 431 if origPath != cleanImport(origPath) { 432 p.Error = &PackageError{ 433 ImportStack: stk.Copy(), 434 Err: fmt.Sprintf("non-canonical import path: %q should be %q", origPath, pathpkg.Clean(origPath)), 435 } 436 p.Incomplete = true 437 } 438 } 439 440 // Checked on every import because the rules depend on the code doing the importing. 441 if perr := disallowInternal(srcDir, p, stk); perr != p { 442 return setErrorPos(perr, importPos) 443 } 444 if mode&UseVendor != 0 { 445 if perr := disallowVendor(srcDir, origPath, p, stk); perr != p { 446 return setErrorPos(perr, importPos) 447 } 448 } 449 450 if p.Name == "main" && parent != nil && parent.Dir != p.Dir { 451 perr := *p 452 perr.Error = &PackageError{ 453 ImportStack: stk.Copy(), 454 Err: fmt.Sprintf("import %q is a program, not an importable package", path), 455 } 456 return setErrorPos(&perr, importPos) 457 } 458 459 if p.Internal.Local && parent != nil && !parent.Internal.Local { 460 perr := *p 461 perr.Error = &PackageError{ 462 ImportStack: stk.Copy(), 463 Err: fmt.Sprintf("local import %q in non-local package", path), 464 } 465 return setErrorPos(&perr, importPos) 466 } 467 468 return p 469 } 470 471 func setErrorPos(p *Package, importPos []token.Position) *Package { 472 if len(importPos) > 0 { 473 pos := importPos[0] 474 pos.Filename = base.ShortPath(pos.Filename) 475 p.Error.Pos = pos.String() 476 } 477 return p 478 } 479 480 func cleanImport(path string) string { 481 orig := path 482 path = pathpkg.Clean(path) 483 if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") { 484 path = "./" + path 485 } 486 return path 487 } 488 489 var isDirCache = map[string]bool{} 490 491 func isDir(path string) bool { 492 result, ok := isDirCache[path] 493 if ok { 494 return result 495 } 496 497 fi, err := os.Stat(path) 498 result = err == nil && fi.IsDir() 499 isDirCache[path] = result 500 return result 501 } 502 503 // VendoredImportPath returns the expansion of path when it appears in parent. 504 // If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path, 505 // x/vendor/path, vendor/path, or else stay path if none of those exist. 506 // VendoredImportPath returns the expanded path or, if no expansion is found, the original. 507 func VendoredImportPath(parent *Package, path string) (found string) { 508 if parent == nil || parent.Root == "" { 509 return path 510 } 511 512 dir := filepath.Clean(parent.Dir) 513 root := filepath.Join(parent.Root, "src") 514 if !hasFilePathPrefix(dir, root) || parent.ImportPath != "command-line-arguments" && filepath.Join(root, parent.ImportPath) != dir { 515 // Look for symlinks before reporting error. 516 dir = expandPath(dir) 517 root = expandPath(root) 518 } 519 520 if !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 { 521 base.Fatalf("unexpected directory layout:\n"+ 522 " import path: %s\n"+ 523 " root: %s\n"+ 524 " dir: %s\n"+ 525 " expand root: %s\n"+ 526 " expand dir: %s\n"+ 527 " separator: %s", 528 parent.ImportPath, 529 filepath.Join(parent.Root, "src"), 530 filepath.Clean(parent.Dir), 531 root, 532 dir, 533 string(filepath.Separator)) 534 } 535 536 vpath := "vendor/" + path 537 for i := len(dir); i >= len(root); i-- { 538 if i < len(dir) && dir[i] != filepath.Separator { 539 continue 540 } 541 // Note: checking for the vendor directory before checking 542 // for the vendor/path directory helps us hit the 543 // isDir cache more often. It also helps us prepare a more useful 544 // list of places we looked, to report when an import is not found. 545 if !isDir(filepath.Join(dir[:i], "vendor")) { 546 continue 547 } 548 targ := filepath.Join(dir[:i], vpath) 549 if isDir(targ) && hasGoFiles(targ) { 550 importPath := parent.ImportPath 551 if importPath == "command-line-arguments" { 552 // If parent.ImportPath is 'command-line-arguments'. 553 // set to relative directory to root (also chopped root directory) 554 importPath = dir[len(root)+1:] 555 } 556 // We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy. 557 // We know the import path for parent's dir. 558 // We chopped off some number of path elements and 559 // added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path. 560 // Now we want to know the import path for that directory. 561 // Construct it by chopping the same number of path elements 562 // (actually the same number of bytes) from parent's import path 563 // and then append /vendor/path. 564 chopped := len(dir) - i 565 if chopped == len(importPath)+1 { 566 // We walked up from c:\gopath\src\foo\bar 567 // and found c:\gopath\src\vendor\path. 568 // We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7). 569 // Use "vendor/path" without any prefix. 570 return vpath 571 } 572 return importPath[:len(importPath)-chopped] + "/" + vpath 573 } 574 } 575 return path 576 } 577 578 // hasGoFiles reports whether dir contains any files with names ending in .go. 579 // For a vendor check we must exclude directories that contain no .go files. 580 // Otherwise it is not possible to vendor just a/b/c and still import the 581 // non-vendored a/b. See golang.org/issue/13832. 582 func hasGoFiles(dir string) bool { 583 fis, _ := ioutil.ReadDir(dir) 584 for _, fi := range fis { 585 if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".go") { 586 return true 587 } 588 } 589 return false 590 } 591 592 // reusePackage reuses package p to satisfy the import at the top 593 // of the import stack stk. If this use causes an import loop, 594 // reusePackage updates p's error information to record the loop. 595 func reusePackage(p *Package, stk *ImportStack) *Package { 596 // We use p.Internal.Imports==nil to detect a package that 597 // is in the midst of its own loadPackage call 598 // (all the recursion below happens before p.Internal.Imports gets set). 599 if p.Internal.Imports == nil { 600 if p.Error == nil { 601 p.Error = &PackageError{ 602 ImportStack: stk.Copy(), 603 Err: "import cycle not allowed", 604 IsImportCycle: true, 605 } 606 } 607 p.Incomplete = true 608 } 609 // Don't rewrite the import stack in the error if we have an import cycle. 610 // If we do, we'll lose the path that describes the cycle. 611 if p.Error != nil && !p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack) { 612 p.Error.ImportStack = stk.Copy() 613 } 614 return p 615 } 616 617 // disallowInternal checks that srcDir is allowed to import p. 618 // If the import is allowed, disallowInternal returns the original package p. 619 // If not, it returns a new package containing just an appropriate error. 620 func disallowInternal(srcDir string, p *Package, stk *ImportStack) *Package { 621 // golang.org/s/go14internal: 622 // An import of a path containing the element “internal” 623 // is disallowed if the importing code is outside the tree 624 // rooted at the parent of the “internal” directory. 625 626 // There was an error loading the package; stop here. 627 if p.Error != nil { 628 return p 629 } 630 631 // The generated 'testmain' package is allowed to access testing/internal/..., 632 // as if it were generated into the testing directory tree 633 // (it's actually in a temporary directory outside any Go tree). 634 // This cleans up a former kludge in passing functionality to the testing package. 635 if strings.HasPrefix(p.ImportPath, "testing/internal") && len(*stk) >= 2 && (*stk)[len(*stk)-2] == "testmain" { 636 return p 637 } 638 639 // We can't check standard packages with gccgo. 640 if cfg.BuildContext.Compiler == "gccgo" && p.Standard { 641 return p 642 } 643 644 // The stack includes p.ImportPath. 645 // If that's the only thing on the stack, we started 646 // with a name given on the command line, not an 647 // import. Anything listed on the command line is fine. 648 if len(*stk) == 1 { 649 return p 650 } 651 652 // Check for "internal" element: three cases depending on begin of string and/or end of string. 653 i, ok := findInternal(p.ImportPath) 654 if !ok { 655 return p 656 } 657 658 // Internal is present. 659 // Map import path back to directory corresponding to parent of internal. 660 if i > 0 { 661 i-- // rewind over slash in ".../internal" 662 } 663 parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)] 664 if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 665 return p 666 } 667 668 // Look for symlinks before reporting error. 669 srcDir = expandPath(srcDir) 670 parent = expandPath(parent) 671 if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 672 return p 673 } 674 675 // Internal is present, and srcDir is outside parent's tree. Not allowed. 676 perr := *p 677 perr.Error = &PackageError{ 678 ImportStack: stk.Copy(), 679 Err: "use of internal package not allowed", 680 } 681 perr.Incomplete = true 682 return &perr 683 } 684 685 // findInternal looks for the final "internal" path element in the given import path. 686 // If there isn't one, findInternal returns ok=false. 687 // Otherwise, findInternal returns ok=true and the index of the "internal". 688 func findInternal(path string) (index int, ok bool) { 689 // Three cases, depending on internal at start/end of string or not. 690 // The order matters: we must return the index of the final element, 691 // because the final one produces the most restrictive requirement 692 // on the importer. 693 switch { 694 case strings.HasSuffix(path, "/internal"): 695 return len(path) - len("internal"), true 696 case strings.Contains(path, "/internal/"): 697 return strings.LastIndex(path, "/internal/") + 1, true 698 case path == "internal", strings.HasPrefix(path, "internal/"): 699 return 0, true 700 } 701 return 0, false 702 } 703 704 // disallowVendor checks that srcDir is allowed to import p as path. 705 // If the import is allowed, disallowVendor returns the original package p. 706 // If not, it returns a new package containing just an appropriate error. 707 func disallowVendor(srcDir, path string, p *Package, stk *ImportStack) *Package { 708 // The stack includes p.ImportPath. 709 // If that's the only thing on the stack, we started 710 // with a name given on the command line, not an 711 // import. Anything listed on the command line is fine. 712 if len(*stk) == 1 { 713 return p 714 } 715 716 if perr := disallowVendorVisibility(srcDir, p, stk); perr != p { 717 return perr 718 } 719 720 // Paths like x/vendor/y must be imported as y, never as x/vendor/y. 721 if i, ok := FindVendor(path); ok { 722 perr := *p 723 perr.Error = &PackageError{ 724 ImportStack: stk.Copy(), 725 Err: "must be imported as " + path[i+len("vendor/"):], 726 } 727 perr.Incomplete = true 728 return &perr 729 } 730 731 return p 732 } 733 734 // disallowVendorVisibility checks that srcDir is allowed to import p. 735 // The rules are the same as for /internal/ except that a path ending in /vendor 736 // is not subject to the rules, only subdirectories of vendor. 737 // This allows people to have packages and commands named vendor, 738 // for maximal compatibility with existing source trees. 739 func disallowVendorVisibility(srcDir string, p *Package, stk *ImportStack) *Package { 740 // The stack includes p.ImportPath. 741 // If that's the only thing on the stack, we started 742 // with a name given on the command line, not an 743 // import. Anything listed on the command line is fine. 744 if len(*stk) == 1 { 745 return p 746 } 747 748 // Check for "vendor" element. 749 i, ok := FindVendor(p.ImportPath) 750 if !ok { 751 return p 752 } 753 754 // Vendor is present. 755 // Map import path back to directory corresponding to parent of vendor. 756 if i > 0 { 757 i-- // rewind over slash in ".../vendor" 758 } 759 truncateTo := i + len(p.Dir) - len(p.ImportPath) 760 if truncateTo < 0 || len(p.Dir) < truncateTo { 761 return p 762 } 763 parent := p.Dir[:truncateTo] 764 if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 765 return p 766 } 767 768 // Look for symlinks before reporting error. 769 srcDir = expandPath(srcDir) 770 parent = expandPath(parent) 771 if hasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 772 return p 773 } 774 775 // Vendor is present, and srcDir is outside parent's tree. Not allowed. 776 perr := *p 777 perr.Error = &PackageError{ 778 ImportStack: stk.Copy(), 779 Err: "use of vendored package not allowed", 780 } 781 perr.Incomplete = true 782 return &perr 783 } 784 785 // FindVendor looks for the last non-terminating "vendor" path element in the given import path. 786 // If there isn't one, FindVendor returns ok=false. 787 // Otherwise, FindVendor returns ok=true and the index of the "vendor". 788 // 789 // Note that terminating "vendor" elements don't count: "x/vendor" is its own package, 790 // not the vendored copy of an import "" (the empty import path). 791 // This will allow people to have packages or commands named vendor. 792 // This may help reduce breakage, or it may just be confusing. We'll see. 793 func FindVendor(path string) (index int, ok bool) { 794 // Two cases, depending on internal at start of string or not. 795 // The order matters: we must return the index of the final element, 796 // because the final one is where the effective import path starts. 797 switch { 798 case strings.Contains(path, "/vendor/"): 799 return strings.LastIndex(path, "/vendor/") + 1, true 800 case strings.HasPrefix(path, "vendor/"): 801 return 0, true 802 } 803 return 0, false 804 } 805 806 type TargetDir int 807 808 const ( 809 ToTool TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*) 810 ToBin // to bin dir inside package root (default for non-cmd/*) 811 StalePath // an old import path; fail to build 812 ) 813 814 // InstallTargetDir reports the target directory for installing the command p. 815 func InstallTargetDir(p *Package) TargetDir { 816 if strings.HasPrefix(p.ImportPath, "code.google.com/p/go.tools/cmd/") { 817 return StalePath 818 } 819 if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" { 820 switch p.ImportPath { 821 case "cmd/go", "cmd/gofmt": 822 return ToBin 823 } 824 return ToTool 825 } 826 return ToBin 827 } 828 829 var cgoExclude = map[string]bool{ 830 "runtime/cgo": true, 831 } 832 833 var cgoSyscallExclude = map[string]bool{ 834 "runtime/cgo": true, 835 "runtime/race": true, 836 "runtime/msan": true, 837 } 838 839 var foldPath = make(map[string]string) 840 841 // load populates p using information from bp, err, which should 842 // be the result of calling build.Context.Import. 843 func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { 844 p.copyBuild(bp) 845 846 // Decide whether p was listed on the command line. 847 // Given that load is called while processing the command line, 848 // you might think we could simply pass a flag down into load 849 // saying whether we are loading something named on the command 850 // line or something to satisfy an import. But the first load of a 851 // package named on the command line may be as a dependency 852 // of an earlier package named on the command line, not when we 853 // get to that package during command line processing. 854 // For example "go test fmt reflect" will load reflect as a dependency 855 // of fmt before it attempts to load as a command-line argument. 856 // Because loads are cached, the later load will be a no-op, 857 // so it is important that the first load can fill in CmdlinePkg correctly. 858 // Hence the call to an explicit matching check here. 859 p.Internal.CmdlinePkg = isCmdlinePkg(p) 860 861 p.Internal.Asmflags = BuildAsmflags.For(p) 862 p.Internal.Gcflags = BuildGcflags.For(p) 863 p.Internal.Ldflags = BuildLdflags.For(p) 864 p.Internal.Gccgoflags = BuildGccgoflags.For(p) 865 866 // The localPrefix is the path we interpret ./ imports relative to. 867 // Synthesized main packages sometimes override this. 868 if p.Internal.Local { 869 p.Internal.LocalPrefix = dirToImportPath(p.Dir) 870 } 871 872 if err != nil { 873 if _, ok := err.(*build.NoGoError); ok { 874 err = &NoGoError{Package: p} 875 } 876 p.Incomplete = true 877 err = base.ExpandScanner(err) 878 p.Error = &PackageError{ 879 ImportStack: stk.Copy(), 880 Err: err.Error(), 881 } 882 return 883 } 884 885 useBindir := p.Name == "main" 886 if !p.Standard { 887 switch cfg.BuildBuildmode { 888 case "c-archive", "c-shared", "plugin": 889 useBindir = false 890 } 891 } 892 893 if useBindir { 894 // Report an error when the old code.google.com/p/go.tools paths are used. 895 if InstallTargetDir(p) == StalePath { 896 newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1) 897 e := fmt.Sprintf("the %v command has moved; use %v instead.", p.ImportPath, newPath) 898 p.Error = &PackageError{Err: e} 899 return 900 } 901 _, elem := filepath.Split(p.Dir) 902 full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem 903 if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH { 904 // Install cross-compiled binaries to subdirectories of bin. 905 elem = full 906 } 907 if p.Internal.Build.BinDir != "" { 908 // Install to GOBIN or bin of GOPATH entry. 909 p.Target = filepath.Join(p.Internal.Build.BinDir, elem) 910 if !p.Goroot && strings.Contains(elem, "/") && cfg.GOBIN != "" { 911 // Do not create $GOBIN/goos_goarch/elem. 912 p.Target = "" 913 p.Internal.GobinSubdir = true 914 } 915 } 916 if InstallTargetDir(p) == ToTool { 917 // This is for 'go tool'. 918 // Override all the usual logic and force it into the tool directory. 919 p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full) 920 } 921 if p.Target != "" && cfg.BuildContext.GOOS == "windows" { 922 p.Target += ".exe" 923 } 924 } else if p.Internal.Local { 925 // Local import turned into absolute path. 926 // No permanent install target. 927 p.Target = "" 928 } else { 929 p.Target = p.Internal.Build.PkgObj 930 if cfg.BuildLinkshared { 931 shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname" 932 shlib, err := ioutil.ReadFile(shlibnamefile) 933 if err != nil && !os.IsNotExist(err) { 934 base.Fatalf("reading shlibname: %v", err) 935 } 936 if err == nil { 937 libname := strings.TrimSpace(string(shlib)) 938 if cfg.BuildContext.Compiler == "gccgo" { 939 p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname) 940 } else { 941 p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname) 942 } 943 } 944 } 945 } 946 947 // Build augmented import list to add implicit dependencies. 948 // Be careful not to add imports twice, just to avoid confusion. 949 importPaths := p.Imports 950 addImport := func(path string) { 951 for _, p := range importPaths { 952 if path == p { 953 return 954 } 955 } 956 importPaths = append(importPaths, path) 957 } 958 959 // Cgo translation adds imports of "runtime/cgo" and "syscall", 960 // except for certain packages, to avoid circular dependencies. 961 if len(p.CgoFiles) > 0 && (!p.Standard || !cgoExclude[p.ImportPath]) { 962 addImport("runtime/cgo") 963 } 964 if len(p.CgoFiles) > 0 && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) { 965 addImport("syscall") 966 } 967 968 // The linker loads implicit dependencies. 969 if p.Name == "main" && !p.Internal.ForceLibrary { 970 for _, dep := range LinkerDeps(p) { 971 addImport(dep) 972 } 973 } 974 975 // Check for case-insensitive collision of input files. 976 // To avoid problems on case-insensitive files, we reject any package 977 // where two different input files have equal names under a case-insensitive 978 // comparison. 979 f1, f2 := str.FoldDup(str.StringList( 980 p.GoFiles, 981 p.CgoFiles, 982 p.IgnoredGoFiles, 983 p.CFiles, 984 p.CXXFiles, 985 p.MFiles, 986 p.HFiles, 987 p.FFiles, 988 p.SFiles, 989 p.SysoFiles, 990 p.SwigFiles, 991 p.SwigCXXFiles, 992 p.TestGoFiles, 993 p.XTestGoFiles, 994 )) 995 if f1 != "" { 996 p.Error = &PackageError{ 997 ImportStack: stk.Copy(), 998 Err: fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2), 999 } 1000 return 1001 } 1002 1003 // Build list of imported packages and full dependency list. 1004 imports := make([]*Package, 0, len(p.Imports)) 1005 for i, path := range importPaths { 1006 if path == "C" { 1007 continue 1008 } 1009 p1 := LoadImport(path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], UseVendor) 1010 if p.Standard && p.Error == nil && !p1.Standard && p1.Error == nil { 1011 p.Error = &PackageError{ 1012 ImportStack: stk.Copy(), 1013 Err: fmt.Sprintf("non-standard import %q in standard package %q", path, p.ImportPath), 1014 } 1015 pos := p.Internal.Build.ImportPos[path] 1016 if len(pos) > 0 { 1017 p.Error.Pos = pos[0].String() 1018 } 1019 } 1020 1021 path = p1.ImportPath 1022 importPaths[i] = path 1023 if i < len(p.Imports) { 1024 p.Imports[i] = path 1025 } 1026 1027 imports = append(imports, p1) 1028 if p1.Incomplete { 1029 p.Incomplete = true 1030 } 1031 } 1032 p.Internal.Imports = imports 1033 1034 deps := make(map[string]*Package) 1035 var q []*Package 1036 q = append(q, imports...) 1037 for i := 0; i < len(q); i++ { 1038 p1 := q[i] 1039 path := p1.ImportPath 1040 // The same import path could produce an error or not, 1041 // depending on what tries to import it. 1042 // Prefer to record entries with errors, so we can report them. 1043 p0 := deps[path] 1044 if p0 == nil || p1.Error != nil && (p0.Error == nil || len(p0.Error.ImportStack) > len(p1.Error.ImportStack)) { 1045 deps[path] = p1 1046 for _, p2 := range p1.Internal.Imports { 1047 if deps[p2.ImportPath] != p2 { 1048 q = append(q, p2) 1049 } 1050 } 1051 } 1052 } 1053 1054 p.Deps = make([]string, 0, len(deps)) 1055 for dep := range deps { 1056 p.Deps = append(p.Deps, dep) 1057 } 1058 sort.Strings(p.Deps) 1059 for _, dep := range p.Deps { 1060 p1 := deps[dep] 1061 if p1 == nil { 1062 panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath) 1063 } 1064 if p1.Error != nil { 1065 p.DepsErrors = append(p.DepsErrors, p1.Error) 1066 } 1067 } 1068 1069 // unsafe is a fake package. 1070 if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") { 1071 p.Target = "" 1072 } 1073 1074 // If cgo is not enabled, ignore cgo supporting sources 1075 // just as we ignore go files containing import "C". 1076 if !cfg.BuildContext.CgoEnabled { 1077 p.CFiles = nil 1078 p.CXXFiles = nil 1079 p.MFiles = nil 1080 p.SwigFiles = nil 1081 p.SwigCXXFiles = nil 1082 // Note that SFiles are okay (they go to the Go assembler) 1083 // and HFiles are okay (they might be used by the SFiles). 1084 // Also Sysofiles are okay (they might not contain object 1085 // code; see issue #16050). 1086 } 1087 1088 setError := func(msg string) { 1089 p.Error = &PackageError{ 1090 ImportStack: stk.Copy(), 1091 Err: msg, 1092 } 1093 } 1094 1095 // The gc toolchain only permits C source files with cgo or SWIG. 1096 if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" { 1097 setError(fmt.Sprintf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " "))) 1098 return 1099 } 1100 1101 // C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG, 1102 // regardless of toolchain. 1103 if len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { 1104 setError(fmt.Sprintf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " "))) 1105 return 1106 } 1107 if len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { 1108 setError(fmt.Sprintf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " "))) 1109 return 1110 } 1111 if len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { 1112 setError(fmt.Sprintf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " "))) 1113 return 1114 } 1115 1116 // Check for case-insensitive collisions of import paths. 1117 fold := str.ToFold(p.ImportPath) 1118 if other := foldPath[fold]; other == "" { 1119 foldPath[fold] = p.ImportPath 1120 } else if other != p.ImportPath { 1121 setError(fmt.Sprintf("case-insensitive import collision: %q and %q", p.ImportPath, other)) 1122 return 1123 } 1124 } 1125 1126 // LinkerDeps returns the list of linker-induced dependencies for main package p. 1127 func LinkerDeps(p *Package) []string { 1128 // Everything links runtime. 1129 deps := []string{"runtime"} 1130 1131 // External linking mode forces an import of runtime/cgo. 1132 if externalLinkingForced(p) { 1133 deps = append(deps, "runtime/cgo") 1134 } 1135 // On ARM with GOARM=5, it forces an import of math, for soft floating point. 1136 if cfg.Goarch == "arm" { 1137 deps = append(deps, "math") 1138 } 1139 // Using the race detector forces an import of runtime/race. 1140 if cfg.BuildRace { 1141 deps = append(deps, "runtime/race") 1142 } 1143 // Using memory sanitizer forces an import of runtime/msan. 1144 if cfg.BuildMSan { 1145 deps = append(deps, "runtime/msan") 1146 } 1147 1148 return deps 1149 } 1150 1151 // externalLinkingForced reports whether external linking is being 1152 // forced even for programs that do not use cgo. 1153 func externalLinkingForced(p *Package) bool { 1154 // Some targets must use external linking even inside GOROOT. 1155 switch cfg.BuildContext.GOOS { 1156 case "android": 1157 return true 1158 case "darwin": 1159 switch cfg.BuildContext.GOARCH { 1160 case "arm", "arm64": 1161 return true 1162 } 1163 } 1164 1165 if !cfg.BuildContext.CgoEnabled { 1166 return false 1167 } 1168 // Currently build modes c-shared, pie (on systems that do not 1169 // support PIE with internal linking mode (currently all 1170 // systems: issue #18968)), plugin, and -linkshared force 1171 // external linking mode, as of course does 1172 // -ldflags=-linkmode=external. External linking mode forces 1173 // an import of runtime/cgo. 1174 pieCgo := cfg.BuildBuildmode == "pie" 1175 linkmodeExternal := false 1176 if p != nil { 1177 ldflags := BuildLdflags.For(p) 1178 for i, a := range ldflags { 1179 if a == "-linkmode=external" { 1180 linkmodeExternal = true 1181 } 1182 if a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" { 1183 linkmodeExternal = true 1184 } 1185 } 1186 } 1187 1188 return cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" || pieCgo || cfg.BuildLinkshared || linkmodeExternal 1189 } 1190 1191 // mkAbs rewrites list, which must be paths relative to p.Dir, 1192 // into a sorted list of absolute paths. It edits list in place but for 1193 // convenience also returns list back to its caller. 1194 func (p *Package) mkAbs(list []string) []string { 1195 for i, f := range list { 1196 list[i] = filepath.Join(p.Dir, f) 1197 } 1198 sort.Strings(list) 1199 return list 1200 } 1201 1202 // InternalGoFiles returns the list of Go files being built for the package, 1203 // using absolute paths. 1204 func (p *Package) InternalGoFiles() []string { 1205 return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) 1206 } 1207 1208 // InternalGoFiles returns the list of all Go files possibly relevant for the package, 1209 // using absolute paths. "Possibly relevant" means that files are not excluded 1210 // due to build tags, but files with names beginning with . or _ are still excluded. 1211 func (p *Package) InternalAllGoFiles() []string { 1212 var extra []string 1213 for _, f := range p.IgnoredGoFiles { 1214 if f != "" && f[0] != '.' || f[0] != '_' { 1215 extra = append(extra, f) 1216 } 1217 } 1218 return p.mkAbs(str.StringList(extra, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) 1219 } 1220 1221 // usesSwig reports whether the package needs to run SWIG. 1222 func (p *Package) UsesSwig() bool { 1223 return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0 1224 } 1225 1226 // usesCgo reports whether the package needs to run cgo 1227 func (p *Package) UsesCgo() bool { 1228 return len(p.CgoFiles) > 0 1229 } 1230 1231 // packageList returns the list of packages in the dag rooted at roots 1232 // as visited in a depth-first post-order traversal. 1233 func PackageList(roots []*Package) []*Package { 1234 seen := map[*Package]bool{} 1235 all := []*Package{} 1236 var walk func(*Package) 1237 walk = func(p *Package) { 1238 if seen[p] { 1239 return 1240 } 1241 seen[p] = true 1242 for _, p1 := range p.Internal.Imports { 1243 walk(p1) 1244 } 1245 all = append(all, p) 1246 } 1247 for _, root := range roots { 1248 walk(root) 1249 } 1250 return all 1251 } 1252 1253 var cmdCache = map[string]*Package{} 1254 1255 func ClearCmdCache() { 1256 for name := range cmdCache { 1257 delete(cmdCache, name) 1258 } 1259 } 1260 1261 // loadPackage is like loadImport but is used for command-line arguments, 1262 // not for paths found in import statements. In addition to ordinary import paths, 1263 // loadPackage accepts pseudo-paths beginning with cmd/ to denote commands 1264 // in the Go command directory, as well as paths to those directories. 1265 func LoadPackage(arg string, stk *ImportStack) *Package { 1266 if build.IsLocalImport(arg) { 1267 dir := arg 1268 if !filepath.IsAbs(dir) { 1269 if abs, err := filepath.Abs(dir); err == nil { 1270 // interpret relative to current directory 1271 dir = abs 1272 } 1273 } 1274 if sub, ok := hasSubdir(cfg.GOROOTsrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") { 1275 arg = sub 1276 } 1277 } 1278 if strings.HasPrefix(arg, "cmd/") && !strings.Contains(arg[4:], "/") { 1279 if p := cmdCache[arg]; p != nil { 1280 return p 1281 } 1282 stk.Push(arg) 1283 defer stk.Pop() 1284 1285 bp, err := cfg.BuildContext.ImportDir(filepath.Join(cfg.GOROOTsrc, arg), 0) 1286 bp.ImportPath = arg 1287 bp.Goroot = true 1288 bp.BinDir = cfg.GOROOTbin 1289 if cfg.GOROOTbin != "" { 1290 bp.BinDir = cfg.GOROOTbin 1291 } 1292 bp.Root = cfg.GOROOT 1293 bp.SrcRoot = cfg.GOROOTsrc 1294 p := new(Package) 1295 cmdCache[arg] = p 1296 p.load(stk, bp, err) 1297 if p.Error == nil && p.Name != "main" { 1298 p.Error = &PackageError{ 1299 ImportStack: stk.Copy(), 1300 Err: fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir), 1301 } 1302 } 1303 return p 1304 } 1305 1306 // Wasn't a command; must be a package. 1307 // If it is a local import path but names a standard package, 1308 // we treat it as if the user specified the standard package. 1309 // This lets you run go test ./ioutil in package io and be 1310 // referring to io/ioutil rather than a hypothetical import of 1311 // "./ioutil". 1312 if build.IsLocalImport(arg) { 1313 bp, _ := cfg.BuildContext.ImportDir(filepath.Join(base.Cwd, arg), build.FindOnly) 1314 if bp.ImportPath != "" && bp.ImportPath != "." { 1315 arg = bp.ImportPath 1316 } 1317 } 1318 1319 return LoadImport(arg, base.Cwd, nil, stk, nil, 0) 1320 } 1321 1322 // packages returns the packages named by the 1323 // command line arguments 'args'. If a named package 1324 // cannot be loaded at all (for example, if the directory does not exist), 1325 // then packages prints an error and does not include that 1326 // package in the results. However, if errors occur trying 1327 // to load dependencies of a named package, the named 1328 // package is still returned, with p.Incomplete = true 1329 // and details in p.DepsErrors. 1330 func Packages(args []string) []*Package { 1331 var pkgs []*Package 1332 for _, pkg := range PackagesAndErrors(args) { 1333 if pkg.Error != nil { 1334 base.Errorf("can't load package: %s", pkg.Error) 1335 continue 1336 } 1337 pkgs = append(pkgs, pkg) 1338 } 1339 return pkgs 1340 } 1341 1342 // packagesAndErrors is like 'packages' but returns a 1343 // *Package for every argument, even the ones that 1344 // cannot be loaded at all. 1345 // The packages that fail to load will have p.Error != nil. 1346 func PackagesAndErrors(args []string) []*Package { 1347 if len(args) > 0 && strings.HasSuffix(args[0], ".go") { 1348 return []*Package{GoFilesPackage(args)} 1349 } 1350 1351 args = ImportPaths(args) 1352 var ( 1353 pkgs []*Package 1354 stk ImportStack 1355 seenArg = make(map[string]bool) 1356 seenPkg = make(map[*Package]bool) 1357 ) 1358 1359 for _, arg := range args { 1360 if seenArg[arg] { 1361 continue 1362 } 1363 seenArg[arg] = true 1364 pkg := LoadPackage(arg, &stk) 1365 if seenPkg[pkg] { 1366 continue 1367 } 1368 seenPkg[pkg] = true 1369 pkgs = append(pkgs, pkg) 1370 } 1371 1372 return pkgs 1373 } 1374 1375 // packagesForBuild is like 'packages' but fails if any of 1376 // the packages or their dependencies have errors 1377 // (cannot be built). 1378 func PackagesForBuild(args []string) []*Package { 1379 pkgs := PackagesAndErrors(args) 1380 printed := map[*PackageError]bool{} 1381 for _, pkg := range pkgs { 1382 if pkg.Error != nil { 1383 base.Errorf("can't load package: %s", pkg.Error) 1384 } 1385 for _, err := range pkg.DepsErrors { 1386 // Since these are errors in dependencies, 1387 // the same error might show up multiple times, 1388 // once in each package that depends on it. 1389 // Only print each once. 1390 if !printed[err] { 1391 printed[err] = true 1392 base.Errorf("%s", err) 1393 } 1394 } 1395 } 1396 base.ExitIfErrors() 1397 1398 // Check for duplicate loads of the same package. 1399 // That should be impossible, but if it does happen then 1400 // we end up trying to build the same package twice, 1401 // usually in parallel overwriting the same files, 1402 // which doesn't work very well. 1403 seen := map[string]bool{} 1404 reported := map[string]bool{} 1405 for _, pkg := range PackageList(pkgs) { 1406 if seen[pkg.ImportPath] && !reported[pkg.ImportPath] { 1407 reported[pkg.ImportPath] = true 1408 base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath) 1409 } 1410 seen[pkg.ImportPath] = true 1411 } 1412 base.ExitIfErrors() 1413 1414 return pkgs 1415 } 1416 1417 // GoFilesPackage creates a package for building a collection of Go files 1418 // (typically named on the command line). The target is named p.a for 1419 // package p or named after the first Go file for package main. 1420 func GoFilesPackage(gofiles []string) *Package { 1421 // TODO: Remove this restriction. 1422 for _, f := range gofiles { 1423 if !strings.HasSuffix(f, ".go") { 1424 base.Fatalf("named files must be .go files") 1425 } 1426 } 1427 1428 var stk ImportStack 1429 ctxt := cfg.BuildContext 1430 ctxt.UseAllFiles = true 1431 1432 // Synthesize fake "directory" that only shows the named files, 1433 // to make it look like this is a standard package or 1434 // command directory. So that local imports resolve 1435 // consistently, the files must all be in the same directory. 1436 var dirent []os.FileInfo 1437 var dir string 1438 for _, file := range gofiles { 1439 fi, err := os.Stat(file) 1440 if err != nil { 1441 base.Fatalf("%s", err) 1442 } 1443 if fi.IsDir() { 1444 base.Fatalf("%s is a directory, should be a Go file", file) 1445 } 1446 dir1, _ := filepath.Split(file) 1447 if dir1 == "" { 1448 dir1 = "./" 1449 } 1450 if dir == "" { 1451 dir = dir1 1452 } else if dir != dir1 { 1453 base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1) 1454 } 1455 dirent = append(dirent, fi) 1456 } 1457 ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil } 1458 1459 var err error 1460 if dir == "" { 1461 dir = base.Cwd 1462 } 1463 dir, err = filepath.Abs(dir) 1464 if err != nil { 1465 base.Fatalf("%s", err) 1466 } 1467 1468 bp, err := ctxt.ImportDir(dir, 0) 1469 pkg := new(Package) 1470 pkg.Internal.Local = true 1471 pkg.Internal.CmdlineFiles = true 1472 stk.Push("main") 1473 pkg.load(&stk, bp, err) 1474 stk.Pop() 1475 pkg.Internal.LocalPrefix = dirToImportPath(dir) 1476 pkg.ImportPath = "command-line-arguments" 1477 pkg.Target = "" 1478 1479 if pkg.Name == "main" { 1480 _, elem := filepath.Split(gofiles[0]) 1481 exe := elem[:len(elem)-len(".go")] + cfg.ExeSuffix 1482 if cfg.BuildO == "" { 1483 cfg.BuildO = exe 1484 } 1485 if cfg.GOBIN != "" { 1486 pkg.Target = filepath.Join(cfg.GOBIN, exe) 1487 } 1488 } 1489 1490 return pkg 1491 }