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