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