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