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