Source file src/cmd/go/internal/load/pkg.go

Documentation: cmd/go/internal/load

     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 load loads packages.
     6  package load
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"go/build"
    12  	"go/token"
    13  	"io/ioutil"
    14  	"os"
    15  	pathpkg "path"
    16  	"path/filepath"
    17  	"sort"
    18  	"strconv"
    19  	"strings"
    20  	"unicode"
    21  	"unicode/utf8"
    22  
    23  	"cmd/go/internal/base"
    24  	"cmd/go/internal/cfg"
    25  	"cmd/go/internal/modinfo"
    26  	"cmd/go/internal/search"
    27  	"cmd/go/internal/str"
    28  )
    29  
    30  var (
    31  	// module initialization hook; never nil, no-op if module use is disabled
    32  	ModInit func()
    33  
    34  	// module hooks; nil if module use is disabled
    35  	ModBinDir            func() string                                       // return effective bin directory
    36  	ModLookup            func(path string) (dir, realPath string, err error) // lookup effective meaning of import
    37  	ModPackageModuleInfo func(path string) *modinfo.ModulePublic             // return module info for Package struct
    38  	ModImportPaths       func(args []string) []*search.Match                 // expand import paths
    39  	ModPackageBuildInfo  func(main string, deps []string) string             // return module info to embed in binary
    40  	ModInfoProg          func(info string) []byte                            // wrap module info in .go code for binary
    41  	ModImportFromFiles   func([]string)                                      // update go.mod to add modules for imports in these files
    42  	ModDirImportPath     func(string) string                                 // return effective import path for directory
    43  )
    44  
    45  var IgnoreImports bool // control whether we ignore imports in packages
    46  
    47  // A Package describes a single package found in a directory.
    48  type Package struct {
    49  	PackagePublic                 // visible in 'go list'
    50  	Internal      PackageInternal // for use inside go command only
    51  }
    52  
    53  type PackagePublic struct {
    54  	// Note: These fields are part of the go command's public API.
    55  	// See list.go. It is okay to add fields, but not to change or
    56  	// remove existing ones. Keep in sync with list.go
    57  	Dir           string                `json:",omitempty"` // directory containing package sources
    58  	ImportPath    string                `json:",omitempty"` // import path of package in dir
    59  	ImportComment string                `json:",omitempty"` // path in import comment on package statement
    60  	Name          string                `json:",omitempty"` // package name
    61  	Doc           string                `json:",omitempty"` // package documentation string
    62  	Target        string                `json:",omitempty"` // installed target for this package (may be executable)
    63  	Shlib         string                `json:",omitempty"` // the shared library that contains this package (only set when -linkshared)
    64  	Root          string                `json:",omitempty"` // Go root or Go path dir containing this package
    65  	ConflictDir   string                `json:",omitempty"` // Dir is hidden by this other directory
    66  	ForTest       string                `json:",omitempty"` // package is only for use in named test
    67  	Export        string                `json:",omitempty"` // file containing export data (set by go list -export)
    68  	Module        *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any
    69  	Match         []string              `json:",omitempty"` // command-line patterns matching this package
    70  	Goroot        bool                  `json:",omitempty"` // is this package found in the Go root?
    71  	Standard      bool                  `json:",omitempty"` // is this package part of the standard Go library?
    72  	DepOnly       bool                  `json:",omitempty"` // package is only as a dependency, not explicitly listed
    73  	BinaryOnly    bool                  `json:",omitempty"` // package cannot be recompiled
    74  	Incomplete    bool                  `json:",omitempty"` // was there an error loading this package or dependencies?
    75  
    76  	// Stale and StaleReason remain here *only* for the list command.
    77  	// They are only initialized in preparation for list execution.
    78  	// The regular build determines staleness on the fly during action execution.
    79  	Stale       bool   `json:",omitempty"` // would 'go install' do anything for this package?
    80  	StaleReason string `json:",omitempty"` // why is Stale true?
    81  
    82  	// Source files
    83  	// If you add to this list you MUST add to p.AllFiles (below) too.
    84  	// Otherwise file name security lists will not apply to any new additions.
    85  	GoFiles         []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
    86  	CgoFiles        []string `json:",omitempty"` // .go source files that import "C"
    87  	CompiledGoFiles []string `json:",omitempty"` // .go output from running cgo on CgoFiles
    88  	IgnoredGoFiles  []string `json:",omitempty"` // .go source files ignored due to build constraints
    89  	CFiles          []string `json:",omitempty"` // .c source files
    90  	CXXFiles        []string `json:",omitempty"` // .cc, .cpp and .cxx source files
    91  	MFiles          []string `json:",omitempty"` // .m source files
    92  	HFiles          []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files
    93  	FFiles          []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files
    94  	SFiles          []string `json:",omitempty"` // .s source files
    95  	SwigFiles       []string `json:",omitempty"` // .swig files
    96  	SwigCXXFiles    []string `json:",omitempty"` // .swigcxx files
    97  	SysoFiles       []string `json:",omitempty"` // .syso system object files added to package
    98  
    99  	// Cgo directives
   100  	CgoCFLAGS    []string `json:",omitempty"` // cgo: flags for C compiler
   101  	CgoCPPFLAGS  []string `json:",omitempty"` // cgo: flags for C preprocessor
   102  	CgoCXXFLAGS  []string `json:",omitempty"` // cgo: flags for C++ compiler
   103  	CgoFFLAGS    []string `json:",omitempty"` // cgo: flags for Fortran compiler
   104  	CgoLDFLAGS   []string `json:",omitempty"` // cgo: flags for linker
   105  	CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names
   106  
   107  	// Dependency information
   108  	Imports   []string          `json:",omitempty"` // import paths used by this package
   109  	ImportMap map[string]string `json:",omitempty"` // map from source import to ImportPath (identity entries omitted)
   110  	Deps      []string          `json:",omitempty"` // all (recursively) imported dependencies
   111  
   112  	// Error information
   113  	// Incomplete is above, packed into the other bools
   114  	Error      *PackageError   `json:",omitempty"` // error loading this package (not dependencies)
   115  	DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies
   116  
   117  	// Test information
   118  	// If you add to this list you MUST add to p.AllFiles (below) too.
   119  	// Otherwise file name security lists will not apply to any new additions.
   120  	TestGoFiles  []string `json:",omitempty"` // _test.go files in package
   121  	TestImports  []string `json:",omitempty"` // imports from TestGoFiles
   122  	XTestGoFiles []string `json:",omitempty"` // _test.go files outside package
   123  	XTestImports []string `json:",omitempty"` // imports from XTestGoFiles
   124  }
   125  
   126  // AllFiles returns the names of all the files considered for the package.
   127  // This is used for sanity and security checks, so we include all files,
   128  // even IgnoredGoFiles, because some subcommands consider them.
   129  // The go/build package filtered others out (like foo_wrongGOARCH.s)
   130  // and that's OK.
   131  func (p *Package) AllFiles() []string {
   132  	return str.StringList(
   133  		p.GoFiles,
   134  		p.CgoFiles,
   135  		// no p.CompiledGoFiles, because they are from GoFiles or generated by us
   136  		p.IgnoredGoFiles,
   137  		p.CFiles,
   138  		p.CXXFiles,
   139  		p.MFiles,
   140  		p.HFiles,
   141  		p.FFiles,
   142  		p.SFiles,
   143  		p.SwigFiles,
   144  		p.SwigCXXFiles,
   145  		p.SysoFiles,
   146  		p.TestGoFiles,
   147  		p.XTestGoFiles,
   148  	)
   149  }
   150  
   151  // Desc returns the package "description", for use in b.showOutput.
   152  func (p *Package) Desc() string {
   153  	if p.ForTest != "" {
   154  		return p.ImportPath + " [" + p.ForTest + ".test]"
   155  	}
   156  	return p.ImportPath
   157  }
   158  
   159  type PackageInternal struct {
   160  	// Unexported fields are not part of the public API.
   161  	Build             *build.Package
   162  	Imports           []*Package           // this package's direct imports
   163  	CompiledImports   []string             // additional Imports necessary when using CompiledGoFiles (all from standard library)
   164  	RawImports        []string             // this package's original imports as they appear in the text of the program
   165  	ForceLibrary      bool                 // this package is a library (even if named "main")
   166  	CmdlineFiles      bool                 // package built from files listed on command line
   167  	CmdlinePkg        bool                 // package listed on command line
   168  	CmdlinePkgLiteral bool                 // package listed as literal on command line (not via wildcard)
   169  	Local             bool                 // imported via local path (./ or ../)
   170  	LocalPrefix       string               // interpret ./ and ../ imports relative to this prefix
   171  	ExeName           string               // desired name for temporary executable
   172  	CoverMode         string               // preprocess Go source files with the coverage tool in this mode
   173  	CoverVars         map[string]*CoverVar // variables created by coverage analysis
   174  	OmitDebug         bool                 // tell linker not to write debug information
   175  	GobinSubdir       bool                 // install target would be subdir of GOBIN
   176  	BuildInfo         string               // add this info to package main
   177  	TestmainGo        *[]byte              // content for _testmain.go
   178  
   179  	Asmflags   []string // -asmflags for this package
   180  	Gcflags    []string // -gcflags for this package
   181  	Ldflags    []string // -ldflags for this package
   182  	Gccgoflags []string // -gccgoflags for this package
   183  }
   184  
   185  type NoGoError struct {
   186  	Package *Package
   187  }
   188  
   189  func (e *NoGoError) Error() string {
   190  	// Count files beginning with _ and ., which we will pretend don't exist at all.
   191  	dummy := 0
   192  	for _, name := range e.Package.IgnoredGoFiles {
   193  		if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") {
   194  			dummy++
   195  		}
   196  	}
   197  
   198  	if len(e.Package.IgnoredGoFiles) > dummy {
   199  		// Go files exist, but they were ignored due to build constraints.
   200  		return "build constraints exclude all Go files in " + e.Package.Dir
   201  	}
   202  	if len(e.Package.TestGoFiles)+len(e.Package.XTestGoFiles) > 0 {
   203  		// Test Go files exist, but we're not interested in them.
   204  		// The double-negative is unfortunate but we want e.Package.Dir
   205  		// to appear at the end of error message.
   206  		return "no non-test Go files in " + e.Package.Dir
   207  	}
   208  	return "no Go files in " + e.Package.Dir
   209  }
   210  
   211  // Resolve returns the resolved version of imports,
   212  // which should be p.TestImports or p.XTestImports, NOT p.Imports.
   213  // The imports in p.TestImports and p.XTestImports are not recursively
   214  // loaded during the initial load of p, so they list the imports found in
   215  // the source file, but most processing should be over the vendor-resolved
   216  // import paths. We do this resolution lazily both to avoid file system work
   217  // and because the eventual real load of the test imports (during 'go test')
   218  // can produce better error messages if it starts with the original paths.
   219  // The initial load of p loads all the non-test imports and rewrites
   220  // the vendored paths, so nothing should ever call p.vendored(p.Imports).
   221  func (p *Package) Resolve(imports []string) []string {
   222  	if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] {
   223  		panic("internal error: p.Resolve(p.Imports) called")
   224  	}
   225  	seen := make(map[string]bool)
   226  	var all []string
   227  	for _, path := range imports {
   228  		path = ResolveImportPath(p, path)
   229  		if !seen[path] {
   230  			seen[path] = true
   231  			all = append(all, path)
   232  		}
   233  	}
   234  	sort.Strings(all)
   235  	return all
   236  }
   237  
   238  // CoverVar holds the name of the generated coverage variables targeting the named file.
   239  type CoverVar struct {
   240  	File string // local file name
   241  	Var  string // name of count struct
   242  }
   243  
   244  func (p *Package) copyBuild(pp *build.Package) {
   245  	p.Internal.Build = pp
   246  
   247  	if pp.PkgTargetRoot != "" && cfg.BuildPkgdir != "" {
   248  		old := pp.PkgTargetRoot
   249  		pp.PkgRoot = cfg.BuildPkgdir
   250  		pp.PkgTargetRoot = cfg.BuildPkgdir
   251  		pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old))
   252  	}
   253  
   254  	p.Dir = pp.Dir
   255  	p.ImportPath = pp.ImportPath
   256  	p.ImportComment = pp.ImportComment
   257  	p.Name = pp.Name
   258  	p.Doc = pp.Doc
   259  	p.Root = pp.Root
   260  	p.ConflictDir = pp.ConflictDir
   261  	p.BinaryOnly = pp.BinaryOnly
   262  
   263  	// TODO? Target
   264  	p.Goroot = pp.Goroot
   265  	p.Standard = p.Goroot && p.ImportPath != "" && search.IsStandardImportPath(p.ImportPath)
   266  	p.GoFiles = pp.GoFiles
   267  	p.CgoFiles = pp.CgoFiles
   268  	p.IgnoredGoFiles = pp.IgnoredGoFiles
   269  	p.CFiles = pp.CFiles
   270  	p.CXXFiles = pp.CXXFiles
   271  	p.MFiles = pp.MFiles
   272  	p.HFiles = pp.HFiles
   273  	p.FFiles = pp.FFiles
   274  	p.SFiles = pp.SFiles
   275  	p.SwigFiles = pp.SwigFiles
   276  	p.SwigCXXFiles = pp.SwigCXXFiles
   277  	p.SysoFiles = pp.SysoFiles
   278  	p.CgoCFLAGS = pp.CgoCFLAGS
   279  	p.CgoCPPFLAGS = pp.CgoCPPFLAGS
   280  	p.CgoCXXFLAGS = pp.CgoCXXFLAGS
   281  	p.CgoFFLAGS = pp.CgoFFLAGS
   282  	p.CgoLDFLAGS = pp.CgoLDFLAGS
   283  	p.CgoPkgConfig = pp.CgoPkgConfig
   284  	// We modify p.Imports in place, so make copy now.
   285  	p.Imports = make([]string, len(pp.Imports))
   286  	copy(p.Imports, pp.Imports)
   287  	p.Internal.RawImports = pp.Imports
   288  	p.TestGoFiles = pp.TestGoFiles
   289  	p.TestImports = pp.TestImports
   290  	p.XTestGoFiles = pp.XTestGoFiles
   291  	p.XTestImports = pp.XTestImports
   292  	if IgnoreImports {
   293  		p.Imports = nil
   294  		p.Internal.RawImports = nil
   295  		p.TestImports = nil
   296  		p.XTestImports = nil
   297  	}
   298  }
   299  
   300  // A PackageError describes an error loading information about a package.
   301  type PackageError struct {
   302  	ImportStack   []string // shortest path from package named on command line to this one
   303  	Pos           string   // position of error
   304  	Err           string   // the error itself
   305  	IsImportCycle bool     `json:"-"` // the error is an import cycle
   306  	Hard          bool     `json:"-"` // whether the error is soft or hard; soft errors are ignored in some places
   307  }
   308  
   309  func (p *PackageError) Error() string {
   310  	// Import cycles deserve special treatment.
   311  	if p.IsImportCycle {
   312  		return fmt.Sprintf("%s\npackage %s\n", p.Err, strings.Join(p.ImportStack, "\n\timports "))
   313  	}
   314  	if p.Pos != "" {
   315  		// Omit import stack. The full path to the file where the error
   316  		// is the most important thing.
   317  		return p.Pos + ": " + p.Err
   318  	}
   319  	if len(p.ImportStack) == 0 {
   320  		return p.Err
   321  	}
   322  	return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err
   323  }
   324  
   325  // An ImportStack is a stack of import paths, possibly with the suffix " (test)" appended.
   326  // The import path of a test package is the import path of the corresponding
   327  // non-test package with the suffix "_test" added.
   328  type ImportStack []string
   329  
   330  func (s *ImportStack) Push(p string) {
   331  	*s = append(*s, p)
   332  }
   333  
   334  func (s *ImportStack) Pop() {
   335  	*s = (*s)[0 : len(*s)-1]
   336  }
   337  
   338  func (s *ImportStack) Copy() []string {
   339  	return append([]string{}, *s...)
   340  }
   341  
   342  // shorterThan reports whether sp is shorter than t.
   343  // We use this to record the shortest import sequence
   344  // that leads to a particular package.
   345  func (sp *ImportStack) shorterThan(t []string) bool {
   346  	s := *sp
   347  	if len(s) != len(t) {
   348  		return len(s) < len(t)
   349  	}
   350  	// If they are the same length, settle ties using string ordering.
   351  	for i := range s {
   352  		if s[i] != t[i] {
   353  			return s[i] < t[i]
   354  		}
   355  	}
   356  	return false // they are equal
   357  }
   358  
   359  // packageCache is a lookup cache for loadPackage,
   360  // so that if we look up a package multiple times
   361  // we return the same pointer each time.
   362  var packageCache = map[string]*Package{}
   363  
   364  func ClearPackageCache() {
   365  	for name := range packageCache {
   366  		delete(packageCache, name)
   367  	}
   368  }
   369  
   370  func ClearPackageCachePartial(args []string) {
   371  	for _, arg := range args {
   372  		p := packageCache[arg]
   373  		if p != nil {
   374  			delete(packageCache, p.Dir)
   375  			delete(packageCache, p.ImportPath)
   376  		}
   377  	}
   378  }
   379  
   380  // ReloadPackageNoFlags is like LoadPackageNoFlags but makes sure
   381  // not to use the package cache.
   382  // It is only for use by GOPATH-based "go get".
   383  // TODO(rsc): When GOPATH-based "go get" is removed, delete this function.
   384  func ReloadPackageNoFlags(arg string, stk *ImportStack) *Package {
   385  	p := packageCache[arg]
   386  	if p != nil {
   387  		delete(packageCache, p.Dir)
   388  		delete(packageCache, p.ImportPath)
   389  	}
   390  	return LoadPackageNoFlags(arg, stk)
   391  }
   392  
   393  // dirToImportPath returns the pseudo-import path we use for a package
   394  // outside the Go path. It begins with _/ and then contains the full path
   395  // to the directory. If the package lives in c:\home\gopher\my\pkg then
   396  // the pseudo-import path is _/c_/home/gopher/my/pkg.
   397  // Using a pseudo-import path like this makes the ./ imports no longer
   398  // a special case, so that all the code to deal with ordinary imports works
   399  // automatically.
   400  func dirToImportPath(dir string) string {
   401  	return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir)))
   402  }
   403  
   404  func makeImportValid(r rune) rune {
   405  	// Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport.
   406  	const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD"
   407  	if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) {
   408  		return '_'
   409  	}
   410  	return r
   411  }
   412  
   413  // Mode flags for loadImport and download (in get.go).
   414  const (
   415  	// ResolveImport means that loadImport should do import path expansion.
   416  	// That is, ResolveImport means that the import path came from
   417  	// a source file and has not been expanded yet to account for
   418  	// vendoring or possible module adjustment.
   419  	// Every import path should be loaded initially with ResolveImport,
   420  	// and then the expanded version (for example with the /vendor/ in it)
   421  	// gets recorded as the canonical import path. At that point, future loads
   422  	// of that package must not pass ResolveImport, because
   423  	// disallowVendor will reject direct use of paths containing /vendor/.
   424  	ResolveImport = 1 << iota
   425  
   426  	// ResolveModule is for download (part of "go get") and indicates
   427  	// that the module adjustment should be done, but not vendor adjustment.
   428  	ResolveModule
   429  
   430  	// GetTestDeps is for download (part of "go get") and indicates
   431  	// that test dependencies should be fetched too.
   432  	GetTestDeps
   433  )
   434  
   435  // LoadImport scans the directory named by path, which must be an import path,
   436  // but possibly a local import path (an absolute file system path or one beginning
   437  // with ./ or ../). A local relative path is interpreted relative to srcDir.
   438  // It returns a *Package describing the package found in that directory.
   439  // LoadImport does not set tool flags and should only be used by
   440  // this package, as part of a bigger load operation, and by GOPATH-based "go get".
   441  // TODO(rsc): When GOPATH-based "go get" is removed, unexport this function.
   442  func LoadImport(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package {
   443  	if path == "" {
   444  		panic("LoadImport called with empty package path")
   445  	}
   446  
   447  	stk.Push(path)
   448  	defer stk.Pop()
   449  
   450  	if strings.HasPrefix(path, "mod/") {
   451  		// Paths beginning with "mod/" might accidentally
   452  		// look in the module cache directory tree in $GOPATH/pkg/mod/.
   453  		// This prefix is owned by the Go core for possible use in the
   454  		// standard library (since it does not begin with a domain name),
   455  		// so it's OK to disallow entirely.
   456  		return &Package{
   457  			PackagePublic: PackagePublic{
   458  				ImportPath: path,
   459  				Error: &PackageError{
   460  					ImportStack: stk.Copy(),
   461  					Err:         fmt.Sprintf("disallowed import path %q", path),
   462  				},
   463  			},
   464  		}
   465  	}
   466  
   467  	if strings.Contains(path, "@") {
   468  		var text string
   469  		if cfg.ModulesEnabled {
   470  			text = "can only use path@version syntax with 'go get'"
   471  		} else {
   472  			text = "cannot use path@version syntax in GOPATH mode"
   473  		}
   474  		return &Package{
   475  			PackagePublic: PackagePublic{
   476  				ImportPath: path,
   477  				Error: &PackageError{
   478  					ImportStack: stk.Copy(),
   479  					Err:         text,
   480  				},
   481  			},
   482  		}
   483  	}
   484  
   485  	parentPath := ""
   486  	if parent != nil {
   487  		parentPath = parent.ImportPath
   488  	}
   489  
   490  	// Determine canonical identifier for this package.
   491  	// For a local import the identifier is the pseudo-import path
   492  	// we create from the full directory to the package.
   493  	// Otherwise it is the usual import path.
   494  	// For vendored imports, it is the expanded form.
   495  	importPath := path
   496  	origPath := path
   497  	isLocal := build.IsLocalImport(path)
   498  	var modDir string
   499  	var modErr error
   500  	if isLocal {
   501  		importPath = dirToImportPath(filepath.Join(srcDir, path))
   502  	} else if cfg.ModulesEnabled {
   503  		var p string
   504  		modDir, p, modErr = ModLookup(path)
   505  		if modErr == nil {
   506  			importPath = p
   507  		}
   508  	} else if mode&ResolveImport != 0 {
   509  		// We do our own path resolution, because we want to
   510  		// find out the key to use in packageCache without the
   511  		// overhead of repeated calls to buildContext.Import.
   512  		// The code is also needed in a few other places anyway.
   513  		path = ResolveImportPath(parent, path)
   514  		importPath = path
   515  	} else if mode&ResolveModule != 0 {
   516  		path = ModuleImportPath(parent, path)
   517  		importPath = path
   518  	}
   519  
   520  	p := packageCache[importPath]
   521  	if p != nil {
   522  		p = reusePackage(p, stk)
   523  	} else {
   524  		p = new(Package)
   525  		p.Internal.Local = isLocal
   526  		p.ImportPath = importPath
   527  		packageCache[importPath] = p
   528  
   529  		// Load package.
   530  		// Import always returns bp != nil, even if an error occurs,
   531  		// in order to return partial information.
   532  		var bp *build.Package
   533  		var err error
   534  		if modDir != "" {
   535  			bp, err = cfg.BuildContext.ImportDir(modDir, 0)
   536  		} else if modErr != nil {
   537  			bp = new(build.Package)
   538  			err = fmt.Errorf("unknown import path %q: %v", importPath, modErr)
   539  		} else if cfg.ModulesEnabled && path != "unsafe" {
   540  			bp = new(build.Package)
   541  			err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", importPath)
   542  		} else {
   543  			buildMode := build.ImportComment
   544  			if mode&ResolveImport == 0 || path != origPath {
   545  				// Not vendoring, or we already found the vendored path.
   546  				buildMode |= build.IgnoreVendor
   547  			}
   548  			bp, err = cfg.BuildContext.Import(path, srcDir, buildMode)
   549  		}
   550  		bp.ImportPath = importPath
   551  		if cfg.GOBIN != "" {
   552  			bp.BinDir = cfg.GOBIN
   553  		} else if cfg.ModulesEnabled {
   554  			bp.BinDir = ModBinDir()
   555  		}
   556  		if modDir == "" && err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path &&
   557  			!strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") {
   558  			err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment)
   559  		}
   560  		p.load(stk, bp, err)
   561  		if p.Error != nil && p.Error.Pos == "" {
   562  			p = setErrorPos(p, importPos)
   563  		}
   564  
   565  		if modDir == "" && origPath != cleanImport(origPath) {
   566  			p.Error = &PackageError{
   567  				ImportStack: stk.Copy(),
   568  				Err:         fmt.Sprintf("non-canonical import path: %q should be %q", origPath, pathpkg.Clean(origPath)),
   569  			}
   570  			p.Incomplete = true
   571  		}
   572  	}
   573  
   574  	// Checked on every import because the rules depend on the code doing the importing.
   575  	if perr := disallowInternal(srcDir, parent, parentPath, p, stk); perr != p {
   576  		return setErrorPos(perr, importPos)
   577  	}
   578  	if mode&ResolveImport != 0 {
   579  		if perr := disallowVendor(srcDir, parent, parentPath, origPath, p, stk); perr != p {
   580  			return setErrorPos(perr, importPos)
   581  		}
   582  	}
   583  
   584  	if p.Name == "main" && parent != nil && parent.Dir != p.Dir {
   585  		perr := *p
   586  		perr.Error = &PackageError{
   587  			ImportStack: stk.Copy(),
   588  			Err:         fmt.Sprintf("import %q is a program, not an importable package", path),
   589  		}
   590  		return setErrorPos(&perr, importPos)
   591  	}
   592  
   593  	if p.Internal.Local && parent != nil && !parent.Internal.Local {
   594  		perr := *p
   595  		perr.Error = &PackageError{
   596  			ImportStack: stk.Copy(),
   597  			Err:         fmt.Sprintf("local import %q in non-local package", path),
   598  		}
   599  		return setErrorPos(&perr, importPos)
   600  	}
   601  
   602  	return p
   603  }
   604  
   605  func setErrorPos(p *Package, importPos []token.Position) *Package {
   606  	if len(importPos) > 0 {
   607  		pos := importPos[0]
   608  		pos.Filename = base.ShortPath(pos.Filename)
   609  		p.Error.Pos = pos.String()
   610  	}
   611  	return p
   612  }
   613  
   614  func cleanImport(path string) string {
   615  	orig := path
   616  	path = pathpkg.Clean(path)
   617  	if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") {
   618  		path = "./" + path
   619  	}
   620  	return path
   621  }
   622  
   623  var isDirCache = map[string]bool{}
   624  
   625  func isDir(path string) bool {
   626  	result, ok := isDirCache[path]
   627  	if ok {
   628  		return result
   629  	}
   630  
   631  	fi, err := os.Stat(path)
   632  	result = err == nil && fi.IsDir()
   633  	isDirCache[path] = result
   634  	return result
   635  }
   636  
   637  // ResolveImportPath returns the true meaning of path when it appears in parent.
   638  // There are two different resolutions applied.
   639  // First, there is Go 1.5 vendoring (golang.org/s/go15vendor).
   640  // If vendor expansion doesn't trigger, then the path is also subject to
   641  // Go 1.11 module legacy conversion (golang.org/issue/25069).
   642  func ResolveImportPath(parent *Package, path string) (found string) {
   643  	if cfg.ModulesEnabled {
   644  		if _, p, e := ModLookup(path); e == nil {
   645  			return p
   646  		}
   647  		return path
   648  	}
   649  	found = VendoredImportPath(parent, path)
   650  	if found != path {
   651  		return found
   652  	}
   653  	return ModuleImportPath(parent, path)
   654  }
   655  
   656  // dirAndRoot returns the source directory and workspace root
   657  // for the package p, guaranteeing that root is a path prefix of dir.
   658  func dirAndRoot(p *Package) (dir, root string) {
   659  	dir = filepath.Clean(p.Dir)
   660  	root = filepath.Join(p.Root, "src")
   661  	if !str.HasFilePathPrefix(dir, root) || p.ImportPath != "command-line-arguments" && filepath.Join(root, p.ImportPath) != dir {
   662  		// Look for symlinks before reporting error.
   663  		dir = expandPath(dir)
   664  		root = expandPath(root)
   665  	}
   666  
   667  	if !str.HasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || p.ImportPath != "command-line-arguments" && !p.Internal.Local && filepath.Join(root, p.ImportPath) != dir {
   668  		base.Fatalf("unexpected directory layout:\n"+
   669  			"	import path: %s\n"+
   670  			"	root: %s\n"+
   671  			"	dir: %s\n"+
   672  			"	expand root: %s\n"+
   673  			"	expand dir: %s\n"+
   674  			"	separator: %s",
   675  			p.ImportPath,
   676  			filepath.Join(p.Root, "src"),
   677  			filepath.Clean(p.Dir),
   678  			root,
   679  			dir,
   680  			string(filepath.Separator))
   681  	}
   682  
   683  	return dir, root
   684  }
   685  
   686  // VendoredImportPath returns the vendor-expansion of path when it appears in parent.
   687  // If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path,
   688  // x/vendor/path, vendor/path, or else stay path if none of those exist.
   689  // VendoredImportPath returns the expanded path or, if no expansion is found, the original.
   690  func VendoredImportPath(parent *Package, path string) (found string) {
   691  	if parent == nil || parent.Root == "" {
   692  		return path
   693  	}
   694  
   695  	dir, root := dirAndRoot(parent)
   696  
   697  	vpath := "vendor/" + path
   698  	for i := len(dir); i >= len(root); i-- {
   699  		if i < len(dir) && dir[i] != filepath.Separator {
   700  			continue
   701  		}
   702  		// Note: checking for the vendor directory before checking
   703  		// for the vendor/path directory helps us hit the
   704  		// isDir cache more often. It also helps us prepare a more useful
   705  		// list of places we looked, to report when an import is not found.
   706  		if !isDir(filepath.Join(dir[:i], "vendor")) {
   707  			continue
   708  		}
   709  		targ := filepath.Join(dir[:i], vpath)
   710  		if isDir(targ) && hasGoFiles(targ) {
   711  			importPath := parent.ImportPath
   712  			if importPath == "command-line-arguments" {
   713  				// If parent.ImportPath is 'command-line-arguments'.
   714  				// set to relative directory to root (also chopped root directory)
   715  				importPath = dir[len(root)+1:]
   716  			}
   717  			// We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy.
   718  			// We know the import path for parent's dir.
   719  			// We chopped off some number of path elements and
   720  			// added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path.
   721  			// Now we want to know the import path for that directory.
   722  			// Construct it by chopping the same number of path elements
   723  			// (actually the same number of bytes) from parent's import path
   724  			// and then append /vendor/path.
   725  			chopped := len(dir) - i
   726  			if chopped == len(importPath)+1 {
   727  				// We walked up from c:\gopath\src\foo\bar
   728  				// and found c:\gopath\src\vendor\path.
   729  				// We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7).
   730  				// Use "vendor/path" without any prefix.
   731  				return vpath
   732  			}
   733  			return importPath[:len(importPath)-chopped] + "/" + vpath
   734  		}
   735  	}
   736  	return path
   737  }
   738  
   739  var (
   740  	modulePrefix   = []byte("\nmodule ")
   741  	goModPathCache = make(map[string]string)
   742  )
   743  
   744  // goModPath returns the module path in the go.mod in dir, if any.
   745  func goModPath(dir string) (path string) {
   746  	path, ok := goModPathCache[dir]
   747  	if ok {
   748  		return path
   749  	}
   750  	defer func() {
   751  		goModPathCache[dir] = path
   752  	}()
   753  
   754  	data, err := ioutil.ReadFile(filepath.Join(dir, "go.mod"))
   755  	if err != nil {
   756  		return ""
   757  	}
   758  	var i int
   759  	if bytes.HasPrefix(data, modulePrefix[1:]) {
   760  		i = 0
   761  	} else {
   762  		i = bytes.Index(data, modulePrefix)
   763  		if i < 0 {
   764  			return ""
   765  		}
   766  		i++
   767  	}
   768  	line := data[i:]
   769  
   770  	// Cut line at \n, drop trailing \r if present.
   771  	if j := bytes.IndexByte(line, '\n'); j >= 0 {
   772  		line = line[:j]
   773  	}
   774  	if line[len(line)-1] == '\r' {
   775  		line = line[:len(line)-1]
   776  	}
   777  	line = line[len("module "):]
   778  
   779  	// If quoted, unquote.
   780  	path = strings.TrimSpace(string(line))
   781  	if path != "" && path[0] == '"' {
   782  		s, err := strconv.Unquote(path)
   783  		if err != nil {
   784  			return ""
   785  		}
   786  		path = s
   787  	}
   788  	return path
   789  }
   790  
   791  // findVersionElement returns the slice indices of the final version element /vN in path.
   792  // If there is no such element, it returns -1, -1.
   793  func findVersionElement(path string) (i, j int) {
   794  	j = len(path)
   795  	for i = len(path) - 1; i >= 0; i-- {
   796  		if path[i] == '/' {
   797  			if isVersionElement(path[i:j]) {
   798  				return i, j
   799  			}
   800  			j = i
   801  		}
   802  	}
   803  	return -1, -1
   804  }
   805  
   806  // isVersionElement reports whether s is a well-formed path version element:
   807  // v2, v3, v10, etc, but not v0, v05, v1.
   808  func isVersionElement(s string) bool {
   809  	if len(s) < 3 || s[0] != '/' || s[1] != 'v' || s[2] == '0' || s[2] == '1' && len(s) == 3 {
   810  		return false
   811  	}
   812  	for i := 2; i < len(s); i++ {
   813  		if s[i] < '0' || '9' < s[i] {
   814  			return false
   815  		}
   816  	}
   817  	return true
   818  }
   819  
   820  // ModuleImportPath translates import paths found in go modules
   821  // back down to paths that can be resolved in ordinary builds.
   822  //
   823  // Define “new” code as code with a go.mod file in the same directory
   824  // or a parent directory. If an import in new code says x/y/v2/z but
   825  // x/y/v2/z does not exist and x/y/go.mod says “module x/y/v2”,
   826  // then go build will read the import as x/y/z instead.
   827  // See golang.org/issue/25069.
   828  func ModuleImportPath(parent *Package, path string) (found string) {
   829  	if parent == nil || parent.Root == "" {
   830  		return path
   831  	}
   832  
   833  	// If there are no vN elements in path, leave it alone.
   834  	// (The code below would do the same, but only after
   835  	// some other file system accesses that we can avoid
   836  	// here by returning early.)
   837  	if i, _ := findVersionElement(path); i < 0 {
   838  		return path
   839  	}
   840  
   841  	dir, root := dirAndRoot(parent)
   842  
   843  	// Consider dir and parents, up to and including root.
   844  	for i := len(dir); i >= len(root); i-- {
   845  		if i < len(dir) && dir[i] != filepath.Separator {
   846  			continue
   847  		}
   848  		if goModPath(dir[:i]) != "" {
   849  			goto HaveGoMod
   850  		}
   851  	}
   852  	// This code is not in a tree with a go.mod,
   853  	// so apply no changes to the path.
   854  	return path
   855  
   856  HaveGoMod:
   857  	// This import is in a tree with a go.mod.
   858  	// Allow it to refer to code in GOPATH/src/x/y/z as x/y/v2/z
   859  	// if GOPATH/src/x/y/go.mod says module "x/y/v2",
   860  
   861  	// If x/y/v2/z exists, use it unmodified.
   862  	if bp, _ := cfg.BuildContext.Import(path, "", build.IgnoreVendor); bp.Dir != "" {
   863  		return path
   864  	}
   865  
   866  	// Otherwise look for a go.mod supplying a version element.
   867  	// Some version-like elements may appear in paths but not
   868  	// be module versions; we skip over those to look for module
   869  	// versions. For example the module m/v2 might have a
   870  	// package m/v2/api/v1/foo.
   871  	limit := len(path)
   872  	for limit > 0 {
   873  		i, j := findVersionElement(path[:limit])
   874  		if i < 0 {
   875  			return path
   876  		}
   877  		if bp, _ := cfg.BuildContext.Import(path[:i], "", build.IgnoreVendor); bp.Dir != "" {
   878  			if mpath := goModPath(bp.Dir); mpath != "" {
   879  				// Found a valid go.mod file, so we're stopping the search.
   880  				// If the path is m/v2/p and we found m/go.mod that says
   881  				// "module m/v2", then we return "m/p".
   882  				if mpath == path[:j] {
   883  					return path[:i] + path[j:]
   884  				}
   885  				// Otherwise just return the original path.
   886  				// We didn't find anything worth rewriting,
   887  				// and the go.mod indicates that we should
   888  				// not consider parent directories.
   889  				return path
   890  			}
   891  		}
   892  		limit = i
   893  	}
   894  	return path
   895  }
   896  
   897  // hasGoFiles reports whether dir contains any files with names ending in .go.
   898  // For a vendor check we must exclude directories that contain no .go files.
   899  // Otherwise it is not possible to vendor just a/b/c and still import the
   900  // non-vendored a/b. See golang.org/issue/13832.
   901  func hasGoFiles(dir string) bool {
   902  	fis, _ := ioutil.ReadDir(dir)
   903  	for _, fi := range fis {
   904  		if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".go") {
   905  			return true
   906  		}
   907  	}
   908  	return false
   909  }
   910  
   911  // reusePackage reuses package p to satisfy the import at the top
   912  // of the import stack stk. If this use causes an import loop,
   913  // reusePackage updates p's error information to record the loop.
   914  func reusePackage(p *Package, stk *ImportStack) *Package {
   915  	// We use p.Internal.Imports==nil to detect a package that
   916  	// is in the midst of its own loadPackage call
   917  	// (all the recursion below happens before p.Internal.Imports gets set).
   918  	if p.Internal.Imports == nil {
   919  		if p.Error == nil {
   920  			p.Error = &PackageError{
   921  				ImportStack:   stk.Copy(),
   922  				Err:           "import cycle not allowed",
   923  				IsImportCycle: true,
   924  			}
   925  		}
   926  		p.Incomplete = true
   927  	}
   928  	// Don't rewrite the import stack in the error if we have an import cycle.
   929  	// If we do, we'll lose the path that describes the cycle.
   930  	if p.Error != nil && !p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack) {
   931  		p.Error.ImportStack = stk.Copy()
   932  	}
   933  	return p
   934  }
   935  
   936  // disallowInternal checks that srcDir (containing package importerPath, if non-empty)
   937  // is allowed to import p.
   938  // If the import is allowed, disallowInternal returns the original package p.
   939  // If not, it returns a new package containing just an appropriate error.
   940  func disallowInternal(srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *Package {
   941  	// golang.org/s/go14internal:
   942  	// An import of a path containing the element “internal”
   943  	// is disallowed if the importing code is outside the tree
   944  	// rooted at the parent of the “internal” directory.
   945  
   946  	// There was an error loading the package; stop here.
   947  	if p.Error != nil {
   948  		return p
   949  	}
   950  
   951  	// The generated 'testmain' package is allowed to access testing/internal/...,
   952  	// as if it were generated into the testing directory tree
   953  	// (it's actually in a temporary directory outside any Go tree).
   954  	// This cleans up a former kludge in passing functionality to the testing package.
   955  	if strings.HasPrefix(p.ImportPath, "testing/internal") && len(*stk) >= 2 && (*stk)[len(*stk)-2] == "testmain" {
   956  		return p
   957  	}
   958  
   959  	// We can't check standard packages with gccgo.
   960  	if cfg.BuildContext.Compiler == "gccgo" && p.Standard {
   961  		return p
   962  	}
   963  
   964  	// The stack includes p.ImportPath.
   965  	// If that's the only thing on the stack, we started
   966  	// with a name given on the command line, not an
   967  	// import. Anything listed on the command line is fine.
   968  	if len(*stk) == 1 {
   969  		return p
   970  	}
   971  
   972  	// Check for "internal" element: three cases depending on begin of string and/or end of string.
   973  	i, ok := findInternal(p.ImportPath)
   974  	if !ok {
   975  		return p
   976  	}
   977  
   978  	// Internal is present.
   979  	// Map import path back to directory corresponding to parent of internal.
   980  	if i > 0 {
   981  		i-- // rewind over slash in ".../internal"
   982  	}
   983  
   984  	if p.Module == nil {
   985  		parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)]
   986  
   987  		if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
   988  			return p
   989  		}
   990  
   991  		// Look for symlinks before reporting error.
   992  		srcDir = expandPath(srcDir)
   993  		parent = expandPath(parent)
   994  		if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
   995  			return p
   996  		}
   997  	} else {
   998  		// p is in a module, so make it available based on the importer's import path instead
   999  		// of the file path (https://golang.org/issue/23970).
  1000  		if importer.Internal.CmdlineFiles {
  1001  			// The importer is a list of command-line files.
  1002  			// Pretend that the import path is the import path of the
  1003  			// directory containing them.
  1004  			// If the directory is outside the main module, this will resolve to ".",
  1005  			// which is not a prefix of any valid module.
  1006  			importerPath = ModDirImportPath(importer.Dir)
  1007  		}
  1008  		parentOfInternal := p.ImportPath[:i]
  1009  		if str.HasPathPrefix(importerPath, parentOfInternal) {
  1010  			return p
  1011  		}
  1012  	}
  1013  
  1014  	// Internal is present, and srcDir is outside parent's tree. Not allowed.
  1015  	perr := *p
  1016  	perr.Error = &PackageError{
  1017  		ImportStack: stk.Copy(),
  1018  		Err:         "use of internal package " + p.ImportPath + " not allowed",
  1019  	}
  1020  	perr.Incomplete = true
  1021  	return &perr
  1022  }
  1023  
  1024  // findInternal looks for the final "internal" path element in the given import path.
  1025  // If there isn't one, findInternal returns ok=false.
  1026  // Otherwise, findInternal returns ok=true and the index of the "internal".
  1027  func findInternal(path string) (index int, ok bool) {
  1028  	// Three cases, depending on internal at start/end of string or not.
  1029  	// The order matters: we must return the index of the final element,
  1030  	// because the final one produces the most restrictive requirement
  1031  	// on the importer.
  1032  	switch {
  1033  	case strings.HasSuffix(path, "/internal"):
  1034  		return len(path) - len("internal"), true
  1035  	case strings.Contains(path, "/internal/"):
  1036  		return strings.LastIndex(path, "/internal/") + 1, true
  1037  	case path == "internal", strings.HasPrefix(path, "internal/"):
  1038  		return 0, true
  1039  	}
  1040  	return 0, false
  1041  }
  1042  
  1043  // disallowVendor checks that srcDir (containing package importerPath, if non-empty)
  1044  // is allowed to import p as path.
  1045  // If the import is allowed, disallowVendor returns the original package p.
  1046  // If not, it returns a new package containing just an appropriate error.
  1047  func disallowVendor(srcDir string, importer *Package, importerPath, path string, p *Package, stk *ImportStack) *Package {
  1048  	// The stack includes p.ImportPath.
  1049  	// If that's the only thing on the stack, we started
  1050  	// with a name given on the command line, not an
  1051  	// import. Anything listed on the command line is fine.
  1052  	if len(*stk) == 1 {
  1053  		return p
  1054  	}
  1055  
  1056  	if perr := disallowVendorVisibility(srcDir, p, stk); perr != p {
  1057  		return perr
  1058  	}
  1059  
  1060  	// Paths like x/vendor/y must be imported as y, never as x/vendor/y.
  1061  	if i, ok := FindVendor(path); ok {
  1062  		perr := *p
  1063  		perr.Error = &PackageError{
  1064  			ImportStack: stk.Copy(),
  1065  			Err:         "must be imported as " + path[i+len("vendor/"):],
  1066  		}
  1067  		perr.Incomplete = true
  1068  		return &perr
  1069  	}
  1070  
  1071  	return p
  1072  }
  1073  
  1074  // disallowVendorVisibility checks that srcDir is allowed to import p.
  1075  // The rules are the same as for /internal/ except that a path ending in /vendor
  1076  // is not subject to the rules, only subdirectories of vendor.
  1077  // This allows people to have packages and commands named vendor,
  1078  // for maximal compatibility with existing source trees.
  1079  func disallowVendorVisibility(srcDir string, p *Package, stk *ImportStack) *Package {
  1080  	// The stack includes p.ImportPath.
  1081  	// If that's the only thing on the stack, we started
  1082  	// with a name given on the command line, not an
  1083  	// import. Anything listed on the command line is fine.
  1084  	if len(*stk) == 1 {
  1085  		return p
  1086  	}
  1087  
  1088  	// Check for "vendor" element.
  1089  	i, ok := FindVendor(p.ImportPath)
  1090  	if !ok {
  1091  		return p
  1092  	}
  1093  
  1094  	// Vendor is present.
  1095  	// Map import path back to directory corresponding to parent of vendor.
  1096  	if i > 0 {
  1097  		i-- // rewind over slash in ".../vendor"
  1098  	}
  1099  	truncateTo := i + len(p.Dir) - len(p.ImportPath)
  1100  	if truncateTo < 0 || len(p.Dir) < truncateTo {
  1101  		return p
  1102  	}
  1103  	parent := p.Dir[:truncateTo]
  1104  	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
  1105  		return p
  1106  	}
  1107  
  1108  	// Look for symlinks before reporting error.
  1109  	srcDir = expandPath(srcDir)
  1110  	parent = expandPath(parent)
  1111  	if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) {
  1112  		return p
  1113  	}
  1114  
  1115  	// Vendor is present, and srcDir is outside parent's tree. Not allowed.
  1116  	perr := *p
  1117  	perr.Error = &PackageError{
  1118  		ImportStack: stk.Copy(),
  1119  		Err:         "use of vendored package not allowed",
  1120  	}
  1121  	perr.Incomplete = true
  1122  	return &perr
  1123  }
  1124  
  1125  // FindVendor looks for the last non-terminating "vendor" path element in the given import path.
  1126  // If there isn't one, FindVendor returns ok=false.
  1127  // Otherwise, FindVendor returns ok=true and the index of the "vendor".
  1128  //
  1129  // Note that terminating "vendor" elements don't count: "x/vendor" is its own package,
  1130  // not the vendored copy of an import "" (the empty import path).
  1131  // This will allow people to have packages or commands named vendor.
  1132  // This may help reduce breakage, or it may just be confusing. We'll see.
  1133  func FindVendor(path string) (index int, ok bool) {
  1134  	// Two cases, depending on internal at start of string or not.
  1135  	// The order matters: we must return the index of the final element,
  1136  	// because the final one is where the effective import path starts.
  1137  	switch {
  1138  	case strings.Contains(path, "/vendor/"):
  1139  		return strings.LastIndex(path, "/vendor/") + 1, true
  1140  	case strings.HasPrefix(path, "vendor/"):
  1141  		return 0, true
  1142  	}
  1143  	return 0, false
  1144  }
  1145  
  1146  type TargetDir int
  1147  
  1148  const (
  1149  	ToTool    TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*)
  1150  	ToBin                      // to bin dir inside package root (default for non-cmd/*)
  1151  	StalePath                  // an old import path; fail to build
  1152  )
  1153  
  1154  // InstallTargetDir reports the target directory for installing the command p.
  1155  func InstallTargetDir(p *Package) TargetDir {
  1156  	if strings.HasPrefix(p.ImportPath, "code.google.com/p/go.tools/cmd/") {
  1157  		return StalePath
  1158  	}
  1159  	if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" {
  1160  		switch p.ImportPath {
  1161  		case "cmd/go", "cmd/gofmt":
  1162  			return ToBin
  1163  		}
  1164  		return ToTool
  1165  	}
  1166  	return ToBin
  1167  }
  1168  
  1169  var cgoExclude = map[string]bool{
  1170  	"runtime/cgo": true,
  1171  }
  1172  
  1173  var cgoSyscallExclude = map[string]bool{
  1174  	"runtime/cgo":  true,
  1175  	"runtime/race": true,
  1176  	"runtime/msan": true,
  1177  }
  1178  
  1179  var foldPath = make(map[string]string)
  1180  
  1181  // DefaultExecName returns the default executable name
  1182  // for a package with the import path importPath.
  1183  //
  1184  // The default executable name is the last element of the import path.
  1185  // In module-aware mode, an additional rule is used. If the last element
  1186  // is a vN path element specifying the major version, then the second last
  1187  // element of the import path is used instead.
  1188  func DefaultExecName(importPath string) string {
  1189  	_, elem := pathpkg.Split(importPath)
  1190  	if cfg.ModulesEnabled {
  1191  		// If this is example.com/mycmd/v2, it's more useful to install it as mycmd than as v2.
  1192  		// See golang.org/issue/24667.
  1193  		isVersion := func(v string) bool {
  1194  			if len(v) < 2 || v[0] != 'v' || v[1] < '1' || '9' < v[1] {
  1195  				return false
  1196  			}
  1197  			for i := 2; i < len(v); i++ {
  1198  				if c := v[i]; c < '0' || '9' < c {
  1199  					return false
  1200  				}
  1201  			}
  1202  			return true
  1203  		}
  1204  		if isVersion(elem) {
  1205  			_, elem = pathpkg.Split(pathpkg.Dir(importPath))
  1206  		}
  1207  	}
  1208  	return elem
  1209  }
  1210  
  1211  // load populates p using information from bp, err, which should
  1212  // be the result of calling build.Context.Import.
  1213  func (p *Package) load(stk *ImportStack, bp *build.Package, err error) {
  1214  	p.copyBuild(bp)
  1215  
  1216  	// The localPrefix is the path we interpret ./ imports relative to.
  1217  	// Synthesized main packages sometimes override this.
  1218  	if p.Internal.Local {
  1219  		p.Internal.LocalPrefix = dirToImportPath(p.Dir)
  1220  	}
  1221  
  1222  	if err != nil {
  1223  		if _, ok := err.(*build.NoGoError); ok {
  1224  			err = &NoGoError{Package: p}
  1225  		}
  1226  		p.Incomplete = true
  1227  		err = base.ExpandScanner(err)
  1228  		p.Error = &PackageError{
  1229  			ImportStack: stk.Copy(),
  1230  			Err:         err.Error(),
  1231  		}
  1232  		return
  1233  	}
  1234  
  1235  	useBindir := p.Name == "main"
  1236  	if !p.Standard {
  1237  		switch cfg.BuildBuildmode {
  1238  		case "c-archive", "c-shared", "plugin":
  1239  			useBindir = false
  1240  		}
  1241  	}
  1242  
  1243  	if useBindir {
  1244  		// Report an error when the old code.google.com/p/go.tools paths are used.
  1245  		if InstallTargetDir(p) == StalePath {
  1246  			newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1)
  1247  			e := fmt.Sprintf("the %v command has moved; use %v instead.", p.ImportPath, newPath)
  1248  			p.Error = &PackageError{Err: e}
  1249  			return
  1250  		}
  1251  		_, elem := filepath.Split(p.Dir)
  1252  		if cfg.ModulesEnabled {
  1253  			// NOTE(rsc,dmitshur): Using p.ImportPath instead of p.Dir
  1254  			// makes sure we install a package in the root of a
  1255  			// cached module directory as that package name
  1256  			// not name@v1.2.3.
  1257  			// Using p.ImportPath instead of p.Dir
  1258  			// is probably correct all the time,
  1259  			// even for non-module-enabled code,
  1260  			// but I'm not brave enough to change the
  1261  			// non-module behavior this late in the
  1262  			// release cycle. Can be done for Go 1.13.
  1263  			// See golang.org/issue/26869.
  1264  			elem = DefaultExecName(p.ImportPath)
  1265  		}
  1266  		full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem
  1267  		if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH {
  1268  			// Install cross-compiled binaries to subdirectories of bin.
  1269  			elem = full
  1270  		}
  1271  		if p.Internal.Build.BinDir == "" && cfg.ModulesEnabled {
  1272  			p.Internal.Build.BinDir = ModBinDir()
  1273  		}
  1274  		if p.Internal.Build.BinDir != "" {
  1275  			// Install to GOBIN or bin of GOPATH entry.
  1276  			p.Target = filepath.Join(p.Internal.Build.BinDir, elem)
  1277  			if !p.Goroot && strings.Contains(elem, "/") && cfg.GOBIN != "" {
  1278  				// Do not create $GOBIN/goos_goarch/elem.
  1279  				p.Target = ""
  1280  				p.Internal.GobinSubdir = true
  1281  			}
  1282  		}
  1283  		if InstallTargetDir(p) == ToTool {
  1284  			// This is for 'go tool'.
  1285  			// Override all the usual logic and force it into the tool directory.
  1286  			if cfg.BuildToolchainName == "gccgo" {
  1287  				p.Target = filepath.Join(base.ToolDir, elem)
  1288  			} else {
  1289  				p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full)
  1290  			}
  1291  		}
  1292  		if p.Target != "" && cfg.BuildContext.GOOS == "windows" {
  1293  			p.Target += ".exe"
  1294  		}
  1295  	} else if p.Internal.Local {
  1296  		// Local import turned into absolute path.
  1297  		// No permanent install target.
  1298  		p.Target = ""
  1299  	} else {
  1300  		p.Target = p.Internal.Build.PkgObj
  1301  		if cfg.BuildLinkshared {
  1302  			shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname"
  1303  			shlib, err := ioutil.ReadFile(shlibnamefile)
  1304  			if err != nil && !os.IsNotExist(err) {
  1305  				base.Fatalf("reading shlibname: %v", err)
  1306  			}
  1307  			if err == nil {
  1308  				libname := strings.TrimSpace(string(shlib))
  1309  				if cfg.BuildContext.Compiler == "gccgo" {
  1310  					p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname)
  1311  				} else {
  1312  					p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname)
  1313  				}
  1314  			}
  1315  		}
  1316  	}
  1317  
  1318  	// Build augmented import list to add implicit dependencies.
  1319  	// Be careful not to add imports twice, just to avoid confusion.
  1320  	importPaths := p.Imports
  1321  	addImport := func(path string, forCompiler bool) {
  1322  		for _, p := range importPaths {
  1323  			if path == p {
  1324  				return
  1325  			}
  1326  		}
  1327  		importPaths = append(importPaths, path)
  1328  		if forCompiler {
  1329  			p.Internal.CompiledImports = append(p.Internal.CompiledImports, path)
  1330  		}
  1331  	}
  1332  
  1333  	// Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall",
  1334  	// except for certain packages, to avoid circular dependencies.
  1335  	if p.UsesCgo() {
  1336  		addImport("unsafe", true)
  1337  	}
  1338  	if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" {
  1339  		addImport("runtime/cgo", true)
  1340  	}
  1341  	if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) {
  1342  		addImport("syscall", true)
  1343  	}
  1344  
  1345  	// SWIG adds imports of some standard packages.
  1346  	if p.UsesSwig() {
  1347  		addImport("unsafe", true)
  1348  		if cfg.BuildContext.Compiler != "gccgo" {
  1349  			addImport("runtime/cgo", true)
  1350  		}
  1351  		addImport("syscall", true)
  1352  		addImport("sync", true)
  1353  
  1354  		// TODO: The .swig and .swigcxx files can use
  1355  		// %go_import directives to import other packages.
  1356  	}
  1357  
  1358  	// The linker loads implicit dependencies.
  1359  	if p.Name == "main" && !p.Internal.ForceLibrary {
  1360  		for _, dep := range LinkerDeps(p) {
  1361  			addImport(dep, false)
  1362  		}
  1363  	}
  1364  
  1365  	// Check for case-insensitive collision of input files.
  1366  	// To avoid problems on case-insensitive files, we reject any package
  1367  	// where two different input files have equal names under a case-insensitive
  1368  	// comparison.
  1369  	inputs := p.AllFiles()
  1370  	f1, f2 := str.FoldDup(inputs)
  1371  	if f1 != "" {
  1372  		p.Error = &PackageError{
  1373  			ImportStack: stk.Copy(),
  1374  			Err:         fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2),
  1375  		}
  1376  		return
  1377  	}
  1378  
  1379  	// If first letter of input file is ASCII, it must be alphanumeric.
  1380  	// This avoids files turning into flags when invoking commands,
  1381  	// and other problems we haven't thought of yet.
  1382  	// Also, _cgo_ files must be generated by us, not supplied.
  1383  	// They are allowed to have //go:cgo_ldflag directives.
  1384  	// The directory scan ignores files beginning with _,
  1385  	// so we shouldn't see any _cgo_ files anyway, but just be safe.
  1386  	for _, file := range inputs {
  1387  		if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") {
  1388  			p.Error = &PackageError{
  1389  				ImportStack: stk.Copy(),
  1390  				Err:         fmt.Sprintf("invalid input file name %q", file),
  1391  			}
  1392  			return
  1393  		}
  1394  	}
  1395  	if name := pathpkg.Base(p.ImportPath); !SafeArg(name) {
  1396  		p.Error = &PackageError{
  1397  			ImportStack: stk.Copy(),
  1398  			Err:         fmt.Sprintf("invalid input directory name %q", name),
  1399  		}
  1400  		return
  1401  	}
  1402  	if !SafeArg(p.ImportPath) {
  1403  		p.Error = &PackageError{
  1404  			ImportStack: stk.Copy(),
  1405  			Err:         fmt.Sprintf("invalid import path %q", p.ImportPath),
  1406  		}
  1407  		return
  1408  	}
  1409  
  1410  	// Build list of imported packages and full dependency list.
  1411  	imports := make([]*Package, 0, len(p.Imports))
  1412  	for i, path := range importPaths {
  1413  		if path == "C" {
  1414  			continue
  1415  		}
  1416  		p1 := LoadImport(path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport)
  1417  		if p.Standard && p.Error == nil && !p1.Standard && p1.Error == nil {
  1418  			p.Error = &PackageError{
  1419  				ImportStack: stk.Copy(),
  1420  				Err:         fmt.Sprintf("non-standard import %q in standard package %q", path, p.ImportPath),
  1421  			}
  1422  			pos := p.Internal.Build.ImportPos[path]
  1423  			if len(pos) > 0 {
  1424  				p.Error.Pos = pos[0].String()
  1425  			}
  1426  		}
  1427  
  1428  		path = p1.ImportPath
  1429  		importPaths[i] = path
  1430  		if i < len(p.Imports) {
  1431  			p.Imports[i] = path
  1432  		}
  1433  
  1434  		imports = append(imports, p1)
  1435  		if p1.Incomplete {
  1436  			p.Incomplete = true
  1437  		}
  1438  	}
  1439  	p.Internal.Imports = imports
  1440  
  1441  	deps := make(map[string]*Package)
  1442  	var q []*Package
  1443  	q = append(q, imports...)
  1444  	for i := 0; i < len(q); i++ {
  1445  		p1 := q[i]
  1446  		path := p1.ImportPath
  1447  		// The same import path could produce an error or not,
  1448  		// depending on what tries to import it.
  1449  		// Prefer to record entries with errors, so we can report them.
  1450  		p0 := deps[path]
  1451  		if p0 == nil || p1.Error != nil && (p0.Error == nil || len(p0.Error.ImportStack) > len(p1.Error.ImportStack)) {
  1452  			deps[path] = p1
  1453  			for _, p2 := range p1.Internal.Imports {
  1454  				if deps[p2.ImportPath] != p2 {
  1455  					q = append(q, p2)
  1456  				}
  1457  			}
  1458  		}
  1459  	}
  1460  
  1461  	p.Deps = make([]string, 0, len(deps))
  1462  	for dep := range deps {
  1463  		p.Deps = append(p.Deps, dep)
  1464  	}
  1465  	sort.Strings(p.Deps)
  1466  	for _, dep := range p.Deps {
  1467  		p1 := deps[dep]
  1468  		if p1 == nil {
  1469  			panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath)
  1470  		}
  1471  		if p1.Error != nil {
  1472  			p.DepsErrors = append(p.DepsErrors, p1.Error)
  1473  		}
  1474  	}
  1475  
  1476  	// unsafe is a fake package.
  1477  	if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") {
  1478  		p.Target = ""
  1479  	}
  1480  
  1481  	// If cgo is not enabled, ignore cgo supporting sources
  1482  	// just as we ignore go files containing import "C".
  1483  	if !cfg.BuildContext.CgoEnabled {
  1484  		p.CFiles = nil
  1485  		p.CXXFiles = nil
  1486  		p.MFiles = nil
  1487  		p.SwigFiles = nil
  1488  		p.SwigCXXFiles = nil
  1489  		// Note that SFiles are okay (they go to the Go assembler)
  1490  		// and HFiles are okay (they might be used by the SFiles).
  1491  		// Also Sysofiles are okay (they might not contain object
  1492  		// code; see issue #16050).
  1493  	}
  1494  
  1495  	setError := func(msg string) {
  1496  		p.Error = &PackageError{
  1497  			ImportStack: stk.Copy(),
  1498  			Err:         msg,
  1499  		}
  1500  	}
  1501  
  1502  	// The gc toolchain only permits C source files with cgo or SWIG.
  1503  	if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" {
  1504  		setError(fmt.Sprintf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " ")))
  1505  		return
  1506  	}
  1507  
  1508  	// C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG,
  1509  	// regardless of toolchain.
  1510  	if len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
  1511  		setError(fmt.Sprintf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " ")))
  1512  		return
  1513  	}
  1514  	if len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
  1515  		setError(fmt.Sprintf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " ")))
  1516  		return
  1517  	}
  1518  	if len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() {
  1519  		setError(fmt.Sprintf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " ")))
  1520  		return
  1521  	}
  1522  
  1523  	// Check for case-insensitive collisions of import paths.
  1524  	fold := str.ToFold(p.ImportPath)
  1525  	if other := foldPath[fold]; other == "" {
  1526  		foldPath[fold] = p.ImportPath
  1527  	} else if other != p.ImportPath {
  1528  		setError(fmt.Sprintf("case-insensitive import collision: %q and %q", p.ImportPath, other))
  1529  		return
  1530  	}
  1531  
  1532  	if cfg.ModulesEnabled {
  1533  		mainPath := p.ImportPath
  1534  		if p.Internal.CmdlineFiles {
  1535  			mainPath = "command-line-arguments"
  1536  		}
  1537  		p.Module = ModPackageModuleInfo(mainPath)
  1538  		if p.Name == "main" {
  1539  			p.Internal.BuildInfo = ModPackageBuildInfo(mainPath, p.Deps)
  1540  		}
  1541  	}
  1542  }
  1543  
  1544  // SafeArg reports whether arg is a "safe" command-line argument,
  1545  // meaning that when it appears in a command-line, it probably
  1546  // doesn't have some special meaning other than its own name.
  1547  // Obviously args beginning with - are not safe (they look like flags).
  1548  // Less obviously, args beginning with @ are not safe (they look like
  1549  // GNU binutils flagfile specifiers, sometimes called "response files").
  1550  // To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII.
  1551  // We accept leading . _ and / as likely in file system paths.
  1552  // There is a copy of this function in cmd/compile/internal/gc/noder.go.
  1553  func SafeArg(name string) bool {
  1554  	if name == "" {
  1555  		return false
  1556  	}
  1557  	c := name[0]
  1558  	return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
  1559  }
  1560  
  1561  // LinkerDeps returns the list of linker-induced dependencies for main package p.
  1562  func LinkerDeps(p *Package) []string {
  1563  	// Everything links runtime.
  1564  	deps := []string{"runtime"}
  1565  
  1566  	// External linking mode forces an import of runtime/cgo.
  1567  	if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" {
  1568  		deps = append(deps, "runtime/cgo")
  1569  	}
  1570  	// On ARM with GOARM=5, it forces an import of math, for soft floating point.
  1571  	if cfg.Goarch == "arm" {
  1572  		deps = append(deps, "math")
  1573  	}
  1574  	// Using the race detector forces an import of runtime/race.
  1575  	if cfg.BuildRace {
  1576  		deps = append(deps, "runtime/race")
  1577  	}
  1578  	// Using memory sanitizer forces an import of runtime/msan.
  1579  	if cfg.BuildMSan {
  1580  		deps = append(deps, "runtime/msan")
  1581  	}
  1582  
  1583  	return deps
  1584  }
  1585  
  1586  // externalLinkingForced reports whether external linking is being
  1587  // forced even for programs that do not use cgo.
  1588  func externalLinkingForced(p *Package) bool {
  1589  	// Some targets must use external linking even inside GOROOT.
  1590  	switch cfg.BuildContext.GOOS {
  1591  	case "android":
  1592  		return true
  1593  	case "darwin":
  1594  		switch cfg.BuildContext.GOARCH {
  1595  		case "arm", "arm64":
  1596  			return true
  1597  		}
  1598  	}
  1599  
  1600  	if !cfg.BuildContext.CgoEnabled {
  1601  		return false
  1602  	}
  1603  	// Currently build modes c-shared, pie (on systems that do not
  1604  	// support PIE with internal linking mode (currently all
  1605  	// systems: issue #18968)), plugin, and -linkshared force
  1606  	// external linking mode, as of course does
  1607  	// -ldflags=-linkmode=external. External linking mode forces
  1608  	// an import of runtime/cgo.
  1609  	pieCgo := cfg.BuildBuildmode == "pie"
  1610  	linkmodeExternal := false
  1611  	if p != nil {
  1612  		ldflags := BuildLdflags.For(p)
  1613  		for i, a := range ldflags {
  1614  			if a == "-linkmode=external" {
  1615  				linkmodeExternal = true
  1616  			}
  1617  			if a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" {
  1618  				linkmodeExternal = true
  1619  			}
  1620  		}
  1621  	}
  1622  
  1623  	return cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" || pieCgo || cfg.BuildLinkshared || linkmodeExternal
  1624  }
  1625  
  1626  // mkAbs rewrites list, which must be paths relative to p.Dir,
  1627  // into a sorted list of absolute paths. It edits list in place but for
  1628  // convenience also returns list back to its caller.
  1629  func (p *Package) mkAbs(list []string) []string {
  1630  	for i, f := range list {
  1631  		list[i] = filepath.Join(p.Dir, f)
  1632  	}
  1633  	sort.Strings(list)
  1634  	return list
  1635  }
  1636  
  1637  // InternalGoFiles returns the list of Go files being built for the package,
  1638  // using absolute paths.
  1639  func (p *Package) InternalGoFiles() []string {
  1640  	return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles))
  1641  }
  1642  
  1643  // InternalXGoFiles returns the list of Go files being built for the XTest package,
  1644  // using absolute paths.
  1645  func (p *Package) InternalXGoFiles() []string {
  1646  	return p.mkAbs(p.XTestGoFiles)
  1647  }
  1648  
  1649  // InternalGoFiles returns the list of all Go files possibly relevant for the package,
  1650  // using absolute paths. "Possibly relevant" means that files are not excluded
  1651  // due to build tags, but files with names beginning with . or _ are still excluded.
  1652  func (p *Package) InternalAllGoFiles() []string {
  1653  	var extra []string
  1654  	for _, f := range p.IgnoredGoFiles {
  1655  		if f != "" && f[0] != '.' || f[0] != '_' {
  1656  			extra = append(extra, f)
  1657  		}
  1658  	}
  1659  	return p.mkAbs(str.StringList(extra, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
  1660  }
  1661  
  1662  // usesSwig reports whether the package needs to run SWIG.
  1663  func (p *Package) UsesSwig() bool {
  1664  	return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0
  1665  }
  1666  
  1667  // usesCgo reports whether the package needs to run cgo
  1668  func (p *Package) UsesCgo() bool {
  1669  	return len(p.CgoFiles) > 0
  1670  }
  1671  
  1672  // PackageList returns the list of packages in the dag rooted at roots
  1673  // as visited in a depth-first post-order traversal.
  1674  func PackageList(roots []*Package) []*Package {
  1675  	seen := map[*Package]bool{}
  1676  	all := []*Package{}
  1677  	var walk func(*Package)
  1678  	walk = func(p *Package) {
  1679  		if seen[p] {
  1680  			return
  1681  		}
  1682  		seen[p] = true
  1683  		for _, p1 := range p.Internal.Imports {
  1684  			walk(p1)
  1685  		}
  1686  		all = append(all, p)
  1687  	}
  1688  	for _, root := range roots {
  1689  		walk(root)
  1690  	}
  1691  	return all
  1692  }
  1693  
  1694  // TestPackageList returns the list of packages in the dag rooted at roots
  1695  // as visited in a depth-first post-order traversal, including the test
  1696  // imports of the roots. This ignores errors in test packages.
  1697  func TestPackageList(roots []*Package) []*Package {
  1698  	seen := map[*Package]bool{}
  1699  	all := []*Package{}
  1700  	var walk func(*Package)
  1701  	walk = func(p *Package) {
  1702  		if seen[p] {
  1703  			return
  1704  		}
  1705  		seen[p] = true
  1706  		for _, p1 := range p.Internal.Imports {
  1707  			walk(p1)
  1708  		}
  1709  		all = append(all, p)
  1710  	}
  1711  	walkTest := func(root *Package, path string) {
  1712  		var stk ImportStack
  1713  		p1 := LoadImport(path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport)
  1714  		if p1.Error == nil {
  1715  			walk(p1)
  1716  		}
  1717  	}
  1718  	for _, root := range roots {
  1719  		walk(root)
  1720  		for _, path := range root.TestImports {
  1721  			walkTest(root, path)
  1722  		}
  1723  		for _, path := range root.XTestImports {
  1724  			walkTest(root, path)
  1725  		}
  1726  	}
  1727  	return all
  1728  }
  1729  
  1730  var cmdCache = map[string]*Package{}
  1731  
  1732  func ClearCmdCache() {
  1733  	for name := range cmdCache {
  1734  		delete(cmdCache, name)
  1735  	}
  1736  }
  1737  
  1738  // LoadPackage loads the package named by arg.
  1739  func LoadPackage(arg string, stk *ImportStack) *Package {
  1740  	p := loadPackage(arg, stk)
  1741  	setToolFlags(p)
  1742  	return p
  1743  }
  1744  
  1745  // LoadPackageNoFlags is like LoadPackage
  1746  // but does not guarantee that the build tool flags are set in the result.
  1747  // It is only for use by GOPATH-based "go get"
  1748  // and is only appropriate for preliminary loading of packages.
  1749  // A real load using LoadPackage or (more likely)
  1750  // Packages, PackageAndErrors, or PackagesForBuild
  1751  // must be done before passing the package to any build
  1752  // steps, so that the tool flags can be set properly.
  1753  // TODO(rsc): When GOPATH-based "go get" is removed, delete this function.
  1754  func LoadPackageNoFlags(arg string, stk *ImportStack) *Package {
  1755  	return loadPackage(arg, stk)
  1756  }
  1757  
  1758  // loadPackage is like loadImport but is used for command-line arguments,
  1759  // not for paths found in import statements. In addition to ordinary import paths,
  1760  // loadPackage accepts pseudo-paths beginning with cmd/ to denote commands
  1761  // in the Go command directory, as well as paths to those directories.
  1762  func loadPackage(arg string, stk *ImportStack) *Package {
  1763  	if arg == "" {
  1764  		panic("loadPackage called with empty package path")
  1765  	}
  1766  	if build.IsLocalImport(arg) {
  1767  		dir := arg
  1768  		if !filepath.IsAbs(dir) {
  1769  			if abs, err := filepath.Abs(dir); err == nil {
  1770  				// interpret relative to current directory
  1771  				dir = abs
  1772  			}
  1773  		}
  1774  		if sub, ok := hasSubdir(cfg.GOROOTsrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") {
  1775  			arg = sub
  1776  		}
  1777  	}
  1778  	if strings.HasPrefix(arg, "cmd/") && !strings.Contains(arg[4:], "/") {
  1779  		if p := cmdCache[arg]; p != nil {
  1780  			return p
  1781  		}
  1782  		stk.Push(arg)
  1783  		defer stk.Pop()
  1784  
  1785  		bp, err := cfg.BuildContext.ImportDir(filepath.Join(cfg.GOROOTsrc, arg), 0)
  1786  		bp.ImportPath = arg
  1787  		bp.Goroot = true
  1788  		bp.BinDir = cfg.GOROOTbin
  1789  		bp.Root = cfg.GOROOT
  1790  		bp.SrcRoot = cfg.GOROOTsrc
  1791  		p := new(Package)
  1792  		cmdCache[arg] = p
  1793  		p.load(stk, bp, err)
  1794  		if p.Error == nil && p.Name != "main" {
  1795  			p.Error = &PackageError{
  1796  				ImportStack: stk.Copy(),
  1797  				Err:         fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir),
  1798  			}
  1799  		}
  1800  		return p
  1801  	}
  1802  
  1803  	// Wasn't a command; must be a package.
  1804  	// If it is a local import path but names a standard package,
  1805  	// we treat it as if the user specified the standard package.
  1806  	// This lets you run go test ./ioutil in package io and be
  1807  	// referring to io/ioutil rather than a hypothetical import of
  1808  	// "./ioutil".
  1809  	if build.IsLocalImport(arg) || filepath.IsAbs(arg) {
  1810  		dir := arg
  1811  		if !filepath.IsAbs(arg) {
  1812  			dir = filepath.Join(base.Cwd, arg)
  1813  		}
  1814  		bp, _ := cfg.BuildContext.ImportDir(dir, build.FindOnly)
  1815  		if bp.ImportPath != "" && bp.ImportPath != "." {
  1816  			arg = bp.ImportPath
  1817  		}
  1818  	}
  1819  
  1820  	return LoadImport(arg, base.Cwd, nil, stk, nil, 0)
  1821  }
  1822  
  1823  // Packages returns the packages named by the
  1824  // command line arguments 'args'. If a named package
  1825  // cannot be loaded at all (for example, if the directory does not exist),
  1826  // then packages prints an error and does not include that
  1827  // package in the results. However, if errors occur trying
  1828  // to load dependencies of a named package, the named
  1829  // package is still returned, with p.Incomplete = true
  1830  // and details in p.DepsErrors.
  1831  func Packages(args []string) []*Package {
  1832  	var pkgs []*Package
  1833  	for _, pkg := range PackagesAndErrors(args) {
  1834  		if pkg.Error != nil {
  1835  			base.Errorf("can't load package: %s", pkg.Error)
  1836  			continue
  1837  		}
  1838  		pkgs = append(pkgs, pkg)
  1839  	}
  1840  	return pkgs
  1841  }
  1842  
  1843  // PackagesAndErrors is like 'packages' but returns a
  1844  // *Package for every argument, even the ones that
  1845  // cannot be loaded at all.
  1846  // The packages that fail to load will have p.Error != nil.
  1847  func PackagesAndErrors(patterns []string) []*Package {
  1848  	if len(patterns) > 0 && strings.HasSuffix(patterns[0], ".go") {
  1849  		return []*Package{GoFilesPackage(patterns)}
  1850  	}
  1851  
  1852  	matches := ImportPaths(patterns)
  1853  	var (
  1854  		pkgs    []*Package
  1855  		stk     ImportStack
  1856  		seenPkg = make(map[*Package]bool)
  1857  	)
  1858  
  1859  	for _, m := range matches {
  1860  		for _, pkg := range m.Pkgs {
  1861  			if pkg == "" {
  1862  				panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern))
  1863  			}
  1864  			p := loadPackage(pkg, &stk)
  1865  			p.Match = append(p.Match, m.Pattern)
  1866  			p.Internal.CmdlinePkg = true
  1867  			if m.Literal {
  1868  				// Note: do not set = m.Literal unconditionally
  1869  				// because maybe we'll see p matching both
  1870  				// a literal and also a non-literal pattern.
  1871  				p.Internal.CmdlinePkgLiteral = true
  1872  			}
  1873  			if seenPkg[p] {
  1874  				continue
  1875  			}
  1876  			seenPkg[p] = true
  1877  			pkgs = append(pkgs, p)
  1878  		}
  1879  	}
  1880  
  1881  	// Now that CmdlinePkg is set correctly,
  1882  	// compute the effective flags for all loaded packages
  1883  	// (not just the ones matching the patterns but also
  1884  	// their dependencies).
  1885  	setToolFlags(pkgs...)
  1886  
  1887  	return pkgs
  1888  }
  1889  
  1890  func setToolFlags(pkgs ...*Package) {
  1891  	for _, p := range PackageList(pkgs) {
  1892  		p.Internal.Asmflags = BuildAsmflags.For(p)
  1893  		p.Internal.Gcflags = BuildGcflags.For(p)
  1894  		p.Internal.Ldflags = BuildLdflags.For(p)
  1895  		p.Internal.Gccgoflags = BuildGccgoflags.For(p)
  1896  	}
  1897  }
  1898  
  1899  func ImportPaths(args []string) []*search.Match {
  1900  	if ModInit(); cfg.ModulesEnabled {
  1901  		return ModImportPaths(args)
  1902  	}
  1903  	return search.ImportPaths(args)
  1904  }
  1905  
  1906  // PackagesForBuild is like Packages but exits
  1907  // if any of the packages or their dependencies have errors
  1908  // (cannot be built).
  1909  func PackagesForBuild(args []string) []*Package {
  1910  	pkgs := PackagesAndErrors(args)
  1911  	printed := map[*PackageError]bool{}
  1912  	for _, pkg := range pkgs {
  1913  		if pkg.Error != nil {
  1914  			base.Errorf("can't load package: %s", pkg.Error)
  1915  			printed[pkg.Error] = true
  1916  		}
  1917  		for _, err := range pkg.DepsErrors {
  1918  			// Since these are errors in dependencies,
  1919  			// the same error might show up multiple times,
  1920  			// once in each package that depends on it.
  1921  			// Only print each once.
  1922  			if !printed[err] {
  1923  				printed[err] = true
  1924  				base.Errorf("%s", err)
  1925  			}
  1926  		}
  1927  	}
  1928  	base.ExitIfErrors()
  1929  
  1930  	// Check for duplicate loads of the same package.
  1931  	// That should be impossible, but if it does happen then
  1932  	// we end up trying to build the same package twice,
  1933  	// usually in parallel overwriting the same files,
  1934  	// which doesn't work very well.
  1935  	seen := map[string]bool{}
  1936  	reported := map[string]bool{}
  1937  	for _, pkg := range PackageList(pkgs) {
  1938  		if seen[pkg.ImportPath] && !reported[pkg.ImportPath] {
  1939  			reported[pkg.ImportPath] = true
  1940  			base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath)
  1941  		}
  1942  		seen[pkg.ImportPath] = true
  1943  	}
  1944  	base.ExitIfErrors()
  1945  
  1946  	return pkgs
  1947  }
  1948  
  1949  // GoFilesPackage creates a package for building a collection of Go files
  1950  // (typically named on the command line). The target is named p.a for
  1951  // package p or named after the first Go file for package main.
  1952  func GoFilesPackage(gofiles []string) *Package {
  1953  	ModInit()
  1954  
  1955  	for _, f := range gofiles {
  1956  		if !strings.HasSuffix(f, ".go") {
  1957  			base.Fatalf("named files must be .go files")
  1958  		}
  1959  	}
  1960  
  1961  	var stk ImportStack
  1962  	ctxt := cfg.BuildContext
  1963  	ctxt.UseAllFiles = true
  1964  
  1965  	// Synthesize fake "directory" that only shows the named files,
  1966  	// to make it look like this is a standard package or
  1967  	// command directory. So that local imports resolve
  1968  	// consistently, the files must all be in the same directory.
  1969  	var dirent []os.FileInfo
  1970  	var dir string
  1971  	for _, file := range gofiles {
  1972  		fi, err := os.Stat(file)
  1973  		if err != nil {
  1974  			base.Fatalf("%s", err)
  1975  		}
  1976  		if fi.IsDir() {
  1977  			base.Fatalf("%s is a directory, should be a Go file", file)
  1978  		}
  1979  		dir1, _ := filepath.Split(file)
  1980  		if dir1 == "" {
  1981  			dir1 = "./"
  1982  		}
  1983  		if dir == "" {
  1984  			dir = dir1
  1985  		} else if dir != dir1 {
  1986  			base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
  1987  		}
  1988  		dirent = append(dirent, fi)
  1989  	}
  1990  	ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
  1991  
  1992  	if cfg.ModulesEnabled {
  1993  		ModImportFromFiles(gofiles)
  1994  	}
  1995  
  1996  	var err error
  1997  	if dir == "" {
  1998  		dir = base.Cwd
  1999  	}
  2000  	dir, err = filepath.Abs(dir)
  2001  	if err != nil {
  2002  		base.Fatalf("%s", err)
  2003  	}
  2004  
  2005  	bp, err := ctxt.ImportDir(dir, 0)
  2006  	pkg := new(Package)
  2007  	pkg.Internal.Local = true
  2008  	pkg.Internal.CmdlineFiles = true
  2009  	stk.Push("main")
  2010  	pkg.load(&stk, bp, err)
  2011  	stk.Pop()
  2012  	pkg.Internal.LocalPrefix = dirToImportPath(dir)
  2013  	pkg.ImportPath = "command-line-arguments"
  2014  	pkg.Target = ""
  2015  	pkg.Match = gofiles
  2016  
  2017  	if pkg.Name == "main" {
  2018  		_, elem := filepath.Split(gofiles[0])
  2019  		exe := elem[:len(elem)-len(".go")] + cfg.ExeSuffix
  2020  		if cfg.BuildO == "" {
  2021  			cfg.BuildO = exe
  2022  		}
  2023  		if cfg.GOBIN != "" {
  2024  			pkg.Target = filepath.Join(cfg.GOBIN, exe)
  2025  		} else if cfg.ModulesEnabled {
  2026  			pkg.Target = filepath.Join(ModBinDir(), exe)
  2027  		}
  2028  	}
  2029  
  2030  	setToolFlags(pkg)
  2031  
  2032  	return pkg
  2033  }
  2034  

View as plain text