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