github.com/s1s1ty/go@v0.0.0-20180207192209-104445e3140f/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  func SafeArg(name string) bool {
  1210  	if name == "" {
  1211  		return false
  1212  	}
  1213  	c := name[0]
  1214  	return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf
  1215  }
  1216  
  1217  // LinkerDeps returns the list of linker-induced dependencies for main package p.
  1218  func LinkerDeps(p *Package) []string {
  1219  	// Everything links runtime.
  1220  	deps := []string{"runtime"}
  1221  
  1222  	// External linking mode forces an import of runtime/cgo.
  1223  	if externalLinkingForced(p) {
  1224  		deps = append(deps, "runtime/cgo")
  1225  	}
  1226  	// On ARM with GOARM=5, it forces an import of math, for soft floating point.
  1227  	if cfg.Goarch == "arm" {
  1228  		deps = append(deps, "math")
  1229  	}
  1230  	// Using the race detector forces an import of runtime/race.
  1231  	if cfg.BuildRace {
  1232  		deps = append(deps, "runtime/race")
  1233  	}
  1234  	// Using memory sanitizer forces an import of runtime/msan.
  1235  	if cfg.BuildMSan {
  1236  		deps = append(deps, "runtime/msan")
  1237  	}
  1238  
  1239  	return deps
  1240  }
  1241  
  1242  // externalLinkingForced reports whether external linking is being
  1243  // forced even for programs that do not use cgo.
  1244  func externalLinkingForced(p *Package) bool {
  1245  	// Some targets must use external linking even inside GOROOT.
  1246  	switch cfg.BuildContext.GOOS {
  1247  	case "android":
  1248  		return true
  1249  	case "darwin":
  1250  		switch cfg.BuildContext.GOARCH {
  1251  		case "arm", "arm64":
  1252  			return true
  1253  		}
  1254  	}
  1255  
  1256  	if !cfg.BuildContext.CgoEnabled {
  1257  		return false
  1258  	}
  1259  	// Currently build modes c-shared, pie (on systems that do not
  1260  	// support PIE with internal linking mode (currently all
  1261  	// systems: issue #18968)), plugin, and -linkshared force
  1262  	// external linking mode, as of course does
  1263  	// -ldflags=-linkmode=external. External linking mode forces
  1264  	// an import of runtime/cgo.
  1265  	pieCgo := cfg.BuildBuildmode == "pie"
  1266  	linkmodeExternal := false
  1267  	if p != nil {
  1268  		ldflags := BuildLdflags.For(p)
  1269  		for i, a := range ldflags {
  1270  			if a == "-linkmode=external" {
  1271  				linkmodeExternal = true
  1272  			}
  1273  			if a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" {
  1274  				linkmodeExternal = true
  1275  			}
  1276  		}
  1277  	}
  1278  
  1279  	return cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" || pieCgo || cfg.BuildLinkshared || linkmodeExternal
  1280  }
  1281  
  1282  // mkAbs rewrites list, which must be paths relative to p.Dir,
  1283  // into a sorted list of absolute paths. It edits list in place but for
  1284  // convenience also returns list back to its caller.
  1285  func (p *Package) mkAbs(list []string) []string {
  1286  	for i, f := range list {
  1287  		list[i] = filepath.Join(p.Dir, f)
  1288  	}
  1289  	sort.Strings(list)
  1290  	return list
  1291  }
  1292  
  1293  // InternalGoFiles returns the list of Go files being built for the package,
  1294  // using absolute paths.
  1295  func (p *Package) InternalGoFiles() []string {
  1296  	return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
  1297  }
  1298  
  1299  // InternalGoFiles returns the list of all Go files possibly relevant for the package,
  1300  // using absolute paths. "Possibly relevant" means that files are not excluded
  1301  // due to build tags, but files with names beginning with . or _ are still excluded.
  1302  func (p *Package) InternalAllGoFiles() []string {
  1303  	var extra []string
  1304  	for _, f := range p.IgnoredGoFiles {
  1305  		if f != "" && f[0] != '.' || f[0] != '_' {
  1306  			extra = append(extra, f)
  1307  		}
  1308  	}
  1309  	return p.mkAbs(str.StringList(extra, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles))
  1310  }
  1311  
  1312  // usesSwig reports whether the package needs to run SWIG.
  1313  func (p *Package) UsesSwig() bool {
  1314  	return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0
  1315  }
  1316  
  1317  // usesCgo reports whether the package needs to run cgo
  1318  func (p *Package) UsesCgo() bool {
  1319  	return len(p.CgoFiles) > 0
  1320  }
  1321  
  1322  // packageList returns the list of packages in the dag rooted at roots
  1323  // as visited in a depth-first post-order traversal.
  1324  func PackageList(roots []*Package) []*Package {
  1325  	seen := map[*Package]bool{}
  1326  	all := []*Package{}
  1327  	var walk func(*Package)
  1328  	walk = func(p *Package) {
  1329  		if seen[p] {
  1330  			return
  1331  		}
  1332  		seen[p] = true
  1333  		for _, p1 := range p.Internal.Imports {
  1334  			walk(p1)
  1335  		}
  1336  		all = append(all, p)
  1337  	}
  1338  	for _, root := range roots {
  1339  		walk(root)
  1340  	}
  1341  	return all
  1342  }
  1343  
  1344  var cmdCache = map[string]*Package{}
  1345  
  1346  func ClearCmdCache() {
  1347  	for name := range cmdCache {
  1348  		delete(cmdCache, name)
  1349  	}
  1350  }
  1351  
  1352  // loadPackage is like loadImport but is used for command-line arguments,
  1353  // not for paths found in import statements. In addition to ordinary import paths,
  1354  // loadPackage accepts pseudo-paths beginning with cmd/ to denote commands
  1355  // in the Go command directory, as well as paths to those directories.
  1356  func LoadPackage(arg string, stk *ImportStack) *Package {
  1357  	if build.IsLocalImport(arg) {
  1358  		dir := arg
  1359  		if !filepath.IsAbs(dir) {
  1360  			if abs, err := filepath.Abs(dir); err == nil {
  1361  				// interpret relative to current directory
  1362  				dir = abs
  1363  			}
  1364  		}
  1365  		if sub, ok := hasSubdir(cfg.GOROOTsrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") {
  1366  			arg = sub
  1367  		}
  1368  	}
  1369  	if strings.HasPrefix(arg, "cmd/") && !strings.Contains(arg[4:], "/") {
  1370  		if p := cmdCache[arg]; p != nil {
  1371  			return p
  1372  		}
  1373  		stk.Push(arg)
  1374  		defer stk.Pop()
  1375  
  1376  		bp, err := cfg.BuildContext.ImportDir(filepath.Join(cfg.GOROOTsrc, arg), 0)
  1377  		bp.ImportPath = arg
  1378  		bp.Goroot = true
  1379  		bp.BinDir = cfg.GOROOTbin
  1380  		if cfg.GOROOTbin != "" {
  1381  			bp.BinDir = cfg.GOROOTbin
  1382  		}
  1383  		bp.Root = cfg.GOROOT
  1384  		bp.SrcRoot = cfg.GOROOTsrc
  1385  		p := new(Package)
  1386  		cmdCache[arg] = p
  1387  		p.load(stk, bp, err)
  1388  		if p.Error == nil && p.Name != "main" {
  1389  			p.Error = &PackageError{
  1390  				ImportStack: stk.Copy(),
  1391  				Err:         fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir),
  1392  			}
  1393  		}
  1394  		return p
  1395  	}
  1396  
  1397  	// Wasn't a command; must be a package.
  1398  	// If it is a local import path but names a standard package,
  1399  	// we treat it as if the user specified the standard package.
  1400  	// This lets you run go test ./ioutil in package io and be
  1401  	// referring to io/ioutil rather than a hypothetical import of
  1402  	// "./ioutil".
  1403  	if build.IsLocalImport(arg) {
  1404  		bp, _ := cfg.BuildContext.ImportDir(filepath.Join(base.Cwd, arg), build.FindOnly)
  1405  		if bp.ImportPath != "" && bp.ImportPath != "." {
  1406  			arg = bp.ImportPath
  1407  		}
  1408  	}
  1409  
  1410  	return LoadImport(arg, base.Cwd, nil, stk, nil, 0)
  1411  }
  1412  
  1413  // packages returns the packages named by the
  1414  // command line arguments 'args'. If a named package
  1415  // cannot be loaded at all (for example, if the directory does not exist),
  1416  // then packages prints an error and does not include that
  1417  // package in the results. However, if errors occur trying
  1418  // to load dependencies of a named package, the named
  1419  // package is still returned, with p.Incomplete = true
  1420  // and details in p.DepsErrors.
  1421  func Packages(args []string) []*Package {
  1422  	var pkgs []*Package
  1423  	for _, pkg := range PackagesAndErrors(args) {
  1424  		if pkg.Error != nil {
  1425  			base.Errorf("can't load package: %s", pkg.Error)
  1426  			continue
  1427  		}
  1428  		pkgs = append(pkgs, pkg)
  1429  	}
  1430  	return pkgs
  1431  }
  1432  
  1433  // packagesAndErrors is like 'packages' but returns a
  1434  // *Package for every argument, even the ones that
  1435  // cannot be loaded at all.
  1436  // The packages that fail to load will have p.Error != nil.
  1437  func PackagesAndErrors(args []string) []*Package {
  1438  	if len(args) > 0 && strings.HasSuffix(args[0], ".go") {
  1439  		return []*Package{GoFilesPackage(args)}
  1440  	}
  1441  
  1442  	args = ImportPaths(args)
  1443  	var (
  1444  		pkgs    []*Package
  1445  		stk     ImportStack
  1446  		seenArg = make(map[string]bool)
  1447  		seenPkg = make(map[*Package]bool)
  1448  	)
  1449  
  1450  	for _, arg := range args {
  1451  		if seenArg[arg] {
  1452  			continue
  1453  		}
  1454  		seenArg[arg] = true
  1455  		pkg := LoadPackage(arg, &stk)
  1456  		if seenPkg[pkg] {
  1457  			continue
  1458  		}
  1459  		seenPkg[pkg] = true
  1460  		pkgs = append(pkgs, pkg)
  1461  	}
  1462  
  1463  	return pkgs
  1464  }
  1465  
  1466  // packagesForBuild is like 'packages' but fails if any of
  1467  // the packages or their dependencies have errors
  1468  // (cannot be built).
  1469  func PackagesForBuild(args []string) []*Package {
  1470  	pkgs := PackagesAndErrors(args)
  1471  	printed := map[*PackageError]bool{}
  1472  	for _, pkg := range pkgs {
  1473  		if pkg.Error != nil {
  1474  			base.Errorf("can't load package: %s", pkg.Error)
  1475  		}
  1476  		for _, err := range pkg.DepsErrors {
  1477  			// Since these are errors in dependencies,
  1478  			// the same error might show up multiple times,
  1479  			// once in each package that depends on it.
  1480  			// Only print each once.
  1481  			if !printed[err] {
  1482  				printed[err] = true
  1483  				base.Errorf("%s", err)
  1484  			}
  1485  		}
  1486  	}
  1487  	base.ExitIfErrors()
  1488  
  1489  	// Check for duplicate loads of the same package.
  1490  	// That should be impossible, but if it does happen then
  1491  	// we end up trying to build the same package twice,
  1492  	// usually in parallel overwriting the same files,
  1493  	// which doesn't work very well.
  1494  	seen := map[string]bool{}
  1495  	reported := map[string]bool{}
  1496  	for _, pkg := range PackageList(pkgs) {
  1497  		if seen[pkg.ImportPath] && !reported[pkg.ImportPath] {
  1498  			reported[pkg.ImportPath] = true
  1499  			base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath)
  1500  		}
  1501  		seen[pkg.ImportPath] = true
  1502  	}
  1503  	base.ExitIfErrors()
  1504  
  1505  	return pkgs
  1506  }
  1507  
  1508  // GoFilesPackage creates a package for building a collection of Go files
  1509  // (typically named on the command line). The target is named p.a for
  1510  // package p or named after the first Go file for package main.
  1511  func GoFilesPackage(gofiles []string) *Package {
  1512  	// TODO: Remove this restriction.
  1513  	for _, f := range gofiles {
  1514  		if !strings.HasSuffix(f, ".go") {
  1515  			base.Fatalf("named files must be .go files")
  1516  		}
  1517  	}
  1518  
  1519  	var stk ImportStack
  1520  	ctxt := cfg.BuildContext
  1521  	ctxt.UseAllFiles = true
  1522  
  1523  	// Synthesize fake "directory" that only shows the named files,
  1524  	// to make it look like this is a standard package or
  1525  	// command directory. So that local imports resolve
  1526  	// consistently, the files must all be in the same directory.
  1527  	var dirent []os.FileInfo
  1528  	var dir string
  1529  	for _, file := range gofiles {
  1530  		fi, err := os.Stat(file)
  1531  		if err != nil {
  1532  			base.Fatalf("%s", err)
  1533  		}
  1534  		if fi.IsDir() {
  1535  			base.Fatalf("%s is a directory, should be a Go file", file)
  1536  		}
  1537  		dir1, _ := filepath.Split(file)
  1538  		if dir1 == "" {
  1539  			dir1 = "./"
  1540  		}
  1541  		if dir == "" {
  1542  			dir = dir1
  1543  		} else if dir != dir1 {
  1544  			base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1)
  1545  		}
  1546  		dirent = append(dirent, fi)
  1547  	}
  1548  	ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil }
  1549  
  1550  	var err error
  1551  	if dir == "" {
  1552  		dir = base.Cwd
  1553  	}
  1554  	dir, err = filepath.Abs(dir)
  1555  	if err != nil {
  1556  		base.Fatalf("%s", err)
  1557  	}
  1558  
  1559  	bp, err := ctxt.ImportDir(dir, 0)
  1560  	pkg := new(Package)
  1561  	pkg.Internal.Local = true
  1562  	pkg.Internal.CmdlineFiles = true
  1563  	stk.Push("main")
  1564  	pkg.load(&stk, bp, err)
  1565  	stk.Pop()
  1566  	pkg.Internal.LocalPrefix = dirToImportPath(dir)
  1567  	pkg.ImportPath = "command-line-arguments"
  1568  	pkg.Target = ""
  1569  
  1570  	if pkg.Name == "main" {
  1571  		_, elem := filepath.Split(gofiles[0])
  1572  		exe := elem[:len(elem)-len(".go")] + cfg.ExeSuffix
  1573  		if cfg.BuildO == "" {
  1574  			cfg.BuildO = exe
  1575  		}
  1576  		if cfg.GOBIN != "" {
  1577  			pkg.Target = filepath.Join(cfg.GOBIN, exe)
  1578  		}
  1579  	}
  1580  
  1581  	return pkg
  1582  }
  1583  
  1584  // TestPackagesFor returns package structs ptest, the package p plus
  1585  // its test files, and pxtest, the external tests of package p.
  1586  // pxtest may be nil. If there are no test files, forceTest decides
  1587  // whether this returns a new package struct or just returns p.
  1588  func TestPackagesFor(p *Package, forceTest bool) (ptest, pxtest *Package, err error) {
  1589  	var imports, ximports []*Package
  1590  	var stk ImportStack
  1591  	stk.Push(p.ImportPath + " (test)")
  1592  	rawTestImports := str.StringList(p.TestImports)
  1593  	for i, path := range p.TestImports {
  1594  		p1 := LoadImport(path, p.Dir, p, &stk, p.Internal.Build.TestImportPos[path], UseVendor)
  1595  		if p1.Error != nil {
  1596  			return nil, nil, p1.Error
  1597  		}
  1598  		if len(p1.DepsErrors) > 0 {
  1599  			err := p1.DepsErrors[0]
  1600  			err.Pos = "" // show full import stack
  1601  			return nil, nil, err
  1602  		}
  1603  		if str.Contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath {
  1604  			// Same error that loadPackage returns (via reusePackage) in pkg.go.
  1605  			// Can't change that code, because that code is only for loading the
  1606  			// non-test copy of a package.
  1607  			err := &PackageError{
  1608  				ImportStack:   testImportStack(stk[0], p1, p.ImportPath),
  1609  				Err:           "import cycle not allowed in test",
  1610  				IsImportCycle: true,
  1611  			}
  1612  			return nil, nil, err
  1613  		}
  1614  		p.TestImports[i] = p1.ImportPath
  1615  		imports = append(imports, p1)
  1616  	}
  1617  	stk.Pop()
  1618  	stk.Push(p.ImportPath + "_test")
  1619  	pxtestNeedsPtest := false
  1620  	rawXTestImports := str.StringList(p.XTestImports)
  1621  	for i, path := range p.XTestImports {
  1622  		p1 := LoadImport(path, p.Dir, p, &stk, p.Internal.Build.XTestImportPos[path], UseVendor)
  1623  		if p1.Error != nil {
  1624  			return nil, nil, p1.Error
  1625  		}
  1626  		if len(p1.DepsErrors) > 0 {
  1627  			err := p1.DepsErrors[0]
  1628  			err.Pos = "" // show full import stack
  1629  			return nil, nil, err
  1630  		}
  1631  		if p1.ImportPath == p.ImportPath {
  1632  			pxtestNeedsPtest = true
  1633  		} else {
  1634  			ximports = append(ximports, p1)
  1635  		}
  1636  		p.XTestImports[i] = p1.ImportPath
  1637  	}
  1638  	stk.Pop()
  1639  
  1640  	// Test package.
  1641  	if len(p.TestGoFiles) > 0 || forceTest {
  1642  		ptest = new(Package)
  1643  		*ptest = *p
  1644  		ptest.GoFiles = nil
  1645  		ptest.GoFiles = append(ptest.GoFiles, p.GoFiles...)
  1646  		ptest.GoFiles = append(ptest.GoFiles, p.TestGoFiles...)
  1647  		ptest.Target = ""
  1648  		// Note: The preparation of the vet config requires that common
  1649  		// indexes in ptest.Imports, ptest.Internal.Imports, and ptest.Internal.RawImports
  1650  		// all line up (but RawImports can be shorter than the others).
  1651  		// That is, for 0 ≤ i < len(RawImports),
  1652  		// RawImports[i] is the import string in the program text,
  1653  		// Imports[i] is the expanded import string (vendoring applied or relative path expanded away),
  1654  		// and Internal.Imports[i] is the corresponding *Package.
  1655  		// Any implicitly added imports appear in Imports and Internal.Imports
  1656  		// but not RawImports (because they were not in the source code).
  1657  		// We insert TestImports, imports, and rawTestImports at the start of
  1658  		// these lists to preserve the alignment.
  1659  		ptest.Imports = str.StringList(p.TestImports, p.Imports)
  1660  		ptest.Internal.Imports = append(imports, p.Internal.Imports...)
  1661  		ptest.Internal.RawImports = str.StringList(rawTestImports, p.Internal.RawImports)
  1662  		ptest.Internal.ForceLibrary = true
  1663  		ptest.Internal.Build = new(build.Package)
  1664  		*ptest.Internal.Build = *p.Internal.Build
  1665  		m := map[string][]token.Position{}
  1666  		for k, v := range p.Internal.Build.ImportPos {
  1667  			m[k] = append(m[k], v...)
  1668  		}
  1669  		for k, v := range p.Internal.Build.TestImportPos {
  1670  			m[k] = append(m[k], v...)
  1671  		}
  1672  		ptest.Internal.Build.ImportPos = m
  1673  	} else {
  1674  		ptest = p
  1675  	}
  1676  
  1677  	// External test package.
  1678  	if len(p.XTestGoFiles) > 0 {
  1679  		pxtest = &Package{
  1680  			PackagePublic: PackagePublic{
  1681  				Name:       p.Name + "_test",
  1682  				ImportPath: p.ImportPath + "_test",
  1683  				Root:       p.Root,
  1684  				Dir:        p.Dir,
  1685  				GoFiles:    p.XTestGoFiles,
  1686  				Imports:    p.XTestImports,
  1687  			},
  1688  			Internal: PackageInternal{
  1689  				LocalPrefix: p.Internal.LocalPrefix,
  1690  				Build: &build.Package{
  1691  					ImportPos: p.Internal.Build.XTestImportPos,
  1692  				},
  1693  				Imports:    ximports,
  1694  				RawImports: rawXTestImports,
  1695  
  1696  				Asmflags:   p.Internal.Asmflags,
  1697  				Gcflags:    p.Internal.Gcflags,
  1698  				Ldflags:    p.Internal.Ldflags,
  1699  				Gccgoflags: p.Internal.Gccgoflags,
  1700  			},
  1701  		}
  1702  		if pxtestNeedsPtest {
  1703  			pxtest.Internal.Imports = append(pxtest.Internal.Imports, ptest)
  1704  		}
  1705  	}
  1706  
  1707  	return ptest, pxtest, nil
  1708  }
  1709  
  1710  func testImportStack(top string, p *Package, target string) []string {
  1711  	stk := []string{top, p.ImportPath}
  1712  Search:
  1713  	for p.ImportPath != target {
  1714  		for _, p1 := range p.Internal.Imports {
  1715  			if p1.ImportPath == target || str.Contains(p1.Deps, target) {
  1716  				stk = append(stk, p1.ImportPath)
  1717  				p = p1
  1718  				continue Search
  1719  			}
  1720  		}
  1721  		// Can't happen, but in case it does...
  1722  		stk = append(stk, "<lost path to cycle>")
  1723  		break
  1724  	}
  1725  	return stk
  1726  }