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