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