]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/go/pkg.go
[dev.cc] all: merge master (b8fcae0) into dev.cc
[gostls13.git] / src / cmd / go / pkg.go
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         "errors"
10         "fmt"
11         "go/build"
12         "go/scanner"
13         "go/token"
14         "os"
15         pathpkg "path"
16         "path/filepath"
17         "runtime"
18         "sort"
19         "strings"
20         "time"
21         "unicode"
22 )
23
24 // A Package describes a single package found in a directory.
25 type Package struct {
26         // Note: These fields are part of the go command's public API.
27         // See list.go.  It is okay to add fields, but not to change or
28         // remove existing ones.  Keep in sync with list.go
29         Dir           string `json:",omitempty"` // directory containing package sources
30         ImportPath    string `json:",omitempty"` // import path of package in dir
31         ImportComment string `json:",omitempty"` // path in import comment on package statement
32         Name          string `json:",omitempty"` // package name
33         Doc           string `json:",omitempty"` // package documentation string
34         Target        string `json:",omitempty"` // install path
35         Goroot        bool   `json:",omitempty"` // is this package found in the Go root?
36         Standard      bool   `json:",omitempty"` // is this package part of the standard Go library?
37         Stale         bool   `json:",omitempty"` // would 'go install' do anything for this package?
38         Root          string `json:",omitempty"` // Go root or Go path dir containing this package
39         ConflictDir   string `json:",omitempty"` // Dir is hidden by this other directory
40
41         // Source files
42         GoFiles        []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
43         CgoFiles       []string `json:",omitempty"` // .go sources files that import "C"
44         IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints
45         CFiles         []string `json:",omitempty"` // .c source files
46         CXXFiles       []string `json:",omitempty"` // .cc, .cpp and .cxx source files
47         MFiles         []string `json:",omitempty"` // .m source files
48         HFiles         []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files
49         SFiles         []string `json:",omitempty"` // .s source files
50         SwigFiles      []string `json:",omitempty"` // .swig files
51         SwigCXXFiles   []string `json:",omitempty"` // .swigcxx files
52         SysoFiles      []string `json:",omitempty"` // .syso system object files added to package
53
54         // Cgo directives
55         CgoCFLAGS    []string `json:",omitempty"` // cgo: flags for C compiler
56         CgoCPPFLAGS  []string `json:",omitempty"` // cgo: flags for C preprocessor
57         CgoCXXFLAGS  []string `json:",omitempty"` // cgo: flags for C++ compiler
58         CgoLDFLAGS   []string `json:",omitempty"` // cgo: flags for linker
59         CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
60
61         // Dependency information
62         Imports []string `json:",omitempty"` // import paths used by this package
63         Deps    []string `json:",omitempty"` // all (recursively) imported dependencies
64
65         // Error information
66         Incomplete bool            `json:",omitempty"` // was there an error loading this package or dependencies?
67         Error      *PackageError   `json:",omitempty"` // error loading this package (not dependencies)
68         DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies
69
70         // Test information
71         TestGoFiles  []string `json:",omitempty"` // _test.go files in package
72         TestImports  []string `json:",omitempty"` // imports from TestGoFiles
73         XTestGoFiles []string `json:",omitempty"` // _test.go files outside package
74         XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
75
76         // Unexported fields are not part of the public API.
77         build        *build.Package
78         pkgdir       string // overrides build.PkgDir
79         imports      []*Package
80         deps         []*Package
81         gofiles      []string // GoFiles+CgoFiles+TestGoFiles+XTestGoFiles files, absolute paths
82         sfiles       []string
83         allgofiles   []string             // gofiles + IgnoredGoFiles, absolute paths
84         target       string               // installed file for this package (may be executable)
85         fake         bool                 // synthesized package
86         forceBuild   bool                 // this package must be rebuilt
87         forceLibrary bool                 // this package is a library (even if named "main")
88         cmdline      bool                 // defined by files listed on command line
89         local        bool                 // imported via local path (./ or ../)
90         localPrefix  string               // interpret ./ and ../ imports relative to this prefix
91         exeName      string               // desired name for temporary executable
92         coverMode    string               // preprocess Go source files with the coverage tool in this mode
93         coverVars    map[string]*CoverVar // variables created by coverage analysis
94         omitDWARF    bool                 // tell linker not to write DWARF information
95 }
96
97 // CoverVar holds the name of the generated coverage variables targeting the named file.
98 type CoverVar struct {
99         File string // local file name
100         Var  string // name of count struct
101 }
102
103 func (p *Package) copyBuild(pp *build.Package) {
104         p.build = pp
105
106         p.Dir = pp.Dir
107         p.ImportPath = pp.ImportPath
108         p.ImportComment = pp.ImportComment
109         p.Name = pp.Name
110         p.Doc = pp.Doc
111         p.Root = pp.Root
112         p.ConflictDir = pp.ConflictDir
113         // TODO? Target
114         p.Goroot = pp.Goroot
115         p.Standard = p.Goroot && p.ImportPath != "" && !strings.Contains(p.ImportPath, ".")
116         p.GoFiles = pp.GoFiles
117         p.CgoFiles = pp.CgoFiles
118         p.IgnoredGoFiles = pp.IgnoredGoFiles
119         p.CFiles = pp.CFiles
120         p.CXXFiles = pp.CXXFiles
121         p.MFiles = pp.MFiles
122         p.HFiles = pp.HFiles
123         p.SFiles = pp.SFiles
124         p.SwigFiles = pp.SwigFiles
125         p.SwigCXXFiles = pp.SwigCXXFiles
126         p.SysoFiles = pp.SysoFiles
127         p.CgoCFLAGS = pp.CgoCFLAGS
128         p.CgoCPPFLAGS = pp.CgoCPPFLAGS
129         p.CgoCXXFLAGS = pp.CgoCXXFLAGS
130         p.CgoLDFLAGS = pp.CgoLDFLAGS
131         p.CgoPkgConfig = pp.CgoPkgConfig
132         p.Imports = pp.Imports
133         p.TestGoFiles = pp.TestGoFiles
134         p.TestImports = pp.TestImports
135         p.XTestGoFiles = pp.XTestGoFiles
136         p.XTestImports = pp.XTestImports
137 }
138
139 // A PackageError describes an error loading information about a package.
140 type PackageError struct {
141         ImportStack   []string // shortest path from package named on command line to this one
142         Pos           string   // position of error
143         Err           string   // the error itself
144         isImportCycle bool     // the error is an import cycle
145         hard          bool     // whether the error is soft or hard; soft errors are ignored in some places
146 }
147
148 func (p *PackageError) Error() string {
149         // Import cycles deserve special treatment.
150         if p.isImportCycle {
151                 return fmt.Sprintf("%s\npackage %s\n", p.Err, strings.Join(p.ImportStack, "\n\timports "))
152         }
153         if p.Pos != "" {
154                 // Omit import stack.  The full path to the file where the error
155                 // is the most important thing.
156                 return p.Pos + ": " + p.Err
157         }
158         if len(p.ImportStack) == 0 {
159                 return p.Err
160         }
161         return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err
162 }
163
164 // An importStack is a stack of import paths.
165 type importStack []string
166
167 func (s *importStack) push(p string) {
168         *s = append(*s, p)
169 }
170
171 func (s *importStack) pop() {
172         *s = (*s)[0 : len(*s)-1]
173 }
174
175 func (s *importStack) copy() []string {
176         return append([]string{}, *s...)
177 }
178
179 // shorterThan returns true if sp is shorter than t.
180 // We use this to record the shortest import sequence
181 // that leads to a particular package.
182 func (sp *importStack) shorterThan(t []string) bool {
183         s := *sp
184         if len(s) != len(t) {
185                 return len(s) < len(t)
186         }
187         // If they are the same length, settle ties using string ordering.
188         for i := range s {
189                 if s[i] != t[i] {
190                         return s[i] < t[i]
191                 }
192         }
193         return false // they are equal
194 }
195
196 // packageCache is a lookup cache for loadPackage,
197 // so that if we look up a package multiple times
198 // we return the same pointer each time.
199 var packageCache = map[string]*Package{}
200
201 // reloadPackage is like loadPackage but makes sure
202 // not to use the package cache.
203 func reloadPackage(arg string, stk *importStack) *Package {
204         p := packageCache[arg]
205         if p != nil {
206                 delete(packageCache, p.Dir)
207                 delete(packageCache, p.ImportPath)
208         }
209         return loadPackage(arg, stk)
210 }
211
212 // dirToImportPath returns the pseudo-import path we use for a package
213 // outside the Go path.  It begins with _/ and then contains the full path
214 // to the directory.  If the package lives in c:\home\gopher\my\pkg then
215 // the pseudo-import path is _/c_/home/gopher/my/pkg.
216 // Using a pseudo-import path like this makes the ./ imports no longer
217 // a special case, so that all the code to deal with ordinary imports works
218 // automatically.
219 func dirToImportPath(dir string) string {
220         return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))
221 }
222
223 func makeImportValid(r rune) rune {
224         // Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.
225         const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
226         if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
227                 return '_'
228         }
229         return r
230 }
231
232 // loadImport scans the directory named by path, which must be an import path,
233 // but possibly a local import path (an absolute file system path or one beginning
234 // with ./ or ../).  A local relative path is interpreted relative to srcDir.
235 // It returns a *Package describing the package found in that directory.
236 func loadImport(path string, srcDir string, stk *importStack, importPos []token.Position) *Package {
237         stk.push(path)
238         defer stk.pop()
239
240         // Determine canonical identifier for this package.
241         // For a local import the identifier is the pseudo-import path
242         // we create from the full directory to the package.
243         // Otherwise it is the usual import path.
244         importPath := path
245         isLocal := build.IsLocalImport(path)
246         if isLocal {
247                 importPath = dirToImportPath(filepath.Join(srcDir, path))
248         }
249         if p := packageCache[importPath]; p != nil {
250                 if perr := disallowInternal(srcDir, p, stk); perr != p {
251                         return perr
252                 }
253                 return reusePackage(p, stk)
254         }
255
256         p := new(Package)
257         p.local = isLocal
258         p.ImportPath = importPath
259         packageCache[importPath] = p
260
261         // Load package.
262         // Import always returns bp != nil, even if an error occurs,
263         // in order to return partial information.
264         //
265         // TODO: After Go 1, decide when to pass build.AllowBinary here.
266         // See issue 3268 for mistakes to avoid.
267         bp, err := buildContext.Import(path, srcDir, build.ImportComment)
268         bp.ImportPath = importPath
269         if gobin != "" {
270                 bp.BinDir = gobin
271         }
272         if err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path {
273                 err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment)
274         }
275         p.load(stk, bp, err)
276         if p.Error != nil && len(importPos) > 0 {
277                 pos := importPos[0]
278                 pos.Filename = shortPath(pos.Filename)
279                 p.Error.Pos = pos.String()
280         }
281
282         if perr := disallowInternal(srcDir, p, stk); perr != p {
283                 return perr
284         }
285
286         return p
287 }
288
289 // reusePackage reuses package p to satisfy the import at the top
290 // of the import stack stk.  If this use causes an import loop,
291 // reusePackage updates p's error information to record the loop.
292 func reusePackage(p *Package, stk *importStack) *Package {
293         // We use p.imports==nil to detect a package that
294         // is in the midst of its own loadPackage call
295         // (all the recursion below happens before p.imports gets set).
296         if p.imports == nil {
297                 if p.Error == nil {
298                         p.Error = &PackageError{
299                                 ImportStack:   stk.copy(),
300                                 Err:           "import cycle not allowed",
301                                 isImportCycle: true,
302                         }
303                 }
304                 p.Incomplete = true
305         }
306         // Don't rewrite the import stack in the error if we have an import cycle.
307         // If we do, we'll lose the path that describes the cycle.
308         if p.Error != nil && !p.Error.isImportCycle && stk.shorterThan(p.Error.ImportStack) {
309                 p.Error.ImportStack = stk.copy()
310         }
311         return p
312 }
313
314 // disallowInternal checks that srcDir is allowed to import p.
315 // If the import is allowed, disallowInternal returns the original package p.
316 // If not, it returns a new package containing just an appropriate error.
317 func disallowInternal(srcDir string, p *Package, stk *importStack) *Package {
318         // golang.org/s/go14internal:
319         // An import of a path containing the element “internal”
320         // is disallowed if the importing code is outside the tree
321         // rooted at the parent of the “internal” directory.
322         //
323         // ... For Go 1.4, we will implement the rule first for $GOROOT, but not $GOPATH.
324
325         // Only applies to $GOROOT.
326         if !p.Standard {
327                 return p
328         }
329
330         // The stack includes p.ImportPath.
331         // If that's the only thing on the stack, we started
332         // with a name given on the command line, not an
333         // import. Anything listed on the command line is fine.
334         if len(*stk) == 1 {
335                 return p
336         }
337
338         // Check for "internal" element: four cases depending on begin of string and/or end of string.
339         i, ok := findInternal(p.ImportPath)
340         if !ok {
341                 return p
342         }
343
344         // Internal is present.
345         // Map import path back to directory corresponding to parent of internal.
346         if i > 0 {
347                 i-- // rewind over slash in ".../internal"
348         }
349         parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
350         if hasPathPrefix(filepath.ToSlash(srcDir), filepath.ToSlash(parent)) {
351                 return p
352         }
353
354         // Internal is present, and srcDir is outside parent's tree. Not allowed.
355         perr := *p
356         perr.Error = &PackageError{
357                 ImportStack: stk.copy(),
358                 Err:         "use of internal package not allowed",
359         }
360         perr.Incomplete = true
361         return &perr
362 }
363
364 // findInternal looks for the final "internal" path element in the given import path.
365 // If there isn't one, findInternal returns ok=false.
366 // Otherwise, findInternal returns ok=true and the index of the "internal".
367 func findInternal(path string) (index int, ok bool) {
368         // Four cases, depending on internal at start/end of string or not.
369         // The order matters: we must return the index of the final element,
370         // because the final one produces the most restrictive requirement
371         // on the importer.
372         switch {
373         case strings.HasSuffix(path, "/internal"):
374                 return len(path) - len("internal"), true
375         case strings.Contains(path, "/internal/"):
376                 return strings.LastIndex(path, "/internal/") + 1, true
377         case path == "internal", strings.HasPrefix(path, "internal/"):
378                 return 0, true
379         }
380         return 0, false
381 }
382
383 type targetDir int
384
385 const (
386         toRoot    targetDir = iota // to bin dir inside package root (default)
387         toTool                     // GOROOT/pkg/tool
388         toBin                      // GOROOT/bin
389         stalePath                  // the old import path; fail to build
390 )
391
392 // goTools is a map of Go program import path to install target directory.
393 var goTools = map[string]targetDir{
394         "cmd/addr2line":                        toTool,
395         "cmd/api":                              toTool,
396         "cmd/cgo":                              toTool,
397         "cmd/dist":                             toTool,
398         "cmd/fix":                              toTool,
399         "cmd/link":                             toTool,
400         "cmd/new5a":                            toTool,
401         "cmd/new6a":                            toTool,
402         "cmd/new8a":                            toTool,
403         "cmd/new9a":                            toTool,
404         "cmd/nm":                               toTool,
405         "cmd/objdump":                          toTool,
406         "cmd/objwriter":                        toTool,
407         "cmd/pack":                             toTool,
408         "cmd/pprof":                            toTool,
409         "cmd/yacc":                             toTool,
410         "golang.org/x/tools/cmd/cover":         toTool,
411         "golang.org/x/tools/cmd/godoc":         toBin,
412         "golang.org/x/tools/cmd/vet":           toTool,
413         "code.google.com/p/go.tools/cmd/cover": stalePath,
414         "code.google.com/p/go.tools/cmd/godoc": stalePath,
415         "code.google.com/p/go.tools/cmd/vet":   stalePath,
416 }
417
418 // expandScanner expands a scanner.List error into all the errors in the list.
419 // The default Error method only shows the first error.
420 func expandScanner(err error) error {
421         // Look for parser errors.
422         if err, ok := err.(scanner.ErrorList); ok {
423                 // Prepare error with \n before each message.
424                 // When printed in something like context: %v
425                 // this will put the leading file positions each on
426                 // its own line.  It will also show all the errors
427                 // instead of just the first, as err.Error does.
428                 var buf bytes.Buffer
429                 for _, e := range err {
430                         e.Pos.Filename = shortPath(e.Pos.Filename)
431                         buf.WriteString("\n")
432                         buf.WriteString(e.Error())
433                 }
434                 return errors.New(buf.String())
435         }
436         return err
437 }
438
439 var raceExclude = map[string]bool{
440         "runtime/race": true,
441         "runtime/cgo":  true,
442         "cmd/cgo":      true,
443         "syscall":      true,
444         "errors":       true,
445 }
446
447 var cgoExclude = map[string]bool{
448         "runtime/cgo": true,
449 }
450
451 var cgoSyscallExclude = map[string]bool{
452         "runtime/cgo":  true,
453         "runtime/race": true,
454 }
455
456 // load populates p using information from bp, err, which should
457 // be the result of calling build.Context.Import.
458 func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package {
459         p.copyBuild(bp)
460
461         // The localPrefix is the path we interpret ./ imports relative to.
462         // Synthesized main packages sometimes override this.
463         p.localPrefix = dirToImportPath(p.Dir)
464
465         if err != nil {
466                 p.Incomplete = true
467                 err = expandScanner(err)
468                 p.Error = &PackageError{
469                         ImportStack: stk.copy(),
470                         Err:         err.Error(),
471                 }
472                 return p
473         }
474
475         if p.Name == "main" {
476                 // Report an error when the old code.google.com/p/go.tools paths are used.
477                 if goTools[p.ImportPath] == stalePath {
478                         newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1)
479                         e := fmt.Sprintf("the %v command has moved; use %v instead.", p.ImportPath, newPath)
480                         p.Error = &PackageError{Err: e}
481                         return p
482                 }
483                 _, elem := filepath.Split(p.Dir)
484                 full := buildContext.GOOS + "_" + buildContext.GOARCH + "/" + elem
485                 if buildContext.GOOS != toolGOOS || buildContext.GOARCH != toolGOARCH {
486                         // Install cross-compiled binaries to subdirectories of bin.
487                         elem = full
488                 }
489                 if p.build.BinDir != gobin && goTools[p.ImportPath] == toBin {
490                         // Override BinDir.
491                         // This is from a subrepo but installs to $GOROOT/bin
492                         // by default anyway (like godoc).
493                         p.target = filepath.Join(gorootBin, elem)
494                 } else if p.build.BinDir != "" {
495                         // Install to GOBIN or bin of GOPATH entry.
496                         p.target = filepath.Join(p.build.BinDir, elem)
497                 }
498                 if goTools[p.ImportPath] == toTool {
499                         // This is for 'go tool'.
500                         // Override all the usual logic and force it into the tool directory.
501                         p.target = filepath.Join(gorootPkg, "tool", full)
502                 }
503                 if p.target != "" && buildContext.GOOS == "windows" {
504                         p.target += ".exe"
505                 }
506         } else if p.local {
507                 // Local import turned into absolute path.
508                 // No permanent install target.
509                 p.target = ""
510         } else {
511                 p.target = p.build.PkgObj
512         }
513
514         importPaths := p.Imports
515         // Packages that use cgo import runtime/cgo implicitly.
516         // Packages that use cgo also import syscall implicitly,
517         // to wrap errno.
518         // Exclude certain packages to avoid circular dependencies.
519         if len(p.CgoFiles) > 0 && (!p.Standard || !cgoExclude[p.ImportPath]) {
520                 importPaths = append(importPaths, "runtime/cgo")
521         }
522         if len(p.CgoFiles) > 0 && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
523                 importPaths = append(importPaths, "syscall")
524         }
525         // Everything depends on runtime, except runtime and unsafe.
526         if !p.Standard || (p.ImportPath != "runtime" && p.ImportPath != "unsafe") {
527                 importPaths = append(importPaths, "runtime")
528                 // When race detection enabled everything depends on runtime/race.
529                 // Exclude certain packages to avoid circular dependencies.
530                 if buildRace && (!p.Standard || !raceExclude[p.ImportPath]) {
531                         importPaths = append(importPaths, "runtime/race")
532                 }
533                 // On ARM with GOARM=5, everything depends on math for the link.
534                 if p.ImportPath == "main" && goarch == "arm" {
535                         importPaths = append(importPaths, "math")
536                 }
537         }
538
539         // Build list of full paths to all Go files in the package,
540         // for use by commands like go fmt.
541         p.gofiles = stringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)
542         for i := range p.gofiles {
543                 p.gofiles[i] = filepath.Join(p.Dir, p.gofiles[i])
544         }
545         sort.Strings(p.gofiles)
546
547         p.sfiles = stringList(p.SFiles)
548         for i := range p.sfiles {
549                 p.sfiles[i] = filepath.Join(p.Dir, p.sfiles[i])
550         }
551         sort.Strings(p.sfiles)
552
553         p.allgofiles = stringList(p.IgnoredGoFiles)
554         for i := range p.allgofiles {
555                 p.allgofiles[i] = filepath.Join(p.Dir, p.allgofiles[i])
556         }
557         p.allgofiles = append(p.allgofiles, p.gofiles...)
558         sort.Strings(p.allgofiles)
559
560         // Check for case-insensitive collision of input files.
561         // To avoid problems on case-insensitive files, we reject any package
562         // where two different input files have equal names under a case-insensitive
563         // comparison.
564         f1, f2 := foldDup(stringList(
565                 p.GoFiles,
566                 p.CgoFiles,
567                 p.IgnoredGoFiles,
568                 p.CFiles,
569                 p.CXXFiles,
570                 p.MFiles,
571                 p.HFiles,
572                 p.SFiles,
573                 p.SysoFiles,
574                 p.SwigFiles,
575                 p.SwigCXXFiles,
576                 p.TestGoFiles,
577                 p.XTestGoFiles,
578         ))
579         if f1 != "" {
580                 p.Error = &PackageError{
581                         ImportStack: stk.copy(),
582                         Err:         fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2),
583                 }
584                 return p
585         }
586
587         // Build list of imported packages and full dependency list.
588         imports := make([]*Package, 0, len(p.Imports))
589         deps := make(map[string]*Package)
590         for i, path := range importPaths {
591                 if path == "C" {
592                         continue
593                 }
594                 p1 := loadImport(path, p.Dir, stk, p.build.ImportPos[path])
595                 if p1.local {
596                         if !p.local && p.Error == nil {
597                                 p.Error = &PackageError{
598                                         ImportStack: stk.copy(),
599                                         Err:         fmt.Sprintf("local import %q in non-local package", path),
600                                 }
601                                 pos := p.build.ImportPos[path]
602                                 if len(pos) > 0 {
603                                         p.Error.Pos = pos[0].String()
604                                 }
605                         }
606                         path = p1.ImportPath
607                         importPaths[i] = path
608                 }
609                 deps[path] = p1
610                 imports = append(imports, p1)
611                 for _, dep := range p1.deps {
612                         deps[dep.ImportPath] = dep
613                 }
614                 if p1.Incomplete {
615                         p.Incomplete = true
616                 }
617         }
618         p.imports = imports
619
620         p.Deps = make([]string, 0, len(deps))
621         for dep := range deps {
622                 p.Deps = append(p.Deps, dep)
623         }
624         sort.Strings(p.Deps)
625         for _, dep := range p.Deps {
626                 p1 := deps[dep]
627                 if p1 == nil {
628                         panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath)
629                 }
630                 p.deps = append(p.deps, p1)
631                 if p1.Error != nil {
632                         p.DepsErrors = append(p.DepsErrors, p1.Error)
633                 }
634         }
635
636         // unsafe is a fake package.
637         if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") {
638                 p.target = ""
639         }
640         p.Target = p.target
641
642         // The gc toolchain only permits C source files with cgo.
643         if len(p.CFiles) > 0 && !p.usesCgo() && buildContext.Compiler == "gc" {
644                 p.Error = &PackageError{
645                         ImportStack: stk.copy(),
646                         Err:         fmt.Sprintf("C source files not allowed when not using cgo: %s", strings.Join(p.CFiles, " ")),
647                 }
648                 return p
649         }
650
651         // In the absence of errors lower in the dependency tree,
652         // check for case-insensitive collisions of import paths.
653         if len(p.DepsErrors) == 0 {
654                 dep1, dep2 := foldDup(p.Deps)
655                 if dep1 != "" {
656                         p.Error = &PackageError{
657                                 ImportStack: stk.copy(),
658                                 Err:         fmt.Sprintf("case-insensitive import collision: %q and %q", dep1, dep2),
659                         }
660                         return p
661                 }
662         }
663
664         return p
665 }
666
667 // usesSwig reports whether the package needs to run SWIG.
668 func (p *Package) usesSwig() bool {
669         return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0
670 }
671
672 // usesCgo reports whether the package needs to run cgo
673 func (p *Package) usesCgo() bool {
674         return len(p.CgoFiles) > 0
675 }
676
677 // packageList returns the list of packages in the dag rooted at roots
678 // as visited in a depth-first post-order traversal.
679 func packageList(roots []*Package) []*Package {
680         seen := map[*Package]bool{}
681         all := []*Package{}
682         var walk func(*Package)
683         walk = func(p *Package) {
684                 if seen[p] {
685                         return
686                 }
687                 seen[p] = true
688                 for _, p1 := range p.imports {
689                         walk(p1)
690                 }
691                 all = append(all, p)
692         }
693         for _, root := range roots {
694                 walk(root)
695         }
696         return all
697 }
698
699 // computeStale computes the Stale flag in the package dag that starts
700 // at the named pkgs (command-line arguments).
701 func computeStale(pkgs ...*Package) {
702         topRoot := map[string]bool{}
703         for _, p := range pkgs {
704                 topRoot[p.Root] = true
705         }
706
707         for _, p := range packageList(pkgs) {
708                 p.Stale = isStale(p, topRoot)
709         }
710 }
711
712 // The runtime version string takes one of two forms:
713 // "go1.X[.Y]" for Go releases, and "devel +hash" at tip.
714 // Determine whether we are in a released copy by
715 // inspecting the version.
716 var isGoRelease = strings.HasPrefix(runtime.Version(), "go1")
717
718 // isStale reports whether package p needs to be rebuilt.
719 func isStale(p *Package, topRoot map[string]bool) bool {
720         if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") {
721                 // fake, builtin package
722                 return false
723         }
724         if p.Error != nil {
725                 return true
726         }
727
728         // A package without Go sources means we only found
729         // the installed .a file.  Since we don't know how to rebuild
730         // it, it can't be stale, even if -a is set.  This enables binary-only
731         // distributions of Go packages, although such binaries are
732         // only useful with the specific version of the toolchain that
733         // created them.
734         if len(p.gofiles) == 0 && !p.usesSwig() {
735                 return false
736         }
737
738         // If we are running a release copy of Go, do not rebuild the standard packages.
739         // They may not be writable anyway, but they are certainly not changing.
740         // This makes 'go build -a' skip the standard packages when using an official release.
741         // See issue 4106 and issue 8290.
742         pkgBuildA := buildA
743         if p.Standard && isGoRelease {
744                 pkgBuildA = false
745         }
746
747         if pkgBuildA || p.target == "" || p.Stale {
748                 return true
749         }
750
751         // Package is stale if completely unbuilt.
752         var built time.Time
753         if fi, err := os.Stat(p.target); err == nil {
754                 built = fi.ModTime()
755         }
756         if built.IsZero() {
757                 return true
758         }
759
760         olderThan := func(file string) bool {
761                 fi, err := os.Stat(file)
762                 return err != nil || fi.ModTime().After(built)
763         }
764
765         // Package is stale if a dependency is, or if a dependency is newer.
766         for _, p1 := range p.deps {
767                 if p1.Stale || p1.target != "" && olderThan(p1.target) {
768                         return true
769                 }
770         }
771
772         // As a courtesy to developers installing new versions of the compiler
773         // frequently, define that packages are stale if they are
774         // older than the compiler, and commands if they are older than
775         // the linker.  This heuristic will not work if the binaries are
776         // back-dated, as some binary distributions may do, but it does handle
777         // a very common case.
778         // See issue 3036.
779         // Assume code in $GOROOT is up to date, since it may not be writeable.
780         // See issue 4106.
781         if p.Root != goroot {
782                 if olderThan(buildToolchain.compiler()) {
783                         return true
784                 }
785                 if p.build.IsCommand() && olderThan(buildToolchain.linker()) {
786                         return true
787                 }
788         }
789
790         // Have installed copy, probably built using current compilers,
791         // and built after its imported packages.  The only reason now
792         // that we'd have to rebuild it is if the sources were newer than
793         // the package.   If a package p is not in the same tree as any
794         // package named on the command-line, assume it is up-to-date
795         // no matter what the modification times on the source files indicate.
796         // This avoids rebuilding $GOROOT packages when people are
797         // working outside the Go root, and it effectively makes each tree
798         // listed in $GOPATH a separate compilation world.
799         // See issue 3149.
800         if p.Root != "" && !topRoot[p.Root] {
801                 return false
802         }
803
804         srcs := stringList(p.GoFiles, p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.SFiles, p.CgoFiles, p.SysoFiles, p.SwigFiles, p.SwigCXXFiles)
805         for _, src := range srcs {
806                 if olderThan(filepath.Join(p.Dir, src)) {
807                         return true
808                 }
809         }
810
811         return false
812 }
813
814 var cwd, _ = os.Getwd()
815
816 var cmdCache = map[string]*Package{}
817
818 // loadPackage is like loadImport but is used for command-line arguments,
819 // not for paths found in import statements.  In addition to ordinary import paths,
820 // loadPackage accepts pseudo-paths beginning with cmd/ to denote commands
821 // in the Go command directory, as well as paths to those directories.
822 func loadPackage(arg string, stk *importStack) *Package {
823         if build.IsLocalImport(arg) {
824                 dir := arg
825                 if !filepath.IsAbs(dir) {
826                         if abs, err := filepath.Abs(dir); err == nil {
827                                 // interpret relative to current directory
828                                 dir = abs
829                         }
830                 }
831                 if sub, ok := hasSubdir(gorootSrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") {
832                         arg = sub
833                 }
834         }
835         if strings.HasPrefix(arg, "cmd/") && !strings.Contains(arg[4:], "/") {
836                 if p := cmdCache[arg]; p != nil {
837                         return p
838                 }
839                 stk.push(arg)
840                 defer stk.pop()
841
842                 bp, err := buildContext.ImportDir(filepath.Join(gorootSrc, arg), 0)
843                 bp.ImportPath = arg
844                 bp.Goroot = true
845                 bp.BinDir = gorootBin
846                 if gobin != "" {
847                         bp.BinDir = gobin
848                 }
849                 bp.Root = goroot
850                 bp.SrcRoot = gorootSrc
851                 p := new(Package)
852                 cmdCache[arg] = p
853                 p.load(stk, bp, err)
854                 if p.Error == nil && p.Name != "main" {
855                         p.Error = &PackageError{
856                                 ImportStack: stk.copy(),
857                                 Err:         fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir),
858                         }
859                 }
860                 return p
861         }
862
863         // Wasn't a command; must be a package.
864         // If it is a local import path but names a standard package,
865         // we treat it as if the user specified the standard package.
866         // This lets you run go test ./ioutil in package io and be
867         // referring to io/ioutil rather than a hypothetical import of
868         // "./ioutil".
869         if build.IsLocalImport(arg) {
870                 bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly)
871                 if bp.ImportPath != "" && bp.ImportPath != "." {
872                         arg = bp.ImportPath
873                 }
874         }
875
876         return loadImport(arg, cwd, stk, nil)
877 }
878
879 // packages returns the packages named by the
880 // command line arguments 'args'.  If a named package
881 // cannot be loaded at all (for example, if the directory does not exist),
882 // then packages prints an error and does not include that
883 // package in the results.  However, if errors occur trying
884 // to load dependencies of a named package, the named
885 // package is still returned, with p.Incomplete = true
886 // and details in p.DepsErrors.
887 func packages(args []string) []*Package {
888         var pkgs []*Package
889         for _, pkg := range packagesAndErrors(args) {
890                 if pkg.Error != nil {
891                         errorf("can't load package: %s", pkg.Error)
892                         continue
893                 }
894                 pkgs = append(pkgs, pkg)
895         }
896         return pkgs
897 }
898
899 // packagesAndErrors is like 'packages' but returns a
900 // *Package for every argument, even the ones that
901 // cannot be loaded at all.
902 // The packages that fail to load will have p.Error != nil.
903 func packagesAndErrors(args []string) []*Package {
904         if len(args) > 0 && strings.HasSuffix(args[0], ".go") {
905                 return []*Package{goFilesPackage(args)}
906         }
907
908         args = importPaths(args)
909         var pkgs []*Package
910         var stk importStack
911         var set = make(map[string]bool)
912
913         for _, arg := range args {
914                 if !set[arg] {
915                         pkgs = append(pkgs, loadPackage(arg, &stk))
916                         set[arg] = true
917                 }
918         }
919         computeStale(pkgs...)
920
921         return pkgs
922 }
923
924 // packagesForBuild is like 'packages' but fails if any of
925 // the packages or their dependencies have errors
926 // (cannot be built).
927 func packagesForBuild(args []string) []*Package {
928         pkgs := packagesAndErrors(args)
929         printed := map[*PackageError]bool{}
930         for _, pkg := range pkgs {
931                 if pkg.Error != nil {
932                         errorf("can't load package: %s", pkg.Error)
933                 }
934                 for _, err := range pkg.DepsErrors {
935                         // Since these are errors in dependencies,
936                         // the same error might show up multiple times,
937                         // once in each package that depends on it.
938                         // Only print each once.
939                         if !printed[err] {
940                                 printed[err] = true
941                                 errorf("%s", err)
942                         }
943                 }
944         }
945         exitIfErrors()
946         return pkgs
947 }
948
949 // hasSubdir reports whether dir is a subdirectory of
950 // (possibly multiple levels below) root.
951 // If so, it sets rel to the path fragment that must be
952 // appended to root to reach dir.
953 func hasSubdir(root, dir string) (rel string, ok bool) {
954         if p, err := filepath.EvalSymlinks(root); err == nil {
955                 root = p
956         }
957         if p, err := filepath.EvalSymlinks(dir); err == nil {
958                 dir = p
959         }
960         const sep = string(filepath.Separator)
961         root = filepath.Clean(root)
962         if !strings.HasSuffix(root, sep) {
963                 root += sep
964         }
965         dir = filepath.Clean(dir)
966         if !strings.HasPrefix(dir, root) {
967                 return "", false
968         }
969         return filepath.ToSlash(dir[len(root):]), true
970 }