github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/src/cmd/go/pkg.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "bytes" 9 "crypto/sha1" 10 "errors" 11 "fmt" 12 "go/build" 13 "go/scanner" 14 "go/token" 15 "io" 16 "io/ioutil" 17 "os" 18 pathpkg "path" 19 "path/filepath" 20 "runtime" 21 "sort" 22 "strconv" 23 "strings" 24 "unicode" 25 ) 26 27 // A Package describes a single package found in a directory. 28 type Package struct { 29 // Note: These fields are part of the go command's public API. 30 // See list.go. It is okay to add fields, but not to change or 31 // remove existing ones. Keep in sync with list.go 32 Dir string `json:",omitempty"` // directory containing package sources 33 ImportPath string `json:",omitempty"` // import path of package in dir 34 ImportComment string `json:",omitempty"` // path in import comment on package statement 35 Name string `json:",omitempty"` // package name 36 Doc string `json:",omitempty"` // package documentation string 37 Target string `json:",omitempty"` // install path 38 Shlib string `json:",omitempty"` // the shared library that contains this package (only set when -linkshared) 39 Goroot bool `json:",omitempty"` // is this package found in the Go root? 40 Standard bool `json:",omitempty"` // is this package part of the standard Go library? 41 Stale bool `json:",omitempty"` // would 'go install' do anything for this package? 42 Root string `json:",omitempty"` // Go root or Go path dir containing this package 43 ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory 44 45 // Source files 46 GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) 47 CgoFiles []string `json:",omitempty"` // .go sources files that import "C" 48 IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints 49 CFiles []string `json:",omitempty"` // .c source files 50 CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files 51 MFiles []string `json:",omitempty"` // .m source files 52 HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files 53 SFiles []string `json:",omitempty"` // .s source files 54 SwigFiles []string `json:",omitempty"` // .swig files 55 SwigCXXFiles []string `json:",omitempty"` // .swigcxx files 56 SysoFiles []string `json:",omitempty"` // .syso system object files added to package 57 58 // Cgo directives 59 CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler 60 CgoCPPFLAGS []string `json:",omitempty"` // cgo: flags for C preprocessor 61 CgoCXXFLAGS []string `json:",omitempty"` // cgo: flags for C++ compiler 62 CgoLDFLAGS []string `json:",omitempty"` // cgo: flags for linker 63 CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names 64 65 // Dependency information 66 Imports []string `json:",omitempty"` // import paths used by this package 67 Deps []string `json:",omitempty"` // all (recursively) imported dependencies 68 69 // Error information 70 Incomplete bool `json:",omitempty"` // was there an error loading this package or dependencies? 71 Error *PackageError `json:",omitempty"` // error loading this package (not dependencies) 72 DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies 73 74 // Test information 75 TestGoFiles []string `json:",omitempty"` // _test.go files in package 76 TestImports []string `json:",omitempty"` // imports from TestGoFiles 77 XTestGoFiles []string `json:",omitempty"` // _test.go files outside package 78 XTestImports []string `json:",omitempty"` // imports from XTestGoFiles 79 80 // Unexported fields are not part of the public API. 81 build *build.Package 82 pkgdir string // overrides build.PkgDir 83 imports []*Package 84 deps []*Package 85 gofiles []string // GoFiles+CgoFiles+TestGoFiles+XTestGoFiles files, absolute paths 86 sfiles []string 87 allgofiles []string // gofiles + IgnoredGoFiles, absolute paths 88 target string // installed file for this package (may be executable) 89 fake bool // synthesized package 90 external bool // synthesized external test package 91 forceBuild bool // this package must be rebuilt 92 forceLibrary bool // this package is a library (even if named "main") 93 cmdline bool // defined by files listed on command line 94 local bool // imported via local path (./ or ../) 95 localPrefix string // interpret ./ and ../ imports relative to this prefix 96 exeName string // desired name for temporary executable 97 coverMode string // preprocess Go source files with the coverage tool in this mode 98 coverVars map[string]*CoverVar // variables created by coverage analysis 99 omitDWARF bool // tell linker not to write DWARF information 100 buildID string // expected build ID for generated package 101 gobinSubdir bool // install target would be subdir of GOBIN 102 } 103 104 // vendored returns the vendor-resolved version of imports, 105 // which should be p.TestImports or p.XTestImports, NOT p.Imports. 106 // The imports in p.TestImports and p.XTestImports are not recursively 107 // loaded during the initial load of p, so they list the imports found in 108 // the source file, but most processing should be over the vendor-resolved 109 // import paths. We do this resolution lazily both to avoid file system work 110 // and because the eventual real load of the test imports (during 'go test') 111 // can produce better error messages if it starts with the original paths. 112 // The initial load of p loads all the non-test imports and rewrites 113 // the vendored paths, so nothing should ever call p.vendored(p.Imports). 114 func (p *Package) vendored(imports []string) []string { 115 if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] { 116 panic("internal error: p.vendored(p.Imports) called") 117 } 118 seen := make(map[string]bool) 119 var all []string 120 for _, path := range imports { 121 path, _ = vendoredImportPath(p, path) 122 if !seen[path] { 123 seen[path] = true 124 all = append(all, path) 125 } 126 } 127 sort.Strings(all) 128 return all 129 } 130 131 // CoverVar holds the name of the generated coverage variables targeting the named file. 132 type CoverVar struct { 133 File string // local file name 134 Var string // name of count struct 135 } 136 137 func (p *Package) copyBuild(pp *build.Package) { 138 p.build = pp 139 140 if pp.PkgTargetRoot != "" && buildPkgdir != "" { 141 old := pp.PkgTargetRoot 142 pp.PkgRoot = buildPkgdir 143 pp.PkgTargetRoot = buildPkgdir 144 pp.PkgObj = filepath.Join(buildPkgdir, strings.TrimPrefix(pp.PkgObj, old)) 145 } 146 147 p.Dir = pp.Dir 148 p.ImportPath = pp.ImportPath 149 p.ImportComment = pp.ImportComment 150 p.Name = pp.Name 151 p.Doc = pp.Doc 152 p.Root = pp.Root 153 p.ConflictDir = pp.ConflictDir 154 // TODO? Target 155 p.Goroot = pp.Goroot 156 p.Standard = p.Goroot && p.ImportPath != "" && !strings.Contains(p.ImportPath, ".") 157 p.GoFiles = pp.GoFiles 158 p.CgoFiles = pp.CgoFiles 159 p.IgnoredGoFiles = pp.IgnoredGoFiles 160 p.CFiles = pp.CFiles 161 p.CXXFiles = pp.CXXFiles 162 p.MFiles = pp.MFiles 163 p.HFiles = pp.HFiles 164 p.SFiles = pp.SFiles 165 p.SwigFiles = pp.SwigFiles 166 p.SwigCXXFiles = pp.SwigCXXFiles 167 p.SysoFiles = pp.SysoFiles 168 p.CgoCFLAGS = pp.CgoCFLAGS 169 p.CgoCPPFLAGS = pp.CgoCPPFLAGS 170 p.CgoCXXFLAGS = pp.CgoCXXFLAGS 171 p.CgoLDFLAGS = pp.CgoLDFLAGS 172 p.CgoPkgConfig = pp.CgoPkgConfig 173 p.Imports = pp.Imports 174 p.TestGoFiles = pp.TestGoFiles 175 p.TestImports = pp.TestImports 176 p.XTestGoFiles = pp.XTestGoFiles 177 p.XTestImports = pp.XTestImports 178 } 179 180 // A PackageError describes an error loading information about a package. 181 type PackageError struct { 182 ImportStack []string // shortest path from package named on command line to this one 183 Pos string // position of error 184 Err string // the error itself 185 isImportCycle bool // the error is an import cycle 186 hard bool // whether the error is soft or hard; soft errors are ignored in some places 187 } 188 189 func (p *PackageError) Error() string { 190 // Import cycles deserve special treatment. 191 if p.isImportCycle { 192 return fmt.Sprintf("%s\npackage %s\n", p.Err, strings.Join(p.ImportStack, "\n\timports ")) 193 } 194 if p.Pos != "" { 195 // Omit import stack. The full path to the file where the error 196 // is the most important thing. 197 return p.Pos + ": " + p.Err 198 } 199 if len(p.ImportStack) == 0 { 200 return p.Err 201 } 202 return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err 203 } 204 205 // An importStack is a stack of import paths. 206 type importStack []string 207 208 func (s *importStack) push(p string) { 209 *s = append(*s, p) 210 } 211 212 func (s *importStack) pop() { 213 *s = (*s)[0 : len(*s)-1] 214 } 215 216 func (s *importStack) copy() []string { 217 return append([]string{}, *s...) 218 } 219 220 // shorterThan reports whether sp is shorter than t. 221 // We use this to record the shortest import sequence 222 // that leads to a particular package. 223 func (sp *importStack) shorterThan(t []string) bool { 224 s := *sp 225 if len(s) != len(t) { 226 return len(s) < len(t) 227 } 228 // If they are the same length, settle ties using string ordering. 229 for i := range s { 230 if s[i] != t[i] { 231 return s[i] < t[i] 232 } 233 } 234 return false // they are equal 235 } 236 237 // packageCache is a lookup cache for loadPackage, 238 // so that if we look up a package multiple times 239 // we return the same pointer each time. 240 var packageCache = map[string]*Package{} 241 242 // reloadPackage is like loadPackage but makes sure 243 // not to use the package cache. 244 func reloadPackage(arg string, stk *importStack) *Package { 245 p := packageCache[arg] 246 if p != nil { 247 delete(packageCache, p.Dir) 248 delete(packageCache, p.ImportPath) 249 } 250 return loadPackage(arg, stk) 251 } 252 253 // The Go 1.5 vendoring experiment was enabled by setting GO15VENDOREXPERIMENT=1. 254 // In Go 1.6 this is on by default and is disabled by setting GO15VENDOREXPERIMENT=0. 255 // In Go 1.7 the variable will stop having any effect. 256 // The variable is obnoxiously long so that years from now when people find it in 257 // their profiles and wonder what it does, there is some chance that a web search 258 // might answer the question. 259 var go15VendorExperiment = os.Getenv("GO15VENDOREXPERIMENT") != "0" 260 261 // dirToImportPath returns the pseudo-import path we use for a package 262 // outside the Go path. It begins with _/ and then contains the full path 263 // to the directory. If the package lives in c:\home\gopher\my\pkg then 264 // the pseudo-import path is _/c_/home/gopher/my/pkg. 265 // Using a pseudo-import path like this makes the ./ imports no longer 266 // a special case, so that all the code to deal with ordinary imports works 267 // automatically. 268 func dirToImportPath(dir string) string { 269 return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir))) 270 } 271 272 func makeImportValid(r rune) rune { 273 // Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport. 274 const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" 275 if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { 276 return '_' 277 } 278 return r 279 } 280 281 // Mode flags for loadImport and download (in get.go). 282 const ( 283 // useVendor means that loadImport should do vendor expansion 284 // (provided the vendoring experiment is enabled). 285 // That is, useVendor means that the import path came from 286 // a source file and has not been vendor-expanded yet. 287 // Every import path should be loaded initially with useVendor, 288 // and then the expanded version (with the /vendor/ in it) gets 289 // recorded as the canonical import path. At that point, future loads 290 // of that package must not pass useVendor, because 291 // disallowVendor will reject direct use of paths containing /vendor/. 292 useVendor = 1 << iota 293 294 // getTestDeps is for download (part of "go get") and indicates 295 // that test dependencies should be fetched too. 296 getTestDeps 297 ) 298 299 // loadImport scans the directory named by path, which must be an import path, 300 // but possibly a local import path (an absolute file system path or one beginning 301 // with ./ or ../). A local relative path is interpreted relative to srcDir. 302 // It returns a *Package describing the package found in that directory. 303 func loadImport(path, srcDir string, parent *Package, stk *importStack, importPos []token.Position, mode int) *Package { 304 stk.push(path) 305 defer stk.pop() 306 307 // Determine canonical identifier for this package. 308 // For a local import the identifier is the pseudo-import path 309 // we create from the full directory to the package. 310 // Otherwise it is the usual import path. 311 // For vendored imports, it is the expanded form. 312 importPath := path 313 origPath := path 314 isLocal := build.IsLocalImport(path) 315 var vendorSearch []string 316 if isLocal { 317 importPath = dirToImportPath(filepath.Join(srcDir, path)) 318 } else if mode&useVendor != 0 { 319 path, vendorSearch = vendoredImportPath(parent, path) 320 importPath = path 321 } 322 323 if p := packageCache[importPath]; p != nil { 324 if perr := disallowInternal(srcDir, p, stk); perr != p { 325 return perr 326 } 327 if mode&useVendor != 0 { 328 if perr := disallowVendor(srcDir, origPath, p, stk); perr != p { 329 return perr 330 } 331 } 332 return reusePackage(p, stk) 333 } 334 335 p := new(Package) 336 p.local = isLocal 337 p.ImportPath = importPath 338 packageCache[importPath] = p 339 340 // Load package. 341 // Import always returns bp != nil, even if an error occurs, 342 // in order to return partial information. 343 // 344 // TODO: After Go 1, decide when to pass build.AllowBinary here. 345 // See issue 3268 for mistakes to avoid. 346 bp, err := buildContext.Import(path, srcDir, build.ImportComment) 347 348 // If we got an error from go/build about package not found, 349 // it contains the directories from $GOROOT and $GOPATH that 350 // were searched. Add to that message the vendor directories 351 // that were searched. 352 if err != nil && len(vendorSearch) > 0 { 353 // NOTE(rsc): The direct text manipulation here is fairly awful, 354 // but it avoids defining new go/build API (an exported error type) 355 // late in the Go 1.5 release cycle. If this turns out to be a more general 356 // problem we could define a real error type when the decision can be 357 // considered more carefully. 358 text := err.Error() 359 if strings.Contains(text, "cannot find package \"") && strings.Contains(text, "\" in any of:\n\t") { 360 old := strings.SplitAfter(text, "\n") 361 lines := []string{old[0]} 362 for _, dir := range vendorSearch { 363 lines = append(lines, "\t"+dir+" (vendor tree)\n") 364 } 365 lines = append(lines, old[1:]...) 366 err = errors.New(strings.Join(lines, "")) 367 } 368 } 369 bp.ImportPath = importPath 370 if gobin != "" { 371 bp.BinDir = gobin 372 } 373 if err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path && 374 (!go15VendorExperiment || (!strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/"))) { 375 err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment) 376 } 377 p.load(stk, bp, err) 378 if p.Error != nil && len(importPos) > 0 { 379 pos := importPos[0] 380 pos.Filename = shortPath(pos.Filename) 381 p.Error.Pos = pos.String() 382 } 383 384 if perr := disallowInternal(srcDir, p, stk); perr != p { 385 return perr 386 } 387 if mode&useVendor != 0 { 388 if perr := disallowVendor(srcDir, origPath, p, stk); perr != p { 389 return perr 390 } 391 } 392 393 return p 394 } 395 396 var isDirCache = map[string]bool{} 397 398 func isDir(path string) bool { 399 result, ok := isDirCache[path] 400 if ok { 401 return result 402 } 403 404 fi, err := os.Stat(path) 405 result = err == nil && fi.IsDir() 406 isDirCache[path] = result 407 return result 408 } 409 410 // vendoredImportPath returns the expansion of path when it appears in parent. 411 // If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path, 412 // x/vendor/path, vendor/path, or else stay path if none of those exist. 413 // vendoredImportPath returns the expanded path or, if no expansion is found, the original. 414 // If no expansion is found, vendoredImportPath also returns a list of vendor directories 415 // it searched along the way, to help prepare a useful error message should path turn 416 // out not to exist. 417 func vendoredImportPath(parent *Package, path string) (found string, searched []string) { 418 if parent == nil || parent.Root == "" || !go15VendorExperiment { 419 return path, nil 420 } 421 dir := filepath.Clean(parent.Dir) 422 root := filepath.Join(parent.Root, "src") 423 if !hasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator { 424 fatalf("invalid vendoredImportPath: dir=%q root=%q separator=%q", dir, root, string(filepath.Separator)) 425 } 426 vpath := "vendor/" + path 427 for i := len(dir); i >= len(root); i-- { 428 if i < len(dir) && dir[i] != filepath.Separator { 429 continue 430 } 431 // Note: checking for the vendor directory before checking 432 // for the vendor/path directory helps us hit the 433 // isDir cache more often. It also helps us prepare a more useful 434 // list of places we looked, to report when an import is not found. 435 if !isDir(filepath.Join(dir[:i], "vendor")) { 436 continue 437 } 438 targ := filepath.Join(dir[:i], vpath) 439 if isDir(targ) { 440 // We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy. 441 // We know the import path for parent's dir. 442 // We chopped off some number of path elements and 443 // added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path. 444 // Now we want to know the import path for that directory. 445 // Construct it by chopping the same number of path elements 446 // (actually the same number of bytes) from parent's import path 447 // and then append /vendor/path. 448 chopped := len(dir) - i 449 if chopped == len(parent.ImportPath)+1 { 450 // We walked up from c:\gopath\src\foo\bar 451 // and found c:\gopath\src\vendor\path. 452 // We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7). 453 // Use "vendor/path" without any prefix. 454 return vpath, nil 455 } 456 return parent.ImportPath[:len(parent.ImportPath)-chopped] + "/" + vpath, nil 457 } 458 // Note the existence of a vendor directory in case path is not found anywhere. 459 searched = append(searched, targ) 460 } 461 return path, searched 462 } 463 464 // reusePackage reuses package p to satisfy the import at the top 465 // of the import stack stk. If this use causes an import loop, 466 // reusePackage updates p's error information to record the loop. 467 func reusePackage(p *Package, stk *importStack) *Package { 468 // We use p.imports==nil to detect a package that 469 // is in the midst of its own loadPackage call 470 // (all the recursion below happens before p.imports gets set). 471 if p.imports == nil { 472 if p.Error == nil { 473 p.Error = &PackageError{ 474 ImportStack: stk.copy(), 475 Err: "import cycle not allowed", 476 isImportCycle: true, 477 } 478 } 479 p.Incomplete = true 480 } 481 // Don't rewrite the import stack in the error if we have an import cycle. 482 // If we do, we'll lose the path that describes the cycle. 483 if p.Error != nil && !p.Error.isImportCycle && stk.shorterThan(p.Error.ImportStack) { 484 p.Error.ImportStack = stk.copy() 485 } 486 return p 487 } 488 489 // disallowInternal checks that srcDir is allowed to import p. 490 // If the import is allowed, disallowInternal returns the original package p. 491 // If not, it returns a new package containing just an appropriate error. 492 func disallowInternal(srcDir string, p *Package, stk *importStack) *Package { 493 // golang.org/s/go14internal: 494 // An import of a path containing the element “internal” 495 // is disallowed if the importing code is outside the tree 496 // rooted at the parent of the “internal” directory. 497 498 // There was an error loading the package; stop here. 499 if p.Error != nil { 500 return p 501 } 502 503 // The stack includes p.ImportPath. 504 // If that's the only thing on the stack, we started 505 // with a name given on the command line, not an 506 // import. Anything listed on the command line is fine. 507 if len(*stk) == 1 { 508 return p 509 } 510 511 // Check for "internal" element: four cases depending on begin of string and/or end of string. 512 i, ok := findInternal(p.ImportPath) 513 if !ok { 514 return p 515 } 516 517 // Internal is present. 518 // Map import path back to directory corresponding to parent of internal. 519 if i > 0 { 520 i-- // rewind over slash in ".../internal" 521 } 522 parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)] 523 if hasPathPrefix(filepath.ToSlash(srcDir), filepath.ToSlash(parent)) { 524 return p 525 } 526 527 // Internal is present, and srcDir is outside parent's tree. Not allowed. 528 perr := *p 529 perr.Error = &PackageError{ 530 ImportStack: stk.copy(), 531 Err: "use of internal package not allowed", 532 } 533 perr.Incomplete = true 534 return &perr 535 } 536 537 // findInternal looks for the final "internal" path element in the given import path. 538 // If there isn't one, findInternal returns ok=false. 539 // Otherwise, findInternal returns ok=true and the index of the "internal". 540 func findInternal(path string) (index int, ok bool) { 541 // Four cases, depending on internal at start/end of string or not. 542 // The order matters: we must return the index of the final element, 543 // because the final one produces the most restrictive requirement 544 // on the importer. 545 switch { 546 case strings.HasSuffix(path, "/internal"): 547 return len(path) - len("internal"), true 548 case strings.Contains(path, "/internal/"): 549 return strings.LastIndex(path, "/internal/") + 1, true 550 case path == "internal", strings.HasPrefix(path, "internal/"): 551 return 0, true 552 } 553 return 0, false 554 } 555 556 // disallowVendor checks that srcDir is allowed to import p as path. 557 // If the import is allowed, disallowVendor returns the original package p. 558 // If not, it returns a new package containing just an appropriate error. 559 func disallowVendor(srcDir, path string, p *Package, stk *importStack) *Package { 560 if !go15VendorExperiment { 561 return p 562 } 563 564 // The stack includes p.ImportPath. 565 // If that's the only thing on the stack, we started 566 // with a name given on the command line, not an 567 // import. Anything listed on the command line is fine. 568 if len(*stk) == 1 { 569 return p 570 } 571 572 if perr := disallowVendorVisibility(srcDir, p, stk); perr != p { 573 return perr 574 } 575 576 // Paths like x/vendor/y must be imported as y, never as x/vendor/y. 577 if i, ok := findVendor(path); ok { 578 perr := *p 579 perr.Error = &PackageError{ 580 ImportStack: stk.copy(), 581 Err: "must be imported as " + path[i+len("vendor/"):], 582 } 583 perr.Incomplete = true 584 return &perr 585 } 586 587 return p 588 } 589 590 // disallowVendorVisibility checks that srcDir is allowed to import p. 591 // The rules are the same as for /internal/ except that a path ending in /vendor 592 // is not subject to the rules, only subdirectories of vendor. 593 // This allows people to have packages and commands named vendor, 594 // for maximal compatibility with existing source trees. 595 func disallowVendorVisibility(srcDir string, p *Package, stk *importStack) *Package { 596 // The stack includes p.ImportPath. 597 // If that's the only thing on the stack, we started 598 // with a name given on the command line, not an 599 // import. Anything listed on the command line is fine. 600 if len(*stk) == 1 { 601 return p 602 } 603 604 // Check for "vendor" element. 605 i, ok := findVendor(p.ImportPath) 606 if !ok { 607 return p 608 } 609 610 // Vendor is present. 611 // Map import path back to directory corresponding to parent of vendor. 612 if i > 0 { 613 i-- // rewind over slash in ".../vendor" 614 } 615 truncateTo := i + len(p.Dir) - len(p.ImportPath) 616 if truncateTo < 0 || len(p.Dir) < truncateTo { 617 return p 618 } 619 parent := p.Dir[:truncateTo] 620 if hasPathPrefix(filepath.ToSlash(srcDir), filepath.ToSlash(parent)) { 621 return p 622 } 623 624 // Vendor is present, and srcDir is outside parent's tree. Not allowed. 625 perr := *p 626 perr.Error = &PackageError{ 627 ImportStack: stk.copy(), 628 Err: "use of vendored package not allowed", 629 } 630 perr.Incomplete = true 631 return &perr 632 } 633 634 // findVendor looks for the last non-terminating "vendor" path element in the given import path. 635 // If there isn't one, findVendor returns ok=false. 636 // Otherwise, findInternal returns ok=true and the index of the "vendor". 637 // 638 // Note that terminating "vendor" elements don't count: "x/vendor" is its own package, 639 // not the vendored copy of an import "" (the empty import path). 640 // This will allow people to have packages or commands named vendor. 641 // This may help reduce breakage, or it may just be confusing. We'll see. 642 func findVendor(path string) (index int, ok bool) { 643 // Two cases, depending on internal at start of string or not. 644 // The order matters: we must return the index of the final element, 645 // because the final one is where the effective import path starts. 646 switch { 647 case strings.Contains(path, "/vendor/"): 648 return strings.LastIndex(path, "/vendor/") + 1, true 649 case strings.HasPrefix(path, "vendor/"): 650 return 0, true 651 } 652 return 0, false 653 } 654 655 type targetDir int 656 657 const ( 658 toRoot targetDir = iota // to bin dir inside package root (default) 659 toTool // GOROOT/pkg/tool 660 toBin // GOROOT/bin 661 stalePath // the old import path; fail to build 662 ) 663 664 // goTools is a map of Go program import path to install target directory. 665 var goTools = map[string]targetDir{ 666 "cmd/addr2line": toTool, 667 "cmd/api": toTool, 668 "cmd/asm": toTool, 669 "cmd/compile": toTool, 670 "cmd/cgo": toTool, 671 "cmd/cover": toTool, 672 "cmd/dist": toTool, 673 "cmd/doc": toTool, 674 "cmd/fix": toTool, 675 "cmd/link": toTool, 676 "cmd/newlink": toTool, 677 "cmd/nm": toTool, 678 "cmd/objdump": toTool, 679 "cmd/pack": toTool, 680 "cmd/pprof": toTool, 681 "cmd/trace": toTool, 682 "cmd/vet": toTool, 683 "cmd/yacc": toTool, 684 "golang.org/x/tools/cmd/godoc": toBin, 685 "code.google.com/p/go.tools/cmd/cover": stalePath, 686 "code.google.com/p/go.tools/cmd/godoc": stalePath, 687 "code.google.com/p/go.tools/cmd/vet": stalePath, 688 } 689 690 // expandScanner expands a scanner.List error into all the errors in the list. 691 // The default Error method only shows the first error. 692 func expandScanner(err error) error { 693 // Look for parser errors. 694 if err, ok := err.(scanner.ErrorList); ok { 695 // Prepare error with \n before each message. 696 // When printed in something like context: %v 697 // this will put the leading file positions each on 698 // its own line. It will also show all the errors 699 // instead of just the first, as err.Error does. 700 var buf bytes.Buffer 701 for _, e := range err { 702 e.Pos.Filename = shortPath(e.Pos.Filename) 703 buf.WriteString("\n") 704 buf.WriteString(e.Error()) 705 } 706 return errors.New(buf.String()) 707 } 708 return err 709 } 710 711 var raceExclude = map[string]bool{ 712 "runtime/race": true, 713 "runtime/msan": true, 714 "runtime/cgo": true, 715 "cmd/cgo": true, 716 "syscall": true, 717 "errors": true, 718 } 719 720 var cgoExclude = map[string]bool{ 721 "runtime/cgo": true, 722 } 723 724 var cgoSyscallExclude = map[string]bool{ 725 "runtime/cgo": true, 726 "runtime/race": true, 727 "runtime/msan": true, 728 } 729 730 // load populates p using information from bp, err, which should 731 // be the result of calling build.Context.Import. 732 func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package { 733 p.copyBuild(bp) 734 735 // The localPrefix is the path we interpret ./ imports relative to. 736 // Synthesized main packages sometimes override this. 737 p.localPrefix = dirToImportPath(p.Dir) 738 739 if err != nil { 740 p.Incomplete = true 741 err = expandScanner(err) 742 p.Error = &PackageError{ 743 ImportStack: stk.copy(), 744 Err: err.Error(), 745 } 746 return p 747 } 748 749 useBindir := p.Name == "main" 750 if !p.Standard { 751 switch buildBuildmode { 752 case "c-archive", "c-shared": 753 useBindir = false 754 } 755 } 756 757 if useBindir { 758 // Report an error when the old code.google.com/p/go.tools paths are used. 759 if goTools[p.ImportPath] == stalePath { 760 newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1) 761 e := fmt.Sprintf("the %v command has moved; use %v instead.", p.ImportPath, newPath) 762 p.Error = &PackageError{Err: e} 763 return p 764 } 765 _, elem := filepath.Split(p.Dir) 766 full := buildContext.GOOS + "_" + buildContext.GOARCH + "/" + elem 767 if buildContext.GOOS != toolGOOS || buildContext.GOARCH != toolGOARCH { 768 // Install cross-compiled binaries to subdirectories of bin. 769 elem = full 770 } 771 if p.build.BinDir != gobin && goTools[p.ImportPath] == toBin { 772 // Override BinDir. 773 // This is from a subrepo but installs to $GOROOT/bin 774 // by default anyway (like godoc). 775 p.target = filepath.Join(gorootBin, elem) 776 } else if p.build.BinDir != "" { 777 // Install to GOBIN or bin of GOPATH entry. 778 p.target = filepath.Join(p.build.BinDir, elem) 779 if !p.Goroot && strings.Contains(elem, "/") && gobin != "" { 780 // Do not create $GOBIN/goos_goarch/elem. 781 p.target = "" 782 p.gobinSubdir = true 783 } 784 } 785 if goTools[p.ImportPath] == toTool { 786 // This is for 'go tool'. 787 // Override all the usual logic and force it into the tool directory. 788 p.target = filepath.Join(gorootPkg, "tool", full) 789 } 790 if p.target != "" && buildContext.GOOS == "windows" { 791 p.target += ".exe" 792 } 793 } else if p.local { 794 // Local import turned into absolute path. 795 // No permanent install target. 796 p.target = "" 797 } else { 798 p.target = p.build.PkgObj 799 if buildLinkshared { 800 shlibnamefile := p.target[:len(p.target)-2] + ".shlibname" 801 shlib, err := ioutil.ReadFile(shlibnamefile) 802 if err == nil { 803 libname := strings.TrimSpace(string(shlib)) 804 if buildContext.Compiler == "gccgo" { 805 p.Shlib = filepath.Join(p.build.PkgTargetRoot, "shlibs", libname) 806 } else { 807 p.Shlib = filepath.Join(p.build.PkgTargetRoot, libname) 808 809 } 810 } else if !os.IsNotExist(err) { 811 fatalf("unexpected error reading %s: %v", shlibnamefile, err) 812 } 813 } 814 } 815 816 importPaths := p.Imports 817 // Packages that use cgo import runtime/cgo implicitly. 818 // Packages that use cgo also import syscall implicitly, 819 // to wrap errno. 820 // Exclude certain packages to avoid circular dependencies. 821 if len(p.CgoFiles) > 0 && (!p.Standard || !cgoExclude[p.ImportPath]) { 822 importPaths = append(importPaths, "runtime/cgo") 823 } 824 if len(p.CgoFiles) > 0 && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) { 825 importPaths = append(importPaths, "syscall") 826 } 827 828 // Currently build modes c-shared, pie, and -linkshared force 829 // external linking mode, and external linking mode forces an 830 // import of runtime/cgo. 831 if p.Name == "main" && !p.Goroot && (buildBuildmode == "c-shared" || buildBuildmode == "pie" || buildLinkshared) { 832 importPaths = append(importPaths, "runtime/cgo") 833 } 834 835 // Everything depends on runtime, except runtime, its internal 836 // subpackages, and unsafe. 837 if !p.Standard || (p.ImportPath != "runtime" && !strings.HasPrefix(p.ImportPath, "runtime/internal/") && p.ImportPath != "unsafe") { 838 importPaths = append(importPaths, "runtime") 839 // When race detection enabled everything depends on runtime/race. 840 // Exclude certain packages to avoid circular dependencies. 841 if buildRace && (!p.Standard || !raceExclude[p.ImportPath]) { 842 importPaths = append(importPaths, "runtime/race") 843 } 844 // MSan uses runtime/msan. 845 if buildMSan && (!p.Standard || !raceExclude[p.ImportPath]) { 846 importPaths = append(importPaths, "runtime/msan") 847 } 848 // On ARM with GOARM=5, everything depends on math for the link. 849 if p.Name == "main" && goarch == "arm" { 850 importPaths = append(importPaths, "math") 851 } 852 } 853 854 // Build list of full paths to all Go files in the package, 855 // for use by commands like go fmt. 856 p.gofiles = stringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles) 857 for i := range p.gofiles { 858 p.gofiles[i] = filepath.Join(p.Dir, p.gofiles[i]) 859 } 860 sort.Strings(p.gofiles) 861 862 p.sfiles = stringList(p.SFiles) 863 for i := range p.sfiles { 864 p.sfiles[i] = filepath.Join(p.Dir, p.sfiles[i]) 865 } 866 sort.Strings(p.sfiles) 867 868 p.allgofiles = stringList(p.IgnoredGoFiles) 869 for i := range p.allgofiles { 870 p.allgofiles[i] = filepath.Join(p.Dir, p.allgofiles[i]) 871 } 872 p.allgofiles = append(p.allgofiles, p.gofiles...) 873 sort.Strings(p.allgofiles) 874 875 // Check for case-insensitive collision of input files. 876 // To avoid problems on case-insensitive files, we reject any package 877 // where two different input files have equal names under a case-insensitive 878 // comparison. 879 f1, f2 := foldDup(stringList( 880 p.GoFiles, 881 p.CgoFiles, 882 p.IgnoredGoFiles, 883 p.CFiles, 884 p.CXXFiles, 885 p.MFiles, 886 p.HFiles, 887 p.SFiles, 888 p.SysoFiles, 889 p.SwigFiles, 890 p.SwigCXXFiles, 891 p.TestGoFiles, 892 p.XTestGoFiles, 893 )) 894 if f1 != "" { 895 p.Error = &PackageError{ 896 ImportStack: stk.copy(), 897 Err: fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2), 898 } 899 return p 900 } 901 902 // Build list of imported packages and full dependency list. 903 imports := make([]*Package, 0, len(p.Imports)) 904 deps := make(map[string]*Package) 905 for i, path := range importPaths { 906 if path == "C" { 907 continue 908 } 909 p1 := loadImport(path, p.Dir, p, stk, p.build.ImportPos[path], useVendor) 910 if p1.Name == "main" { 911 p.Error = &PackageError{ 912 ImportStack: stk.copy(), 913 Err: fmt.Sprintf("import %q is a program, not an importable package", path), 914 } 915 pos := p.build.ImportPos[path] 916 if len(pos) > 0 { 917 p.Error.Pos = pos[0].String() 918 } 919 } 920 if p1.local { 921 if !p.local && p.Error == nil { 922 p.Error = &PackageError{ 923 ImportStack: stk.copy(), 924 Err: fmt.Sprintf("local import %q in non-local package", path), 925 } 926 pos := p.build.ImportPos[path] 927 if len(pos) > 0 { 928 p.Error.Pos = pos[0].String() 929 } 930 } 931 } 932 path = p1.ImportPath 933 importPaths[i] = path 934 if i < len(p.Imports) { 935 p.Imports[i] = path 936 } 937 deps[path] = p1 938 imports = append(imports, p1) 939 for _, dep := range p1.deps { 940 // The same import path could produce an error or not, 941 // depending on what tries to import it. 942 // Prefer to record entries with errors, so we can report them. 943 if deps[dep.ImportPath] == nil || dep.Error != nil { 944 deps[dep.ImportPath] = dep 945 } 946 } 947 if p1.Incomplete { 948 p.Incomplete = true 949 } 950 } 951 p.imports = imports 952 953 p.Deps = make([]string, 0, len(deps)) 954 for dep := range deps { 955 p.Deps = append(p.Deps, dep) 956 } 957 sort.Strings(p.Deps) 958 for _, dep := range p.Deps { 959 p1 := deps[dep] 960 if p1 == nil { 961 panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath) 962 } 963 p.deps = append(p.deps, p1) 964 if p1.Error != nil { 965 p.DepsErrors = append(p.DepsErrors, p1.Error) 966 } 967 } 968 969 // unsafe is a fake package. 970 if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") { 971 p.target = "" 972 } 973 p.Target = p.target 974 975 // The gc toolchain only permits C source files with cgo. 976 if len(p.CFiles) > 0 && !p.usesCgo() && !p.usesSwig() && buildContext.Compiler == "gc" { 977 p.Error = &PackageError{ 978 ImportStack: stk.copy(), 979 Err: fmt.Sprintf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")), 980 } 981 return p 982 } 983 984 // In the absence of errors lower in the dependency tree, 985 // check for case-insensitive collisions of import paths. 986 if len(p.DepsErrors) == 0 { 987 dep1, dep2 := foldDup(p.Deps) 988 if dep1 != "" { 989 p.Error = &PackageError{ 990 ImportStack: stk.copy(), 991 Err: fmt.Sprintf("case-insensitive import collision: %q and %q", dep1, dep2), 992 } 993 return p 994 } 995 } 996 997 computeBuildID(p) 998 return p 999 } 1000 1001 // usesSwig reports whether the package needs to run SWIG. 1002 func (p *Package) usesSwig() bool { 1003 return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0 1004 } 1005 1006 // usesCgo reports whether the package needs to run cgo 1007 func (p *Package) usesCgo() bool { 1008 return len(p.CgoFiles) > 0 1009 } 1010 1011 // packageList returns the list of packages in the dag rooted at roots 1012 // as visited in a depth-first post-order traversal. 1013 func packageList(roots []*Package) []*Package { 1014 seen := map[*Package]bool{} 1015 all := []*Package{} 1016 var walk func(*Package) 1017 walk = func(p *Package) { 1018 if seen[p] { 1019 return 1020 } 1021 seen[p] = true 1022 for _, p1 := range p.imports { 1023 walk(p1) 1024 } 1025 all = append(all, p) 1026 } 1027 for _, root := range roots { 1028 walk(root) 1029 } 1030 return all 1031 } 1032 1033 // computeStale computes the Stale flag in the package dag that starts 1034 // at the named pkgs (command-line arguments). 1035 func computeStale(pkgs ...*Package) { 1036 for _, p := range packageList(pkgs) { 1037 p.Stale = isStale(p) 1038 } 1039 } 1040 1041 // The runtime version string takes one of two forms: 1042 // "go1.X[.Y]" for Go releases, and "devel +hash" at tip. 1043 // Determine whether we are in a released copy by 1044 // inspecting the version. 1045 var isGoRelease = strings.HasPrefix(runtime.Version(), "go1") 1046 1047 // isStale and computeBuildID 1048 // 1049 // Theory of Operation 1050 // 1051 // There is an installed copy of the package (or binary). 1052 // Can we reuse the installed copy, or do we need to build a new one? 1053 // 1054 // We can use the installed copy if it matches what we'd get 1055 // by building a new one. The hard part is predicting that without 1056 // actually running a build. 1057 // 1058 // To start, we must know the set of inputs to the build process that can 1059 // affect the generated output. At a minimum, that includes the source 1060 // files for the package and also any compiled packages imported by those 1061 // source files. The *Package has these, and we use them. One might also 1062 // argue for including in the input set: the build tags, whether the race 1063 // detector is in use, the target operating system and architecture, the 1064 // compiler and linker binaries being used, the additional flags being 1065 // passed to those, the cgo binary being used, the additional flags cgo 1066 // passes to the host C compiler, the host C compiler being used, the set 1067 // of host C include files and installed C libraries, and so on. 1068 // We include some but not all of this information. 1069 // 1070 // Once we have decided on a set of inputs, we must next decide how to 1071 // tell whether the content of that set has changed since the last build 1072 // of p. If there have been no changes, then we assume a new build would 1073 // produce the same result and reuse the installed package or binary. 1074 // But if there have been changes, then we assume a new build might not 1075 // produce the same result, so we rebuild. 1076 // 1077 // There are two common ways to decide whether the content of the set has 1078 // changed: modification times and content hashes. We use a mixture of both. 1079 // 1080 // The use of modification times (mtimes) was pioneered by make: 1081 // assuming that a file's mtime is an accurate record of when that file was last written, 1082 // and assuming that the modification time of an installed package or 1083 // binary is the time that it was built, if the mtimes of the inputs 1084 // predate the mtime of the installed object, then the build of that 1085 // object saw those versions of the files, and therefore a rebuild using 1086 // those same versions would produce the same object. In contrast, if any 1087 // mtime of an input is newer than the mtime of the installed object, a 1088 // change has occurred since the build, and the build should be redone. 1089 // 1090 // Modification times are attractive because the logic is easy to 1091 // understand and the file system maintains the mtimes automatically 1092 // (less work for us). Unfortunately, there are a variety of ways in 1093 // which the mtime approach fails to detect a change and reuses a stale 1094 // object file incorrectly. (Making the opposite mistake, rebuilding 1095 // unnecessarily, is only a performance problem and not a correctness 1096 // problem, so we ignore that one.) 1097 // 1098 // As a warmup, one problem is that to be perfectly precise, we need to 1099 // compare the input mtimes against the time at the beginning of the 1100 // build, but the object file time is the time at the end of the build. 1101 // If an input file changes after being read but before the object is 1102 // written, the next build will see an object newer than the input and 1103 // will incorrectly decide that the object is up to date. We make no 1104 // attempt to detect or solve this problem. 1105 // 1106 // Another problem is that due to file system imprecision, an input and 1107 // output that are actually ordered in time have the same mtime. 1108 // This typically happens on file systems with 1-second (or, worse, 1109 // 2-second) mtime granularity and with automated scripts that write an 1110 // input and then immediately run a build, or vice versa. If an input and 1111 // an output have the same mtime, the conservative behavior is to treat 1112 // the output as out-of-date and rebuild. This can cause one or more 1113 // spurious rebuilds, but only for 1 second, until the object finally has 1114 // an mtime later than the input. 1115 // 1116 // Another problem is that binary distributions often set the mtime on 1117 // all files to the same time. If the distribution includes both inputs 1118 // and cached build outputs, the conservative solution to the previous 1119 // problem will cause unnecessary rebuilds. Worse, in such a binary 1120 // distribution, those rebuilds might not even have permission to update 1121 // the cached build output. To avoid these write errors, if an input and 1122 // output have the same mtime, we assume the output is up-to-date. 1123 // This is the opposite of what the previous problem would have us do, 1124 // but binary distributions are more common than instances of the 1125 // previous problem. 1126 // 1127 // A variant of the last problem is that some binary distributions do not 1128 // set the mtime on all files to the same time. Instead they let the file 1129 // system record mtimes as the distribution is unpacked. If the outputs 1130 // are unpacked before the inputs, they'll be older and a build will try 1131 // to rebuild them. That rebuild might hit the same write errors as in 1132 // the last scenario. We don't make any attempt to solve this, and we 1133 // haven't had many reports of it. Perhaps the only time this happens is 1134 // when people manually unpack the distribution, and most of the time 1135 // that's done as the same user who will be using it, so an initial 1136 // rebuild on first use succeeds quietly. 1137 // 1138 // More generally, people and programs change mtimes on files. The last 1139 // few problems were specific examples of this, but it's a general problem. 1140 // For example, instead of a binary distribution, copying a home 1141 // directory from one directory or machine to another might copy files 1142 // but not preserve mtimes. If the inputs are new than the outputs on the 1143 // first machine but copied first, they end up older than the outputs on 1144 // the second machine. 1145 // 1146 // Because many other build systems have the same sensitivity to mtimes, 1147 // most programs manipulating source code take pains not to break the 1148 // mtime assumptions. For example, Git does not set the mtime of files 1149 // during a checkout operation, even when checking out an old version of 1150 // the code. This decision was made specifically to work well with 1151 // mtime-based build systems. 1152 // 1153 // The killer problem, though, for mtime-based build systems is that the 1154 // build only has access to the mtimes of the inputs that still exist. 1155 // If it is possible to remove an input without changing any other inputs, 1156 // a later build will think the object is up-to-date when it is not. 1157 // This happens for Go because a package is made up of all source 1158 // files in a directory. If a source file is removed, there is no newer 1159 // mtime available recording that fact. The mtime on the directory could 1160 // be used, but it also changes when unrelated files are added to or 1161 // removed from the directory, so including the directory mtime would 1162 // cause unnecessary rebuilds, possibly many. It would also exacerbate 1163 // the problems mentioned earlier, since even programs that are careful 1164 // to maintain mtimes on files rarely maintain mtimes on directories. 1165 // 1166 // A variant of the last problem is when the inputs change for other 1167 // reasons. For example, Go 1.4 and Go 1.5 both install $GOPATH/src/mypkg 1168 // into the same target, $GOPATH/pkg/$GOOS_$GOARCH/mypkg.a. 1169 // If Go 1.4 has built mypkg into mypkg.a, a build using Go 1.5 must 1170 // rebuild mypkg.a, but from mtimes alone mypkg.a looks up-to-date. 1171 // If Go 1.5 has just been installed, perhaps the compiler will have a 1172 // newer mtime; since the compiler is considered an input, that would 1173 // trigger a rebuild. But only once, and only the last Go 1.4 build of 1174 // mypkg.a happened before Go 1.5 was installed. If a user has the two 1175 // versions installed in different locations and flips back and forth, 1176 // mtimes alone cannot tell what to do. Changing the toolchain is 1177 // changing the set of inputs, without affecting any mtimes. 1178 // 1179 // To detect the set of inputs changing, we turn away from mtimes and to 1180 // an explicit data comparison. Specifically, we build a list of the 1181 // inputs to the build, compute its SHA1 hash, and record that as the 1182 // ``build ID'' in the generated object. At the next build, we can 1183 // recompute the buid ID and compare it to the one in the generated 1184 // object. If they differ, the list of inputs has changed, so the object 1185 // is out of date and must be rebuilt. 1186 // 1187 // Because this build ID is computed before the build begins, the 1188 // comparison does not have the race that mtime comparison does. 1189 // 1190 // Making the build sensitive to changes in other state is 1191 // straightforward: include the state in the build ID hash, and if it 1192 // changes, so does the build ID, triggering a rebuild. 1193 // 1194 // To detect changes in toolchain, we include the toolchain version in 1195 // the build ID hash for package runtime, and then we include the build 1196 // IDs of all imported packages in the build ID for p. 1197 // 1198 // It is natural to think about including build tags in the build ID, but 1199 // the naive approach of just dumping the tags into the hash would cause 1200 // spurious rebuilds. For example, 'go install' and 'go install -tags neverusedtag' 1201 // produce the same binaries (assuming neverusedtag is never used). 1202 // A more precise approach would be to include only tags that have an 1203 // effect on the build. But the effect of a tag on the build is to 1204 // include or exclude a file from the compilation, and that file list is 1205 // already in the build ID hash. So the build ID is already tag-sensitive 1206 // in a perfectly precise way. So we do NOT explicitly add build tags to 1207 // the build ID hash. 1208 // 1209 // We do not include as part of the build ID the operating system, 1210 // architecture, or whether the race detector is enabled, even though all 1211 // three have an effect on the output, because that information is used 1212 // to decide the install location. Binaries for linux and binaries for 1213 // darwin are written to different directory trees; including that 1214 // information in the build ID is unnecessary (although it would be 1215 // harmless). 1216 // 1217 // TODO(rsc): Investigate the cost of putting source file content into 1218 // the build ID hash as a replacement for the use of mtimes. Using the 1219 // file content would avoid all the mtime problems, but it does require 1220 // reading all the source files, something we avoid today (we read the 1221 // beginning to find the build tags and the imports, but we stop as soon 1222 // as we see the import block is over). If the package is stale, the compiler 1223 // is going to read the files anyway. But if the package is up-to-date, the 1224 // read is overhead. 1225 // 1226 // TODO(rsc): Investigate the complexity of making the build more 1227 // precise about when individual results are needed. To be fully precise, 1228 // there are two results of a compilation: the entire .a file used by the link 1229 // and the subpiece used by later compilations (__.PKGDEF only). 1230 // If a rebuild is needed but produces the previous __.PKGDEF, then 1231 // no more recompilation due to the rebuilt package is needed, only 1232 // relinking. To date, there is nothing in the Go command to express this. 1233 // 1234 // Special Cases 1235 // 1236 // When the go command makes the wrong build decision and does not 1237 // rebuild something it should, users fall back to adding the -a flag. 1238 // Any common use of the -a flag should be considered prima facie evidence 1239 // that isStale is returning an incorrect false result in some important case. 1240 // Bugs reported in the behavior of -a itself should prompt the question 1241 // ``Why is -a being used at all? What bug does that indicate?'' 1242 // 1243 // There is a long history of changes to isStale to try to make -a into a 1244 // suitable workaround for bugs in the mtime-based decisions. 1245 // It is worth recording that history to inform (and, as much as possible, deter) future changes. 1246 // 1247 // (1) Before the build IDs were introduced, building with alternate tags 1248 // would happily reuse installed objects built without those tags. 1249 // For example, "go build -tags netgo myprog.go" would use the installed 1250 // copy of package net, even if that copy had been built without netgo. 1251 // (The netgo tag controls whether package net uses cgo or pure Go for 1252 // functionality such as name resolution.) 1253 // Using the installed non-netgo package defeats the purpose. 1254 // 1255 // Users worked around this with "go build -tags netgo -a myprog.go". 1256 // 1257 // Build IDs have made that workaround unnecessary: 1258 // "go build -tags netgo myprog.go" 1259 // cannot use a non-netgo copy of package net. 1260 // 1261 // (2) Before the build IDs were introduced, building with different toolchains, 1262 // especially changing between toolchains, tried to reuse objects stored in 1263 // $GOPATH/pkg, resulting in link-time errors about object file mismatches. 1264 // 1265 // Users worked around this with "go install -a ./...". 1266 // 1267 // Build IDs have made that workaround unnecessary: 1268 // "go install ./..." will rebuild any objects it finds that were built against 1269 // a different toolchain. 1270 // 1271 // (3) The common use of "go install -a ./..." led to reports of problems 1272 // when the -a forced the rebuild of the standard library, which for some 1273 // users was not writable. Because we didn't understand that the real 1274 // problem was the bug -a was working around, we changed -a not to 1275 // apply to the standard library. 1276 // 1277 // (4) The common use of "go build -tags netgo -a myprog.go" broke 1278 // when we changed -a not to apply to the standard library, because 1279 // if go build doesn't rebuild package net, it uses the non-netgo version. 1280 // 1281 // Users worked around this with "go build -tags netgo -installsuffix barf myprog.go". 1282 // The -installsuffix here is making the go command look for packages 1283 // in pkg/$GOOS_$GOARCH_barf instead of pkg/$GOOS_$GOARCH. 1284 // Since the former presumably doesn't exist, go build decides to rebuild 1285 // everything, including the standard library. Since go build doesn't 1286 // install anything it builds, nothing is ever written to pkg/$GOOS_$GOARCH_barf, 1287 // so repeated invocations continue to work. 1288 // 1289 // If the use of -a wasn't a red flag, the use of -installsuffix to point to 1290 // a non-existent directory in a command that installs nothing should 1291 // have been. 1292 // 1293 // (5) Now that (1) and (2) no longer need -a, we have removed the kludge 1294 // introduced in (3): once again, -a means ``rebuild everything,'' not 1295 // ``rebuild everything except the standard library.'' Only Go 1.4 had 1296 // the restricted meaning. 1297 // 1298 // In addition to these cases trying to trigger rebuilds, there are 1299 // special cases trying NOT to trigger rebuilds. The main one is that for 1300 // a variety of reasons (see above), the install process for a Go release 1301 // cannot be relied upon to set the mtimes such that the go command will 1302 // think the standard library is up to date. So the mtime evidence is 1303 // ignored for the standard library if we find ourselves in a release 1304 // version of Go. Build ID-based staleness checks still apply to the 1305 // standard library, even in release versions. This makes 1306 // 'go build -tags netgo' work, among other things. 1307 1308 // isStale reports whether package p needs to be rebuilt. 1309 func isStale(p *Package) bool { 1310 if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") { 1311 // fake, builtin package 1312 return false 1313 } 1314 if p.Error != nil { 1315 return true 1316 } 1317 1318 // A package without Go sources means we only found 1319 // the installed .a file. Since we don't know how to rebuild 1320 // it, it can't be stale, even if -a is set. This enables binary-only 1321 // distributions of Go packages, although such binaries are 1322 // only useful with the specific version of the toolchain that 1323 // created them. 1324 if len(p.gofiles) == 0 && !p.usesSwig() { 1325 return false 1326 } 1327 1328 // If the -a flag is given, rebuild everything. 1329 if buildA { 1330 return true 1331 } 1332 1333 // If there's no install target or it's already marked stale, we have to rebuild. 1334 if p.target == "" || p.Stale { 1335 return true 1336 } 1337 1338 // Package is stale if completely unbuilt. 1339 fi, err := os.Stat(p.target) 1340 if err != nil { 1341 return true 1342 } 1343 1344 // Package is stale if the expected build ID differs from the 1345 // recorded build ID. This catches changes like a source file 1346 // being removed from a package directory. See issue 3895. 1347 // It also catches changes in build tags that affect the set of 1348 // files being compiled. See issue 9369. 1349 // It also catches changes in toolchain, like when flipping between 1350 // two versions of Go compiling a single GOPATH. 1351 // See issue 8290 and issue 10702. 1352 targetBuildID, err := readBuildID(p) 1353 if err == nil && targetBuildID != p.buildID { 1354 return true 1355 } 1356 1357 // Package is stale if a dependency is. 1358 for _, p1 := range p.deps { 1359 if p1.Stale { 1360 return true 1361 } 1362 } 1363 1364 // The checks above are content-based staleness. 1365 // We assume they are always accurate. 1366 // 1367 // The checks below are mtime-based staleness. 1368 // We hope they are accurate, but we know that they fail in the case of 1369 // prebuilt Go installations that don't preserve the build mtimes 1370 // (for example, if the pkg/ mtimes are before the src/ mtimes). 1371 // See the large comment above isStale for details. 1372 1373 // If we are running a release copy of Go and didn't find a content-based 1374 // reason to rebuild the standard packages, do not rebuild them. 1375 // They may not be writable anyway, but they are certainly not changing. 1376 // This makes 'go build' skip the standard packages when 1377 // using an official release, even when the mtimes have been changed. 1378 // See issue 3036, issue 3149, issue 4106, issue 8290. 1379 // (If a change to a release tree must be made by hand, the way to force the 1380 // install is to run make.bash, which will remove the old package archives 1381 // before rebuilding.) 1382 if p.Standard && isGoRelease { 1383 return false 1384 } 1385 1386 // Time-based staleness. 1387 1388 built := fi.ModTime() 1389 1390 olderThan := func(file string) bool { 1391 fi, err := os.Stat(file) 1392 return err != nil || fi.ModTime().After(built) 1393 } 1394 1395 // Package is stale if a dependency is, or if a dependency is newer. 1396 for _, p1 := range p.deps { 1397 if p1.target != "" && olderThan(p1.target) { 1398 return true 1399 } 1400 } 1401 1402 // As a courtesy to developers installing new versions of the compiler 1403 // frequently, define that packages are stale if they are 1404 // older than the compiler, and commands if they are older than 1405 // the linker. This heuristic will not work if the binaries are 1406 // back-dated, as some binary distributions may do, but it does handle 1407 // a very common case. 1408 // See issue 3036. 1409 // Exclude $GOROOT, under the assumption that people working on 1410 // the compiler may want to control when everything gets rebuilt, 1411 // and people updating the Go repository will run make.bash or all.bash 1412 // and get a full rebuild anyway. 1413 // Excluding $GOROOT used to also fix issue 4106, but that's now 1414 // taken care of above (at least when the installed Go is a released version). 1415 if p.Root != goroot { 1416 if olderThan(buildToolchain.compiler()) { 1417 return true 1418 } 1419 if p.build.IsCommand() && olderThan(buildToolchain.linker()) { 1420 return true 1421 } 1422 } 1423 1424 // Note: Until Go 1.5, we had an additional shortcut here. 1425 // We built a list of the workspace roots ($GOROOT, each $GOPATH) 1426 // containing targets directly named on the command line, 1427 // and if p were not in any of those, it would be treated as up-to-date 1428 // as long as it is built. The goal was to avoid rebuilding a system-installed 1429 // $GOROOT, unless something from $GOROOT were explicitly named 1430 // on the command line (like go install math). 1431 // That's now handled by the isGoRelease clause above. 1432 // The other effect of the shortcut was to isolate different entries in 1433 // $GOPATH from each other. This had the unfortunate effect that 1434 // if you had (say), GOPATH listing two entries, one for commands 1435 // and one for libraries, and you did a 'git pull' in the library one 1436 // and then tried 'go install commands/...', it would build the new libraries 1437 // during the first build (because they wouldn't have been installed at all) 1438 // but then subsequent builds would not rebuild the libraries, even if the 1439 // mtimes indicate they are stale, because the different GOPATH entries 1440 // were treated differently. This behavior was confusing when using 1441 // non-trivial GOPATHs, which were particularly common with some 1442 // code management conventions, like the original godep. 1443 // Since the $GOROOT case (the original motivation) is handled separately, 1444 // we no longer put a barrier between the different $GOPATH entries. 1445 // 1446 // One implication of this is that if there is a system directory for 1447 // non-standard Go packages that is included in $GOPATH, the mtimes 1448 // on those compiled packages must be no earlier than the mtimes 1449 // on the source files. Since most distributions use the same mtime 1450 // for all files in a tree, they will be unaffected. People using plain 1451 // tar x to extract system-installed packages will need to adjust mtimes, 1452 // but it's better to force them to get the mtimes right than to ignore 1453 // the mtimes and thereby do the wrong thing in common use cases. 1454 // 1455 // So there is no GOPATH vs GOPATH shortcut here anymore. 1456 // 1457 // If something needs to come back here, we could try writing a dummy 1458 // file with a random name to the $GOPATH/pkg directory (and removing it) 1459 // to test for write access, and then skip GOPATH roots we don't have write 1460 // access to. But hopefully we can just use the mtimes always. 1461 1462 srcs := stringList(p.GoFiles, p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.SFiles, p.CgoFiles, p.SysoFiles, p.SwigFiles, p.SwigCXXFiles) 1463 for _, src := range srcs { 1464 if olderThan(filepath.Join(p.Dir, src)) { 1465 return true 1466 } 1467 } 1468 1469 return false 1470 } 1471 1472 // computeBuildID computes the build ID for p, leaving it in p.buildID. 1473 // Build ID is a hash of the information we want to detect changes in. 1474 // See the long comment in isStale for details. 1475 func computeBuildID(p *Package) { 1476 h := sha1.New() 1477 1478 // Include the list of files compiled as part of the package. 1479 // This lets us detect removed files. See issue 3895. 1480 inputFiles := stringList( 1481 p.GoFiles, 1482 p.CgoFiles, 1483 p.CFiles, 1484 p.CXXFiles, 1485 p.MFiles, 1486 p.HFiles, 1487 p.SFiles, 1488 p.SysoFiles, 1489 p.SwigFiles, 1490 p.SwigCXXFiles, 1491 ) 1492 for _, file := range inputFiles { 1493 fmt.Fprintf(h, "file %s\n", file) 1494 } 1495 1496 // Include the content of runtime/zversion.go in the hash 1497 // for package runtime. This will give package runtime a 1498 // different build ID in each Go release. 1499 if p.Standard && p.ImportPath == "runtime" { 1500 data, _ := ioutil.ReadFile(filepath.Join(p.Dir, "zversion.go")) 1501 fmt.Fprintf(h, "zversion %q\n", string(data)) 1502 } 1503 1504 // Include the build IDs of any dependencies in the hash. 1505 // This, combined with the runtime/zversion content, 1506 // will cause packages to have different build IDs when 1507 // compiled with different Go releases. 1508 // This helps the go command know to recompile when 1509 // people use the same GOPATH but switch between 1510 // different Go releases. See issue 10702. 1511 // This is also a better fix for issue 8290. 1512 for _, p1 := range p.deps { 1513 fmt.Fprintf(h, "dep %s %s\n", p1.ImportPath, p1.buildID) 1514 } 1515 1516 p.buildID = fmt.Sprintf("%x", h.Sum(nil)) 1517 } 1518 1519 var cwd, _ = os.Getwd() 1520 1521 var cmdCache = map[string]*Package{} 1522 1523 // loadPackage is like loadImport but is used for command-line arguments, 1524 // not for paths found in import statements. In addition to ordinary import paths, 1525 // loadPackage accepts pseudo-paths beginning with cmd/ to denote commands 1526 // in the Go command directory, as well as paths to those directories. 1527 func loadPackage(arg string, stk *importStack) *Package { 1528 if build.IsLocalImport(arg) { 1529 dir := arg 1530 if !filepath.IsAbs(dir) { 1531 if abs, err := filepath.Abs(dir); err == nil { 1532 // interpret relative to current directory 1533 dir = abs 1534 } 1535 } 1536 if sub, ok := hasSubdir(gorootSrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") { 1537 arg = sub 1538 } 1539 } 1540 if strings.HasPrefix(arg, "cmd/") && !strings.Contains(arg[4:], "/") { 1541 if p := cmdCache[arg]; p != nil { 1542 return p 1543 } 1544 stk.push(arg) 1545 defer stk.pop() 1546 1547 bp, err := buildContext.ImportDir(filepath.Join(gorootSrc, arg), 0) 1548 bp.ImportPath = arg 1549 bp.Goroot = true 1550 bp.BinDir = gorootBin 1551 if gobin != "" { 1552 bp.BinDir = gobin 1553 } 1554 bp.Root = goroot 1555 bp.SrcRoot = gorootSrc 1556 p := new(Package) 1557 cmdCache[arg] = p 1558 p.load(stk, bp, err) 1559 if p.Error == nil && p.Name != "main" { 1560 p.Error = &PackageError{ 1561 ImportStack: stk.copy(), 1562 Err: fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir), 1563 } 1564 } 1565 return p 1566 } 1567 1568 // Wasn't a command; must be a package. 1569 // If it is a local import path but names a standard package, 1570 // we treat it as if the user specified the standard package. 1571 // This lets you run go test ./ioutil in package io and be 1572 // referring to io/ioutil rather than a hypothetical import of 1573 // "./ioutil". 1574 if build.IsLocalImport(arg) { 1575 bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly) 1576 if bp.ImportPath != "" && bp.ImportPath != "." { 1577 arg = bp.ImportPath 1578 } 1579 } 1580 1581 return loadImport(arg, cwd, nil, stk, nil, 0) 1582 } 1583 1584 // packages returns the packages named by the 1585 // command line arguments 'args'. If a named package 1586 // cannot be loaded at all (for example, if the directory does not exist), 1587 // then packages prints an error and does not include that 1588 // package in the results. However, if errors occur trying 1589 // to load dependencies of a named package, the named 1590 // package is still returned, with p.Incomplete = true 1591 // and details in p.DepsErrors. 1592 func packages(args []string) []*Package { 1593 var pkgs []*Package 1594 for _, pkg := range packagesAndErrors(args) { 1595 if pkg.Error != nil { 1596 errorf("can't load package: %s", pkg.Error) 1597 continue 1598 } 1599 pkgs = append(pkgs, pkg) 1600 } 1601 return pkgs 1602 } 1603 1604 // packagesAndErrors is like 'packages' but returns a 1605 // *Package for every argument, even the ones that 1606 // cannot be loaded at all. 1607 // The packages that fail to load will have p.Error != nil. 1608 func packagesAndErrors(args []string) []*Package { 1609 if len(args) > 0 && strings.HasSuffix(args[0], ".go") { 1610 return []*Package{goFilesPackage(args)} 1611 } 1612 1613 args = importPaths(args) 1614 var ( 1615 pkgs []*Package 1616 stk importStack 1617 seenArg = make(map[string]bool) 1618 seenPkg = make(map[*Package]bool) 1619 ) 1620 1621 for _, arg := range args { 1622 if seenArg[arg] { 1623 continue 1624 } 1625 seenArg[arg] = true 1626 pkg := loadPackage(arg, &stk) 1627 if seenPkg[pkg] { 1628 continue 1629 } 1630 seenPkg[pkg] = true 1631 pkgs = append(pkgs, pkg) 1632 } 1633 computeStale(pkgs...) 1634 1635 return pkgs 1636 } 1637 1638 // packagesForBuild is like 'packages' but fails if any of 1639 // the packages or their dependencies have errors 1640 // (cannot be built). 1641 func packagesForBuild(args []string) []*Package { 1642 pkgs := packagesAndErrors(args) 1643 printed := map[*PackageError]bool{} 1644 for _, pkg := range pkgs { 1645 if pkg.Error != nil { 1646 errorf("can't load package: %s", pkg.Error) 1647 } 1648 for _, err := range pkg.DepsErrors { 1649 // Since these are errors in dependencies, 1650 // the same error might show up multiple times, 1651 // once in each package that depends on it. 1652 // Only print each once. 1653 if !printed[err] { 1654 printed[err] = true 1655 errorf("%s", err) 1656 } 1657 } 1658 } 1659 exitIfErrors() 1660 1661 // Check for duplicate loads of the same package. 1662 // That should be impossible, but if it does happen then 1663 // we end up trying to build the same package twice, 1664 // usually in parallel overwriting the same files, 1665 // which doesn't work very well. 1666 seen := map[string]bool{} 1667 reported := map[string]bool{} 1668 for _, pkg := range packageList(pkgs) { 1669 if seen[pkg.ImportPath] && !reported[pkg.ImportPath] { 1670 reported[pkg.ImportPath] = true 1671 errorf("internal error: duplicate loads of %s", pkg.ImportPath) 1672 } 1673 seen[pkg.ImportPath] = true 1674 } 1675 exitIfErrors() 1676 1677 return pkgs 1678 } 1679 1680 // hasSubdir reports whether dir is a subdirectory of 1681 // (possibly multiple levels below) root. 1682 // If so, it sets rel to the path fragment that must be 1683 // appended to root to reach dir. 1684 func hasSubdir(root, dir string) (rel string, ok bool) { 1685 if p, err := filepath.EvalSymlinks(root); err == nil { 1686 root = p 1687 } 1688 if p, err := filepath.EvalSymlinks(dir); err == nil { 1689 dir = p 1690 } 1691 const sep = string(filepath.Separator) 1692 root = filepath.Clean(root) 1693 if !strings.HasSuffix(root, sep) { 1694 root += sep 1695 } 1696 dir = filepath.Clean(dir) 1697 if !strings.HasPrefix(dir, root) { 1698 return "", false 1699 } 1700 return filepath.ToSlash(dir[len(root):]), true 1701 } 1702 1703 var ( 1704 errBuildIDToolchain = fmt.Errorf("build ID only supported in gc toolchain") 1705 errBuildIDMalformed = fmt.Errorf("malformed object file") 1706 errBuildIDUnknown = fmt.Errorf("lost build ID") 1707 ) 1708 1709 var ( 1710 bangArch = []byte("!<arch>") 1711 pkgdef = []byte("__.PKGDEF") 1712 goobject = []byte("go object ") 1713 buildid = []byte("build id ") 1714 ) 1715 1716 // readBuildID reads the build ID from an archive or binary. 1717 // It only supports the gc toolchain. 1718 // Other toolchain maintainers should adjust this function. 1719 func readBuildID(p *Package) (id string, err error) { 1720 if buildToolchain != (gcToolchain{}) { 1721 return "", errBuildIDToolchain 1722 } 1723 1724 // For commands, read build ID directly from binary. 1725 if p.Name == "main" { 1726 return ReadBuildIDFromBinary(p.Target) 1727 } 1728 1729 // Otherwise, we expect to have an archive (.a) file, 1730 // and we can read the build ID from the Go export data. 1731 if !strings.HasSuffix(p.Target, ".a") { 1732 return "", &os.PathError{Op: "parse", Path: p.Target, Err: errBuildIDUnknown} 1733 } 1734 1735 // Read just enough of the target to fetch the build ID. 1736 // The archive is expected to look like: 1737 // 1738 // !<arch> 1739 // __.PKGDEF 0 0 0 644 7955 ` 1740 // go object darwin amd64 devel X:none 1741 // build id "b41e5c45250e25c9fd5e9f9a1de7857ea0d41224" 1742 // 1743 // The variable-sized strings are GOOS, GOARCH, and the experiment list (X:none). 1744 // Reading the first 1024 bytes should be plenty. 1745 f, err := os.Open(p.Target) 1746 if err != nil { 1747 return "", err 1748 } 1749 data := make([]byte, 1024) 1750 n, err := io.ReadFull(f, data) 1751 f.Close() 1752 1753 if err != nil && n == 0 { 1754 return "", err 1755 } 1756 1757 bad := func() (string, error) { 1758 return "", &os.PathError{Op: "parse", Path: p.Target, Err: errBuildIDMalformed} 1759 } 1760 1761 // Archive header. 1762 for i := 0; ; i++ { // returns during i==3 1763 j := bytes.IndexByte(data, '\n') 1764 if j < 0 { 1765 return bad() 1766 } 1767 line := data[:j] 1768 data = data[j+1:] 1769 switch i { 1770 case 0: 1771 if !bytes.Equal(line, bangArch) { 1772 return bad() 1773 } 1774 case 1: 1775 if !bytes.HasPrefix(line, pkgdef) { 1776 return bad() 1777 } 1778 case 2: 1779 if !bytes.HasPrefix(line, goobject) { 1780 return bad() 1781 } 1782 case 3: 1783 if !bytes.HasPrefix(line, buildid) { 1784 // Found the object header, just doesn't have a build id line. 1785 // Treat as successful, with empty build id. 1786 return "", nil 1787 } 1788 id, err := strconv.Unquote(string(line[len(buildid):])) 1789 if err != nil { 1790 return bad() 1791 } 1792 return id, nil 1793 } 1794 } 1795 } 1796 1797 var ( 1798 goBuildPrefix = []byte("\xff Go build ID: \"") 1799 goBuildEnd = []byte("\"\n \xff") 1800 1801 elfPrefix = []byte("\x7fELF") 1802 1803 machoPrefixes = [][]byte{ 1804 {0xfe, 0xed, 0xfa, 0xce}, 1805 {0xfe, 0xed, 0xfa, 0xcf}, 1806 {0xce, 0xfa, 0xed, 0xfe}, 1807 {0xcf, 0xfa, 0xed, 0xfe}, 1808 } 1809 ) 1810 1811 var BuildIDReadSize = 32 * 1024 // changed for testing 1812 1813 // ReadBuildIDFromBinary reads the build ID from a binary. 1814 // 1815 // ELF binaries store the build ID in a proper PT_NOTE section. 1816 // 1817 // Other binary formats are not so flexible. For those, the linker 1818 // stores the build ID as non-instruction bytes at the very beginning 1819 // of the text segment, which should appear near the beginning 1820 // of the file. This is clumsy but fairly portable. Custom locations 1821 // can be added for other binary types as needed, like we did for ELF. 1822 func ReadBuildIDFromBinary(filename string) (id string, err error) { 1823 if filename == "" { 1824 return "", &os.PathError{Op: "parse", Path: filename, Err: errBuildIDUnknown} 1825 } 1826 1827 // Read the first 32 kB of the binary file. 1828 // That should be enough to find the build ID. 1829 // In ELF files, the build ID is in the leading headers, 1830 // which are typically less than 4 kB, not to mention 32 kB. 1831 // In Mach-O files, there's no limit, so we have to parse the file. 1832 // On other systems, we're trying to read enough that 1833 // we get the beginning of the text segment in the read. 1834 // The offset where the text segment begins in a hello 1835 // world compiled for each different object format today: 1836 // 1837 // Plan 9: 0x20 1838 // Windows: 0x600 1839 // 1840 f, err := os.Open(filename) 1841 if err != nil { 1842 return "", err 1843 } 1844 defer f.Close() 1845 1846 data := make([]byte, BuildIDReadSize) 1847 _, err = io.ReadFull(f, data) 1848 if err == io.ErrUnexpectedEOF { 1849 err = nil 1850 } 1851 if err != nil { 1852 return "", err 1853 } 1854 1855 if bytes.HasPrefix(data, elfPrefix) { 1856 return readELFGoBuildID(filename, f, data) 1857 } 1858 for _, m := range machoPrefixes { 1859 if bytes.HasPrefix(data, m) { 1860 return readMachoGoBuildID(filename, f, data) 1861 } 1862 } 1863 1864 return readRawGoBuildID(filename, data) 1865 } 1866 1867 // readRawGoBuildID finds the raw build ID stored in text segment data. 1868 func readRawGoBuildID(filename string, data []byte) (id string, err error) { 1869 i := bytes.Index(data, goBuildPrefix) 1870 if i < 0 { 1871 // Missing. Treat as successful but build ID empty. 1872 return "", nil 1873 } 1874 1875 j := bytes.Index(data[i+len(goBuildPrefix):], goBuildEnd) 1876 if j < 0 { 1877 return "", &os.PathError{Op: "parse", Path: filename, Err: errBuildIDMalformed} 1878 } 1879 1880 quoted := data[i+len(goBuildPrefix)-1 : i+len(goBuildPrefix)+j+1] 1881 id, err = strconv.Unquote(string(quoted)) 1882 if err != nil { 1883 return "", &os.PathError{Op: "parse", Path: filename, Err: errBuildIDMalformed} 1884 } 1885 1886 return id, nil 1887 }