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