...

Source file src/pkg/go/build/build.go

     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 build
     6	
     7	import (
     8		"bytes"
     9		"errors"
    10		"fmt"
    11		"go/ast"
    12		"go/doc"
    13		"go/parser"
    14		"go/token"
    15		"internal/goroot"
    16		"internal/goversion"
    17		"io"
    18		"io/ioutil"
    19		"log"
    20		"os"
    21		"os/exec"
    22		pathpkg "path"
    23		"path/filepath"
    24		"runtime"
    25		"sort"
    26		"strconv"
    27		"strings"
    28		"unicode"
    29		"unicode/utf8"
    30	)
    31	
    32	// A Context specifies the supporting context for a build.
    33	type Context struct {
    34		GOARCH      string // target architecture
    35		GOOS        string // target operating system
    36		GOROOT      string // Go root
    37		GOPATH      string // Go path
    38		CgoEnabled  bool   // whether cgo files are included
    39		UseAllFiles bool   // use files regardless of +build lines, file names
    40		Compiler    string // compiler to assume when computing target paths
    41	
    42		// The build and release tags specify build constraints
    43		// that should be considered satisfied when processing +build lines.
    44		// Clients creating a new context may customize BuildTags, which
    45		// defaults to empty, but it is usually an error to customize ReleaseTags,
    46		// which defaults to the list of Go releases the current release is compatible with.
    47		// BuildTags is not set for the Default build Context.
    48		// In addition to the BuildTags and ReleaseTags, build constraints
    49		// consider the values of GOARCH and GOOS as satisfied tags.
    50		// The last element in ReleaseTags is assumed to be the current release.
    51		BuildTags   []string
    52		ReleaseTags []string
    53	
    54		// The install suffix specifies a suffix to use in the name of the installation
    55		// directory. By default it is empty, but custom builds that need to keep
    56		// their outputs separate can set InstallSuffix to do so. For example, when
    57		// using the race detector, the go command uses InstallSuffix = "race", so
    58		// that on a Linux/386 system, packages are written to a directory named
    59		// "linux_386_race" instead of the usual "linux_386".
    60		InstallSuffix string
    61	
    62		// By default, Import uses the operating system's file system calls
    63		// to read directories and files. To read from other sources,
    64		// callers can set the following functions. They all have default
    65		// behaviors that use the local file system, so clients need only set
    66		// the functions whose behaviors they wish to change.
    67	
    68		// JoinPath joins the sequence of path fragments into a single path.
    69		// If JoinPath is nil, Import uses filepath.Join.
    70		JoinPath func(elem ...string) string
    71	
    72		// SplitPathList splits the path list into a slice of individual paths.
    73		// If SplitPathList is nil, Import uses filepath.SplitList.
    74		SplitPathList func(list string) []string
    75	
    76		// IsAbsPath reports whether path is an absolute path.
    77		// If IsAbsPath is nil, Import uses filepath.IsAbs.
    78		IsAbsPath func(path string) bool
    79	
    80		// IsDir reports whether the path names a directory.
    81		// If IsDir is nil, Import calls os.Stat and uses the result's IsDir method.
    82		IsDir func(path string) bool
    83	
    84		// HasSubdir reports whether dir is lexically a subdirectory of
    85		// root, perhaps multiple levels below. It does not try to check
    86		// whether dir exists.
    87		// If so, HasSubdir sets rel to a slash-separated path that
    88		// can be joined to root to produce a path equivalent to dir.
    89		// If HasSubdir is nil, Import uses an implementation built on
    90		// filepath.EvalSymlinks.
    91		HasSubdir func(root, dir string) (rel string, ok bool)
    92	
    93		// ReadDir returns a slice of os.FileInfo, sorted by Name,
    94		// describing the content of the named directory.
    95		// If ReadDir is nil, Import uses ioutil.ReadDir.
    96		ReadDir func(dir string) ([]os.FileInfo, error)
    97	
    98		// OpenFile opens a file (not a directory) for reading.
    99		// If OpenFile is nil, Import uses os.Open.
   100		OpenFile func(path string) (io.ReadCloser, error)
   101	}
   102	
   103	// joinPath calls ctxt.JoinPath (if not nil) or else filepath.Join.
   104	func (ctxt *Context) joinPath(elem ...string) string {
   105		if f := ctxt.JoinPath; f != nil {
   106			return f(elem...)
   107		}
   108		return filepath.Join(elem...)
   109	}
   110	
   111	// splitPathList calls ctxt.SplitPathList (if not nil) or else filepath.SplitList.
   112	func (ctxt *Context) splitPathList(s string) []string {
   113		if f := ctxt.SplitPathList; f != nil {
   114			return f(s)
   115		}
   116		return filepath.SplitList(s)
   117	}
   118	
   119	// isAbsPath calls ctxt.IsAbsPath (if not nil) or else filepath.IsAbs.
   120	func (ctxt *Context) isAbsPath(path string) bool {
   121		if f := ctxt.IsAbsPath; f != nil {
   122			return f(path)
   123		}
   124		return filepath.IsAbs(path)
   125	}
   126	
   127	// isDir calls ctxt.IsDir (if not nil) or else uses os.Stat.
   128	func (ctxt *Context) isDir(path string) bool {
   129		if f := ctxt.IsDir; f != nil {
   130			return f(path)
   131		}
   132		fi, err := os.Stat(path)
   133		return err == nil && fi.IsDir()
   134	}
   135	
   136	// hasSubdir calls ctxt.HasSubdir (if not nil) or else uses
   137	// the local file system to answer the question.
   138	func (ctxt *Context) hasSubdir(root, dir string) (rel string, ok bool) {
   139		if f := ctxt.HasSubdir; f != nil {
   140			return f(root, dir)
   141		}
   142	
   143		// Try using paths we received.
   144		if rel, ok = hasSubdir(root, dir); ok {
   145			return
   146		}
   147	
   148		// Try expanding symlinks and comparing
   149		// expanded against unexpanded and
   150		// expanded against expanded.
   151		rootSym, _ := filepath.EvalSymlinks(root)
   152		dirSym, _ := filepath.EvalSymlinks(dir)
   153	
   154		if rel, ok = hasSubdir(rootSym, dir); ok {
   155			return
   156		}
   157		if rel, ok = hasSubdir(root, dirSym); ok {
   158			return
   159		}
   160		return hasSubdir(rootSym, dirSym)
   161	}
   162	
   163	// hasSubdir reports if dir is within root by performing lexical analysis only.
   164	func hasSubdir(root, dir string) (rel string, ok bool) {
   165		const sep = string(filepath.Separator)
   166		root = filepath.Clean(root)
   167		if !strings.HasSuffix(root, sep) {
   168			root += sep
   169		}
   170		dir = filepath.Clean(dir)
   171		if !strings.HasPrefix(dir, root) {
   172			return "", false
   173		}
   174		return filepath.ToSlash(dir[len(root):]), true
   175	}
   176	
   177	// readDir calls ctxt.ReadDir (if not nil) or else ioutil.ReadDir.
   178	func (ctxt *Context) readDir(path string) ([]os.FileInfo, error) {
   179		if f := ctxt.ReadDir; f != nil {
   180			return f(path)
   181		}
   182		return ioutil.ReadDir(path)
   183	}
   184	
   185	// openFile calls ctxt.OpenFile (if not nil) or else os.Open.
   186	func (ctxt *Context) openFile(path string) (io.ReadCloser, error) {
   187		if fn := ctxt.OpenFile; fn != nil {
   188			return fn(path)
   189		}
   190	
   191		f, err := os.Open(path)
   192		if err != nil {
   193			return nil, err // nil interface
   194		}
   195		return f, nil
   196	}
   197	
   198	// isFile determines whether path is a file by trying to open it.
   199	// It reuses openFile instead of adding another function to the
   200	// list in Context.
   201	func (ctxt *Context) isFile(path string) bool {
   202		f, err := ctxt.openFile(path)
   203		if err != nil {
   204			return false
   205		}
   206		f.Close()
   207		return true
   208	}
   209	
   210	// gopath returns the list of Go path directories.
   211	func (ctxt *Context) gopath() []string {
   212		var all []string
   213		for _, p := range ctxt.splitPathList(ctxt.GOPATH) {
   214			if p == "" || p == ctxt.GOROOT {
   215				// Empty paths are uninteresting.
   216				// If the path is the GOROOT, ignore it.
   217				// People sometimes set GOPATH=$GOROOT.
   218				// Do not get confused by this common mistake.
   219				continue
   220			}
   221			if strings.HasPrefix(p, "~") {
   222				// Path segments starting with ~ on Unix are almost always
   223				// users who have incorrectly quoted ~ while setting GOPATH,
   224				// preventing it from expanding to $HOME.
   225				// The situation is made more confusing by the fact that
   226				// bash allows quoted ~ in $PATH (most shells do not).
   227				// Do not get confused by this, and do not try to use the path.
   228				// It does not exist, and printing errors about it confuses
   229				// those users even more, because they think "sure ~ exists!".
   230				// The go command diagnoses this situation and prints a
   231				// useful error.
   232				// On Windows, ~ is used in short names, such as c:\progra~1
   233				// for c:\program files.
   234				continue
   235			}
   236			all = append(all, p)
   237		}
   238		return all
   239	}
   240	
   241	// SrcDirs returns a list of package source root directories.
   242	// It draws from the current Go root and Go path but omits directories
   243	// that do not exist.
   244	func (ctxt *Context) SrcDirs() []string {
   245		var all []string
   246		if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" {
   247			dir := ctxt.joinPath(ctxt.GOROOT, "src")
   248			if ctxt.isDir(dir) {
   249				all = append(all, dir)
   250			}
   251		}
   252		for _, p := range ctxt.gopath() {
   253			dir := ctxt.joinPath(p, "src")
   254			if ctxt.isDir(dir) {
   255				all = append(all, dir)
   256			}
   257		}
   258		return all
   259	}
   260	
   261	// Default is the default Context for builds.
   262	// It uses the GOARCH, GOOS, GOROOT, and GOPATH environment variables
   263	// if set, or else the compiled code's GOARCH, GOOS, and GOROOT.
   264	var Default Context = defaultContext()
   265	
   266	func defaultGOPATH() string {
   267		env := "HOME"
   268		if runtime.GOOS == "windows" {
   269			env = "USERPROFILE"
   270		} else if runtime.GOOS == "plan9" {
   271			env = "home"
   272		}
   273		if home := os.Getenv(env); home != "" {
   274			def := filepath.Join(home, "go")
   275			if filepath.Clean(def) == filepath.Clean(runtime.GOROOT()) {
   276				// Don't set the default GOPATH to GOROOT,
   277				// as that will trigger warnings from the go tool.
   278				return ""
   279			}
   280			return def
   281		}
   282		return ""
   283	}
   284	
   285	var defaultReleaseTags []string
   286	
   287	func defaultContext() Context {
   288		var c Context
   289	
   290		c.GOARCH = envOr("GOARCH", runtime.GOARCH)
   291		c.GOOS = envOr("GOOS", runtime.GOOS)
   292		c.GOROOT = pathpkg.Clean(runtime.GOROOT())
   293		c.GOPATH = envOr("GOPATH", defaultGOPATH())
   294		c.Compiler = runtime.Compiler
   295	
   296		// Each major Go release in the Go 1.x series adds a new
   297		// "go1.x" release tag. That is, the go1.x tag is present in
   298		// all releases >= Go 1.x. Code that requires Go 1.x or later
   299		// should say "+build go1.x", and code that should only be
   300		// built before Go 1.x (perhaps it is the stub to use in that
   301		// case) should say "+build !go1.x".
   302		// The last element in ReleaseTags is the current release.
   303		for i := 1; i <= goversion.Version; i++ {
   304			c.ReleaseTags = append(c.ReleaseTags, "go1."+strconv.Itoa(i))
   305		}
   306	
   307		defaultReleaseTags = append([]string{}, c.ReleaseTags...) // our own private copy
   308	
   309		env := os.Getenv("CGO_ENABLED")
   310		if env == "" {
   311			env = defaultCGO_ENABLED
   312		}
   313		switch env {
   314		case "1":
   315			c.CgoEnabled = true
   316		case "0":
   317			c.CgoEnabled = false
   318		default:
   319			// cgo must be explicitly enabled for cross compilation builds
   320			if runtime.GOARCH == c.GOARCH && runtime.GOOS == c.GOOS {
   321				c.CgoEnabled = cgoEnabled[c.GOOS+"/"+c.GOARCH]
   322				break
   323			}
   324			c.CgoEnabled = false
   325		}
   326	
   327		return c
   328	}
   329	
   330	func envOr(name, def string) string {
   331		s := os.Getenv(name)
   332		if s == "" {
   333			return def
   334		}
   335		return s
   336	}
   337	
   338	// An ImportMode controls the behavior of the Import method.
   339	type ImportMode uint
   340	
   341	const (
   342		// If FindOnly is set, Import stops after locating the directory
   343		// that should contain the sources for a package. It does not
   344		// read any files in the directory.
   345		FindOnly ImportMode = 1 << iota
   346	
   347		// If AllowBinary is set, Import can be satisfied by a compiled
   348		// package object without corresponding sources.
   349		//
   350		// Deprecated:
   351		// The supported way to create a compiled-only package is to
   352		// write source code containing a //go:binary-only-package comment at
   353		// the top of the file. Such a package will be recognized
   354		// regardless of this flag setting (because it has source code)
   355		// and will have BinaryOnly set to true in the returned Package.
   356		AllowBinary
   357	
   358		// If ImportComment is set, parse import comments on package statements.
   359		// Import returns an error if it finds a comment it cannot understand
   360		// or finds conflicting comments in multiple source files.
   361		// See golang.org/s/go14customimport for more information.
   362		ImportComment
   363	
   364		// By default, Import searches vendor directories
   365		// that apply in the given source directory before searching
   366		// the GOROOT and GOPATH roots.
   367		// If an Import finds and returns a package using a vendor
   368		// directory, the resulting ImportPath is the complete path
   369		// to the package, including the path elements leading up
   370		// to and including "vendor".
   371		// For example, if Import("y", "x/subdir", 0) finds
   372		// "x/vendor/y", the returned package's ImportPath is "x/vendor/y",
   373		// not plain "y".
   374		// See golang.org/s/go15vendor for more information.
   375		//
   376		// Setting IgnoreVendor ignores vendor directories.
   377		//
   378		// In contrast to the package's ImportPath,
   379		// the returned package's Imports, TestImports, and XTestImports
   380		// are always the exact import paths from the source files:
   381		// Import makes no attempt to resolve or check those paths.
   382		IgnoreVendor
   383	)
   384	
   385	// A Package describes the Go package found in a directory.
   386	type Package struct {
   387		Dir           string   // directory containing package sources
   388		Name          string   // package name
   389		ImportComment string   // path in import comment on package statement
   390		Doc           string   // documentation synopsis
   391		ImportPath    string   // import path of package ("" if unknown)
   392		Root          string   // root of Go tree where this package lives
   393		SrcRoot       string   // package source root directory ("" if unknown)
   394		PkgRoot       string   // package install root directory ("" if unknown)
   395		PkgTargetRoot string   // architecture dependent install root directory ("" if unknown)
   396		BinDir        string   // command install directory ("" if unknown)
   397		Goroot        bool     // package found in Go root
   398		PkgObj        string   // installed .a file
   399		AllTags       []string // tags that can influence file selection in this directory
   400		ConflictDir   string   // this directory shadows Dir in $GOPATH
   401		BinaryOnly    bool     // cannot be rebuilt from source (has //go:binary-only-package comment)
   402	
   403		// Source files
   404		GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
   405		CgoFiles       []string // .go source files that import "C"
   406		IgnoredGoFiles []string // .go source files ignored for this build
   407		InvalidGoFiles []string // .go source files with detected problems (parse error, wrong package name, and so on)
   408		CFiles         []string // .c source files
   409		CXXFiles       []string // .cc, .cpp and .cxx source files
   410		MFiles         []string // .m (Objective-C) source files
   411		HFiles         []string // .h, .hh, .hpp and .hxx source files
   412		FFiles         []string // .f, .F, .for and .f90 Fortran source files
   413		SFiles         []string // .s source files
   414		SwigFiles      []string // .swig files
   415		SwigCXXFiles   []string // .swigcxx files
   416		SysoFiles      []string // .syso system object files to add to archive
   417	
   418		// Cgo directives
   419		CgoCFLAGS    []string // Cgo CFLAGS directives
   420		CgoCPPFLAGS  []string // Cgo CPPFLAGS directives
   421		CgoCXXFLAGS  []string // Cgo CXXFLAGS directives
   422		CgoFFLAGS    []string // Cgo FFLAGS directives
   423		CgoLDFLAGS   []string // Cgo LDFLAGS directives
   424		CgoPkgConfig []string // Cgo pkg-config directives
   425	
   426		// Dependency information
   427		Imports   []string                    // import paths from GoFiles, CgoFiles
   428		ImportPos map[string][]token.Position // line information for Imports
   429	
   430		// Test information
   431		TestGoFiles    []string                    // _test.go files in package
   432		TestImports    []string                    // import paths from TestGoFiles
   433		TestImportPos  map[string][]token.Position // line information for TestImports
   434		XTestGoFiles   []string                    // _test.go files outside package
   435		XTestImports   []string                    // import paths from XTestGoFiles
   436		XTestImportPos map[string][]token.Position // line information for XTestImports
   437	}
   438	
   439	// IsCommand reports whether the package is considered a
   440	// command to be installed (not just a library).
   441	// Packages named "main" are treated as commands.
   442	func (p *Package) IsCommand() bool {
   443		return p.Name == "main"
   444	}
   445	
   446	// ImportDir is like Import but processes the Go package found in
   447	// the named directory.
   448	func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) {
   449		return ctxt.Import(".", dir, mode)
   450	}
   451	
   452	// NoGoError is the error used by Import to describe a directory
   453	// containing no buildable Go source files. (It may still contain
   454	// test files, files hidden by build tags, and so on.)
   455	type NoGoError struct {
   456		Dir string
   457	}
   458	
   459	func (e *NoGoError) Error() string {
   460		return "no buildable Go source files in " + e.Dir
   461	}
   462	
   463	// MultiplePackageError describes a directory containing
   464	// multiple buildable Go source files for multiple packages.
   465	type MultiplePackageError struct {
   466		Dir      string   // directory containing files
   467		Packages []string // package names found
   468		Files    []string // corresponding files: Files[i] declares package Packages[i]
   469	}
   470	
   471	func (e *MultiplePackageError) Error() string {
   472		// Error string limited to two entries for compatibility.
   473		return fmt.Sprintf("found packages %s (%s) and %s (%s) in %s", e.Packages[0], e.Files[0], e.Packages[1], e.Files[1], e.Dir)
   474	}
   475	
   476	func nameExt(name string) string {
   477		i := strings.LastIndex(name, ".")
   478		if i < 0 {
   479			return ""
   480		}
   481		return name[i:]
   482	}
   483	
   484	// Import returns details about the Go package named by the import path,
   485	// interpreting local import paths relative to the srcDir directory.
   486	// If the path is a local import path naming a package that can be imported
   487	// using a standard import path, the returned package will set p.ImportPath
   488	// to that path.
   489	//
   490	// In the directory containing the package, .go, .c, .h, and .s files are
   491	// considered part of the package except for:
   492	//
   493	//	- .go files in package documentation
   494	//	- files starting with _ or . (likely editor temporary files)
   495	//	- files with build constraints not satisfied by the context
   496	//
   497	// If an error occurs, Import returns a non-nil error and a non-nil
   498	// *Package containing partial information.
   499	//
   500	func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) {
   501		p := &Package{
   502			ImportPath: path,
   503		}
   504		if path == "" {
   505			return p, fmt.Errorf("import %q: invalid import path", path)
   506		}
   507	
   508		var pkgtargetroot string
   509		var pkga string
   510		var pkgerr error
   511		suffix := ""
   512		if ctxt.InstallSuffix != "" {
   513			suffix = "_" + ctxt.InstallSuffix
   514		}
   515		switch ctxt.Compiler {
   516		case "gccgo":
   517			pkgtargetroot = "pkg/gccgo_" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
   518		case "gc":
   519			pkgtargetroot = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + suffix
   520		default:
   521			// Save error for end of function.
   522			pkgerr = fmt.Errorf("import %q: unknown compiler %q", path, ctxt.Compiler)
   523		}
   524		setPkga := func() {
   525			switch ctxt.Compiler {
   526			case "gccgo":
   527				dir, elem := pathpkg.Split(p.ImportPath)
   528				pkga = pkgtargetroot + "/" + dir + "lib" + elem + ".a"
   529			case "gc":
   530				pkga = pkgtargetroot + "/" + p.ImportPath + ".a"
   531			}
   532		}
   533		setPkga()
   534	
   535		binaryOnly := false
   536		if IsLocalImport(path) {
   537			pkga = "" // local imports have no installed path
   538			if srcDir == "" {
   539				return p, fmt.Errorf("import %q: import relative to unknown directory", path)
   540			}
   541			if !ctxt.isAbsPath(path) {
   542				p.Dir = ctxt.joinPath(srcDir, path)
   543			}
   544			// p.Dir directory may or may not exist. Gather partial information first, check if it exists later.
   545			// Determine canonical import path, if any.
   546			// Exclude results where the import path would include /testdata/.
   547			inTestdata := func(sub string) bool {
   548				return strings.Contains(sub, "/testdata/") || strings.HasSuffix(sub, "/testdata") || strings.HasPrefix(sub, "testdata/") || sub == "testdata"
   549			}
   550			if ctxt.GOROOT != "" {
   551				root := ctxt.joinPath(ctxt.GOROOT, "src")
   552				if sub, ok := ctxt.hasSubdir(root, p.Dir); ok && !inTestdata(sub) {
   553					p.Goroot = true
   554					p.ImportPath = sub
   555					p.Root = ctxt.GOROOT
   556					setPkga() // p.ImportPath changed
   557					goto Found
   558				}
   559			}
   560			all := ctxt.gopath()
   561			for i, root := range all {
   562				rootsrc := ctxt.joinPath(root, "src")
   563				if sub, ok := ctxt.hasSubdir(rootsrc, p.Dir); ok && !inTestdata(sub) {
   564					// We found a potential import path for dir,
   565					// but check that using it wouldn't find something
   566					// else first.
   567					if ctxt.GOROOT != "" && ctxt.Compiler != "gccgo" {
   568						if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) {
   569							p.ConflictDir = dir
   570							goto Found
   571						}
   572					}
   573					for _, earlyRoot := range all[:i] {
   574						if dir := ctxt.joinPath(earlyRoot, "src", sub); ctxt.isDir(dir) {
   575							p.ConflictDir = dir
   576							goto Found
   577						}
   578					}
   579	
   580					// sub would not name some other directory instead of this one.
   581					// Record it.
   582					p.ImportPath = sub
   583					p.Root = root
   584					setPkga() // p.ImportPath changed
   585					goto Found
   586				}
   587			}
   588			// It's okay that we didn't find a root containing dir.
   589			// Keep going with the information we have.
   590		} else {
   591			if strings.HasPrefix(path, "/") {
   592				return p, fmt.Errorf("import %q: cannot import absolute path", path)
   593			}
   594	
   595			gopath := ctxt.gopath() // needed by both importGo and below; avoid computing twice
   596			if err := ctxt.importGo(p, path, srcDir, mode, gopath); err == nil {
   597				goto Found
   598			} else if err != errNoModules {
   599				return p, err
   600			}
   601	
   602			// tried records the location of unsuccessful package lookups
   603			var tried struct {
   604				vendor []string
   605				goroot string
   606				gopath []string
   607			}
   608	
   609			// Vendor directories get first chance to satisfy import.
   610			if mode&IgnoreVendor == 0 && srcDir != "" {
   611				searchVendor := func(root string, isGoroot bool) bool {
   612					sub, ok := ctxt.hasSubdir(root, srcDir)
   613					if !ok || !strings.HasPrefix(sub, "src/") || strings.Contains(sub, "/testdata/") {
   614						return false
   615					}
   616					for {
   617						vendor := ctxt.joinPath(root, sub, "vendor")
   618						if ctxt.isDir(vendor) {
   619							dir := ctxt.joinPath(vendor, path)
   620							if ctxt.isDir(dir) && hasGoFiles(ctxt, dir) {
   621								p.Dir = dir
   622								p.ImportPath = strings.TrimPrefix(pathpkg.Join(sub, "vendor", path), "src/")
   623								p.Goroot = isGoroot
   624								p.Root = root
   625								setPkga() // p.ImportPath changed
   626								return true
   627							}
   628							tried.vendor = append(tried.vendor, dir)
   629						}
   630						i := strings.LastIndex(sub, "/")
   631						if i < 0 {
   632							break
   633						}
   634						sub = sub[:i]
   635					}
   636					return false
   637				}
   638				if ctxt.Compiler != "gccgo" && searchVendor(ctxt.GOROOT, true) {
   639					goto Found
   640				}
   641				for _, root := range gopath {
   642					if searchVendor(root, false) {
   643						goto Found
   644					}
   645				}
   646			}
   647	
   648			// Determine directory from import path.
   649			if ctxt.GOROOT != "" {
   650				// If the package path starts with "vendor/", only search GOROOT before
   651				// GOPATH if the importer is also within GOROOT. That way, if the user has
   652				// vendored in a package that is subsequently included in the standard
   653				// distribution, they'll continue to pick up their own vendored copy.
   654				gorootFirst := srcDir == "" || !strings.HasPrefix(path, "vendor/")
   655				if !gorootFirst {
   656					_, gorootFirst = ctxt.hasSubdir(ctxt.GOROOT, srcDir)
   657				}
   658				if gorootFirst {
   659					dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
   660					if ctxt.Compiler != "gccgo" {
   661						isDir := ctxt.isDir(dir)
   662						binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
   663						if isDir || binaryOnly {
   664							p.Dir = dir
   665							p.Goroot = true
   666							p.Root = ctxt.GOROOT
   667							goto Found
   668						}
   669					}
   670					tried.goroot = dir
   671				}
   672			}
   673			if ctxt.Compiler == "gccgo" && goroot.IsStandardPackage(ctxt.GOROOT, ctxt.Compiler, path) {
   674				p.Dir = ctxt.joinPath(ctxt.GOROOT, "src", path)
   675				p.Goroot = true
   676				p.Root = ctxt.GOROOT
   677				goto Found
   678			}
   679			for _, root := range gopath {
   680				dir := ctxt.joinPath(root, "src", path)
   681				isDir := ctxt.isDir(dir)
   682				binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(root, pkga))
   683				if isDir || binaryOnly {
   684					p.Dir = dir
   685					p.Root = root
   686					goto Found
   687				}
   688				tried.gopath = append(tried.gopath, dir)
   689			}
   690	
   691			// If we tried GOPATH first due to a "vendor/" prefix, fall back to GOPATH.
   692			// That way, the user can still get useful results from 'go list' for
   693			// standard-vendored paths passed on the command line.
   694			if ctxt.GOROOT != "" && tried.goroot == "" {
   695				dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
   696				if ctxt.Compiler != "gccgo" {
   697					isDir := ctxt.isDir(dir)
   698					binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga))
   699					if isDir || binaryOnly {
   700						p.Dir = dir
   701						p.Goroot = true
   702						p.Root = ctxt.GOROOT
   703						goto Found
   704					}
   705				}
   706				tried.goroot = dir
   707			}
   708	
   709			// package was not found
   710			var paths []string
   711			format := "\t%s (vendor tree)"
   712			for _, dir := range tried.vendor {
   713				paths = append(paths, fmt.Sprintf(format, dir))
   714				format = "\t%s"
   715			}
   716			if tried.goroot != "" {
   717				paths = append(paths, fmt.Sprintf("\t%s (from $GOROOT)", tried.goroot))
   718			} else {
   719				paths = append(paths, "\t($GOROOT not set)")
   720			}
   721			format = "\t%s (from $GOPATH)"
   722			for _, dir := range tried.gopath {
   723				paths = append(paths, fmt.Sprintf(format, dir))
   724				format = "\t%s"
   725			}
   726			if len(tried.gopath) == 0 {
   727				paths = append(paths, "\t($GOPATH not set. For more details see: 'go help gopath')")
   728			}
   729			return p, fmt.Errorf("cannot find package %q in any of:\n%s", path, strings.Join(paths, "\n"))
   730		}
   731	
   732	Found:
   733		if p.Root != "" {
   734			p.SrcRoot = ctxt.joinPath(p.Root, "src")
   735			p.PkgRoot = ctxt.joinPath(p.Root, "pkg")
   736			p.BinDir = ctxt.joinPath(p.Root, "bin")
   737			if pkga != "" {
   738				p.PkgTargetRoot = ctxt.joinPath(p.Root, pkgtargetroot)
   739				p.PkgObj = ctxt.joinPath(p.Root, pkga)
   740			}
   741		}
   742	
   743		// If it's a local import path, by the time we get here, we still haven't checked
   744		// that p.Dir directory exists. This is the right time to do that check.
   745		// We can't do it earlier, because we want to gather partial information for the
   746		// non-nil *Package returned when an error occurs.
   747		// We need to do this before we return early on FindOnly flag.
   748		if IsLocalImport(path) && !ctxt.isDir(p.Dir) {
   749			if ctxt.Compiler == "gccgo" && p.Goroot {
   750				// gccgo has no sources for GOROOT packages.
   751				return p, nil
   752			}
   753	
   754			// package was not found
   755			return p, fmt.Errorf("cannot find package %q in:\n\t%s", path, p.Dir)
   756		}
   757	
   758		if mode&FindOnly != 0 {
   759			return p, pkgerr
   760		}
   761		if binaryOnly && (mode&AllowBinary) != 0 {
   762			return p, pkgerr
   763		}
   764	
   765		if ctxt.Compiler == "gccgo" && p.Goroot {
   766			// gccgo has no sources for GOROOT packages.
   767			return p, nil
   768		}
   769	
   770		dirs, err := ctxt.readDir(p.Dir)
   771		if err != nil {
   772			return p, err
   773		}
   774	
   775		var badGoError error
   776		var Sfiles []string // files with ".S" (capital S)
   777		var firstFile, firstCommentFile string
   778		imported := make(map[string][]token.Position)
   779		testImported := make(map[string][]token.Position)
   780		xTestImported := make(map[string][]token.Position)
   781		allTags := make(map[string]bool)
   782		fset := token.NewFileSet()
   783		for _, d := range dirs {
   784			if d.IsDir() {
   785				continue
   786			}
   787	
   788			name := d.Name()
   789			ext := nameExt(name)
   790	
   791			badFile := func(err error) {
   792				if badGoError == nil {
   793					badGoError = err
   794				}
   795				p.InvalidGoFiles = append(p.InvalidGoFiles, name)
   796			}
   797	
   798			match, data, filename, err := ctxt.matchFile(p.Dir, name, allTags, &p.BinaryOnly)
   799			if err != nil {
   800				badFile(err)
   801				continue
   802			}
   803			if !match {
   804				if ext == ".go" {
   805					p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
   806				}
   807				continue
   808			}
   809	
   810			// Going to save the file. For non-Go files, can stop here.
   811			switch ext {
   812			case ".c":
   813				p.CFiles = append(p.CFiles, name)
   814				continue
   815			case ".cc", ".cpp", ".cxx":
   816				p.CXXFiles = append(p.CXXFiles, name)
   817				continue
   818			case ".m":
   819				p.MFiles = append(p.MFiles, name)
   820				continue
   821			case ".h", ".hh", ".hpp", ".hxx":
   822				p.HFiles = append(p.HFiles, name)
   823				continue
   824			case ".f", ".F", ".for", ".f90":
   825				p.FFiles = append(p.FFiles, name)
   826				continue
   827			case ".s":
   828				p.SFiles = append(p.SFiles, name)
   829				continue
   830			case ".S":
   831				Sfiles = append(Sfiles, name)
   832				continue
   833			case ".swig":
   834				p.SwigFiles = append(p.SwigFiles, name)
   835				continue
   836			case ".swigcxx":
   837				p.SwigCXXFiles = append(p.SwigCXXFiles, name)
   838				continue
   839			case ".syso":
   840				// binary objects to add to package archive
   841				// Likely of the form foo_windows.syso, but
   842				// the name was vetted above with goodOSArchFile.
   843				p.SysoFiles = append(p.SysoFiles, name)
   844				continue
   845			}
   846	
   847			pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
   848			if err != nil {
   849				badFile(err)
   850				continue
   851			}
   852	
   853			pkg := pf.Name.Name
   854			if pkg == "documentation" {
   855				p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
   856				continue
   857			}
   858	
   859			isTest := strings.HasSuffix(name, "_test.go")
   860			isXTest := false
   861			if isTest && strings.HasSuffix(pkg, "_test") {
   862				isXTest = true
   863				pkg = pkg[:len(pkg)-len("_test")]
   864			}
   865	
   866			if p.Name == "" {
   867				p.Name = pkg
   868				firstFile = name
   869			} else if pkg != p.Name {
   870				badFile(&MultiplePackageError{
   871					Dir:      p.Dir,
   872					Packages: []string{p.Name, pkg},
   873					Files:    []string{firstFile, name},
   874				})
   875				p.InvalidGoFiles = append(p.InvalidGoFiles, name)
   876			}
   877			// Grab the first package comment as docs, provided it is not from a test file.
   878			if pf.Doc != nil && p.Doc == "" && !isTest && !isXTest {
   879				p.Doc = doc.Synopsis(pf.Doc.Text())
   880			}
   881	
   882			if mode&ImportComment != 0 {
   883				qcom, line := findImportComment(data)
   884				if line != 0 {
   885					com, err := strconv.Unquote(qcom)
   886					if err != nil {
   887						badFile(fmt.Errorf("%s:%d: cannot parse import comment", filename, line))
   888					} else if p.ImportComment == "" {
   889						p.ImportComment = com
   890						firstCommentFile = name
   891					} else if p.ImportComment != com {
   892						badFile(fmt.Errorf("found import comments %q (%s) and %q (%s) in %s", p.ImportComment, firstCommentFile, com, name, p.Dir))
   893					}
   894				}
   895			}
   896	
   897			// Record imports and information about cgo.
   898			isCgo := false
   899			for _, decl := range pf.Decls {
   900				d, ok := decl.(*ast.GenDecl)
   901				if !ok {
   902					continue
   903				}
   904				for _, dspec := range d.Specs {
   905					spec, ok := dspec.(*ast.ImportSpec)
   906					if !ok {
   907						continue
   908					}
   909					quoted := spec.Path.Value
   910					path, err := strconv.Unquote(quoted)
   911					if err != nil {
   912						log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted)
   913					}
   914					if isXTest {
   915						xTestImported[path] = append(xTestImported[path], fset.Position(spec.Pos()))
   916					} else if isTest {
   917						testImported[path] = append(testImported[path], fset.Position(spec.Pos()))
   918					} else {
   919						imported[path] = append(imported[path], fset.Position(spec.Pos()))
   920					}
   921					if path == "C" {
   922						if isTest {
   923							badFile(fmt.Errorf("use of cgo in test %s not supported", filename))
   924						} else {
   925							cg := spec.Doc
   926							if cg == nil && len(d.Specs) == 1 {
   927								cg = d.Doc
   928							}
   929							if cg != nil {
   930								if err := ctxt.saveCgo(filename, p, cg); err != nil {
   931									badFile(err)
   932								}
   933							}
   934							isCgo = true
   935						}
   936					}
   937				}
   938			}
   939			if isCgo {
   940				allTags["cgo"] = true
   941				if ctxt.CgoEnabled {
   942					p.CgoFiles = append(p.CgoFiles, name)
   943				} else {
   944					p.IgnoredGoFiles = append(p.IgnoredGoFiles, name)
   945				}
   946			} else if isXTest {
   947				p.XTestGoFiles = append(p.XTestGoFiles, name)
   948			} else if isTest {
   949				p.TestGoFiles = append(p.TestGoFiles, name)
   950			} else {
   951				p.GoFiles = append(p.GoFiles, name)
   952			}
   953		}
   954		if badGoError != nil {
   955			return p, badGoError
   956		}
   957		if len(p.GoFiles)+len(p.CgoFiles)+len(p.TestGoFiles)+len(p.XTestGoFiles) == 0 {
   958			return p, &NoGoError{p.Dir}
   959		}
   960	
   961		for tag := range allTags {
   962			p.AllTags = append(p.AllTags, tag)
   963		}
   964		sort.Strings(p.AllTags)
   965	
   966		p.Imports, p.ImportPos = cleanImports(imported)
   967		p.TestImports, p.TestImportPos = cleanImports(testImported)
   968		p.XTestImports, p.XTestImportPos = cleanImports(xTestImported)
   969	
   970		// add the .S files only if we are using cgo
   971		// (which means gcc will compile them).
   972		// The standard assemblers expect .s files.
   973		if len(p.CgoFiles) > 0 {
   974			p.SFiles = append(p.SFiles, Sfiles...)
   975			sort.Strings(p.SFiles)
   976		}
   977	
   978		return p, pkgerr
   979	}
   980	
   981	var errNoModules = errors.New("not using modules")
   982	
   983	// importGo checks whether it can use the go command to find the directory for path.
   984	// If using the go command is not appopriate, importGo returns errNoModules.
   985	// Otherwise, importGo tries using the go command and reports whether that succeeded.
   986	// Using the go command lets build.Import and build.Context.Import find code
   987	// in Go modules. In the long term we want tools to use go/packages (currently golang.org/x/tools/go/packages),
   988	// which will also use the go command.
   989	// Invoking the go command here is not very efficient in that it computes information
   990	// about the requested package and all dependencies and then only reports about the requested package.
   991	// Then we reinvoke it for every dependency. But this is still better than not working at all.
   992	// See golang.org/issue/26504.
   993	func (ctxt *Context) importGo(p *Package, path, srcDir string, mode ImportMode, gopath []string) error {
   994		const debugImportGo = false
   995	
   996		// To invoke the go command, we must know the source directory,
   997		// we must not being doing special things like AllowBinary or IgnoreVendor,
   998		// and all the file system callbacks must be nil (we're meant to use the local file system).
   999		if srcDir == "" || mode&AllowBinary != 0 || mode&IgnoreVendor != 0 ||
  1000			ctxt.JoinPath != nil || ctxt.SplitPathList != nil || ctxt.IsAbsPath != nil || ctxt.IsDir != nil || ctxt.HasSubdir != nil || ctxt.ReadDir != nil || ctxt.OpenFile != nil || !equal(ctxt.ReleaseTags, defaultReleaseTags) {
  1001			return errNoModules
  1002		}
  1003	
  1004		// Find the absolute source directory. hasSubdir does not handle
  1005		// relative paths (and can't because the callbacks don't support this).
  1006		absSrcDir, err := filepath.Abs(srcDir)
  1007		if err != nil {
  1008			return errNoModules
  1009		}
  1010	
  1011		// If modules are not enabled, then the in-process code works fine and we should keep using it.
  1012		switch os.Getenv("GO111MODULE") {
  1013		case "off":
  1014			return errNoModules
  1015		default: // "", "on", "auto", anything else
  1016			// Maybe use modules.
  1017		}
  1018	
  1019		// If the source directory is in GOROOT, then the in-process code works fine
  1020		// and we should keep using it. Moreover, the 'go list' approach below doesn't
  1021		// take standard-library vendoring into account and will fail.
  1022		if _, ok := ctxt.hasSubdir(filepath.Join(ctxt.GOROOT, "src"), absSrcDir); ok {
  1023			return errNoModules
  1024		}
  1025	
  1026		// For efficiency, if path is a standard library package, let the usual lookup code handle it.
  1027		if ctxt.GOROOT != "" {
  1028			dir := ctxt.joinPath(ctxt.GOROOT, "src", path)
  1029			if ctxt.isDir(dir) {
  1030				return errNoModules
  1031			}
  1032		}
  1033	
  1034		// Look to see if there is a go.mod.
  1035		// Since go1.13, it doesn't matter if we're inside GOPATH.
  1036		parent := absSrcDir
  1037		for {
  1038			info, err := os.Stat(filepath.Join(parent, "go.mod"))
  1039			if err == nil && !info.IsDir() {
  1040				break
  1041			}
  1042			d := filepath.Dir(parent)
  1043			if len(d) >= len(parent) {
  1044				return errNoModules // reached top of file system, no go.mod
  1045			}
  1046			parent = d
  1047		}
  1048	
  1049		cmd := exec.Command("go", "list", "-compiler="+ctxt.Compiler, "-tags="+strings.Join(ctxt.BuildTags, ","), "-installsuffix="+ctxt.InstallSuffix, "-f={{.Dir}}\n{{.ImportPath}}\n{{.Root}}\n{{.Goroot}}\n", path)
  1050	
  1051		// TODO(bcmills): This is wrong if srcDir is in a vendor directory, or if
  1052		// srcDir is in some module dependency of the main module. The main module
  1053		// chooses what the import paths mean: individual packages don't.
  1054		cmd.Dir = srcDir
  1055	
  1056		var stdout, stderr strings.Builder
  1057		cmd.Stdout = &stdout
  1058		cmd.Stderr = &stderr
  1059	
  1060		cgo := "0"
  1061		if ctxt.CgoEnabled {
  1062			cgo = "1"
  1063		}
  1064		cmd.Env = append(os.Environ(),
  1065			"GOOS="+ctxt.GOOS,
  1066			"GOARCH="+ctxt.GOARCH,
  1067			"GOROOT="+ctxt.GOROOT,
  1068			"GOPATH="+ctxt.GOPATH,
  1069			"CGO_ENABLED="+cgo,
  1070		)
  1071	
  1072		if err := cmd.Run(); err != nil {
  1073			return fmt.Errorf("go/build: importGo %s: %v\n%s\n", path, err, stderr.String())
  1074		}
  1075	
  1076		f := strings.Split(stdout.String(), "\n")
  1077		if len(f) != 5 || f[4] != "" {
  1078			return fmt.Errorf("go/build: importGo %s: unexpected output:\n%s\n", path, stdout.String())
  1079		}
  1080	
  1081		p.Dir = f[0]
  1082		p.ImportPath = f[1]
  1083		p.Root = f[2]
  1084		p.Goroot = f[3] == "true"
  1085		return nil
  1086	}
  1087	
  1088	func equal(x, y []string) bool {
  1089		if len(x) != len(y) {
  1090			return false
  1091		}
  1092		for i, xi := range x {
  1093			if xi != y[i] {
  1094				return false
  1095			}
  1096		}
  1097		return true
  1098	}
  1099	
  1100	// hasGoFiles reports whether dir contains any files with names ending in .go.
  1101	// For a vendor check we must exclude directories that contain no .go files.
  1102	// Otherwise it is not possible to vendor just a/b/c and still import the
  1103	// non-vendored a/b. See golang.org/issue/13832.
  1104	func hasGoFiles(ctxt *Context, dir string) bool {
  1105		ents, _ := ctxt.readDir(dir)
  1106		for _, ent := range ents {
  1107			if !ent.IsDir() && strings.HasSuffix(ent.Name(), ".go") {
  1108				return true
  1109			}
  1110		}
  1111		return false
  1112	}
  1113	
  1114	func findImportComment(data []byte) (s string, line int) {
  1115		// expect keyword package
  1116		word, data := parseWord(data)
  1117		if string(word) != "package" {
  1118			return "", 0
  1119		}
  1120	
  1121		// expect package name
  1122		_, data = parseWord(data)
  1123	
  1124		// now ready for import comment, a // or /* */ comment
  1125		// beginning and ending on the current line.
  1126		for len(data) > 0 && (data[0] == ' ' || data[0] == '\t' || data[0] == '\r') {
  1127			data = data[1:]
  1128		}
  1129	
  1130		var comment []byte
  1131		switch {
  1132		case bytes.HasPrefix(data, slashSlash):
  1133			i := bytes.Index(data, newline)
  1134			if i < 0 {
  1135				i = len(data)
  1136			}
  1137			comment = data[2:i]
  1138		case bytes.HasPrefix(data, slashStar):
  1139			data = data[2:]
  1140			i := bytes.Index(data, starSlash)
  1141			if i < 0 {
  1142				// malformed comment
  1143				return "", 0
  1144			}
  1145			comment = data[:i]
  1146			if bytes.Contains(comment, newline) {
  1147				return "", 0
  1148			}
  1149		}
  1150		comment = bytes.TrimSpace(comment)
  1151	
  1152		// split comment into `import`, `"pkg"`
  1153		word, arg := parseWord(comment)
  1154		if string(word) != "import" {
  1155			return "", 0
  1156		}
  1157	
  1158		line = 1 + bytes.Count(data[:cap(data)-cap(arg)], newline)
  1159		return strings.TrimSpace(string(arg)), line
  1160	}
  1161	
  1162	var (
  1163		slashSlash = []byte("//")
  1164		slashStar  = []byte("/*")
  1165		starSlash  = []byte("*/")
  1166		newline    = []byte("\n")
  1167	)
  1168	
  1169	// skipSpaceOrComment returns data with any leading spaces or comments removed.
  1170	func skipSpaceOrComment(data []byte) []byte {
  1171		for len(data) > 0 {
  1172			switch data[0] {
  1173			case ' ', '\t', '\r', '\n':
  1174				data = data[1:]
  1175				continue
  1176			case '/':
  1177				if bytes.HasPrefix(data, slashSlash) {
  1178					i := bytes.Index(data, newline)
  1179					if i < 0 {
  1180						return nil
  1181					}
  1182					data = data[i+1:]
  1183					continue
  1184				}
  1185				if bytes.HasPrefix(data, slashStar) {
  1186					data = data[2:]
  1187					i := bytes.Index(data, starSlash)
  1188					if i < 0 {
  1189						return nil
  1190					}
  1191					data = data[i+2:]
  1192					continue
  1193				}
  1194			}
  1195			break
  1196		}
  1197		return data
  1198	}
  1199	
  1200	// parseWord skips any leading spaces or comments in data
  1201	// and then parses the beginning of data as an identifier or keyword,
  1202	// returning that word and what remains after the word.
  1203	func parseWord(data []byte) (word, rest []byte) {
  1204		data = skipSpaceOrComment(data)
  1205	
  1206		// Parse past leading word characters.
  1207		rest = data
  1208		for {
  1209			r, size := utf8.DecodeRune(rest)
  1210			if unicode.IsLetter(r) || '0' <= r && r <= '9' || r == '_' {
  1211				rest = rest[size:]
  1212				continue
  1213			}
  1214			break
  1215		}
  1216	
  1217		word = data[:len(data)-len(rest)]
  1218		if len(word) == 0 {
  1219			return nil, nil
  1220		}
  1221	
  1222		return word, rest
  1223	}
  1224	
  1225	// MatchFile reports whether the file with the given name in the given directory
  1226	// matches the context and would be included in a Package created by ImportDir
  1227	// of that directory.
  1228	//
  1229	// MatchFile considers the name of the file and may use ctxt.OpenFile to
  1230	// read some or all of the file's content.
  1231	func (ctxt *Context) MatchFile(dir, name string) (match bool, err error) {
  1232		match, _, _, err = ctxt.matchFile(dir, name, nil, nil)
  1233		return
  1234	}
  1235	
  1236	// matchFile determines whether the file with the given name in the given directory
  1237	// should be included in the package being constructed.
  1238	// It returns the data read from the file.
  1239	// If name denotes a Go program, matchFile reads until the end of the
  1240	// imports (and returns that data) even though it only considers text
  1241	// until the first non-comment.
  1242	// If allTags is non-nil, matchFile records any encountered build tag
  1243	// by setting allTags[tag] = true.
  1244	func (ctxt *Context) matchFile(dir, name string, allTags map[string]bool, binaryOnly *bool) (match bool, data []byte, filename string, err error) {
  1245		if strings.HasPrefix(name, "_") ||
  1246			strings.HasPrefix(name, ".") {
  1247			return
  1248		}
  1249	
  1250		i := strings.LastIndex(name, ".")
  1251		if i < 0 {
  1252			i = len(name)
  1253		}
  1254		ext := name[i:]
  1255	
  1256		if !ctxt.goodOSArchFile(name, allTags) && !ctxt.UseAllFiles {
  1257			return
  1258		}
  1259	
  1260		switch ext {
  1261		case ".go", ".c", ".cc", ".cxx", ".cpp", ".m", ".s", ".h", ".hh", ".hpp", ".hxx", ".f", ".F", ".f90", ".S", ".swig", ".swigcxx":
  1262			// tentatively okay - read to make sure
  1263		case ".syso":
  1264			// binary, no reading
  1265			match = true
  1266			return
  1267		default:
  1268			// skip
  1269			return
  1270		}
  1271	
  1272		filename = ctxt.joinPath(dir, name)
  1273		f, err := ctxt.openFile(filename)
  1274		if err != nil {
  1275			return
  1276		}
  1277	
  1278		if strings.HasSuffix(filename, ".go") {
  1279			data, err = readImports(f, false, nil)
  1280			if strings.HasSuffix(filename, "_test.go") {
  1281				binaryOnly = nil // ignore //go:binary-only-package comments in _test.go files
  1282			}
  1283		} else {
  1284			binaryOnly = nil // ignore //go:binary-only-package comments in non-Go sources
  1285			data, err = readComments(f)
  1286		}
  1287		f.Close()
  1288		if err != nil {
  1289			err = fmt.Errorf("read %s: %v", filename, err)
  1290			return
  1291		}
  1292	
  1293		// Look for +build comments to accept or reject the file.
  1294		var sawBinaryOnly bool
  1295		if !ctxt.shouldBuild(data, allTags, &sawBinaryOnly) && !ctxt.UseAllFiles {
  1296			return
  1297		}
  1298	
  1299		if binaryOnly != nil && sawBinaryOnly {
  1300			*binaryOnly = true
  1301		}
  1302		match = true
  1303		return
  1304	}
  1305	
  1306	func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) {
  1307		all := make([]string, 0, len(m))
  1308		for path := range m {
  1309			all = append(all, path)
  1310		}
  1311		sort.Strings(all)
  1312		return all, m
  1313	}
  1314	
  1315	// Import is shorthand for Default.Import.
  1316	func Import(path, srcDir string, mode ImportMode) (*Package, error) {
  1317		return Default.Import(path, srcDir, mode)
  1318	}
  1319	
  1320	// ImportDir is shorthand for Default.ImportDir.
  1321	func ImportDir(dir string, mode ImportMode) (*Package, error) {
  1322		return Default.ImportDir(dir, mode)
  1323	}
  1324	
  1325	var slashslash = []byte("//")
  1326	
  1327	// Special comment denoting a binary-only package.
  1328	// See https://golang.org/design/2775-binary-only-packages
  1329	// for more about the design of binary-only packages.
  1330	var binaryOnlyComment = []byte("//go:binary-only-package")
  1331	
  1332	// shouldBuild reports whether it is okay to use this file,
  1333	// The rule is that in the file's leading run of // comments
  1334	// and blank lines, which must be followed by a blank line
  1335	// (to avoid including a Go package clause doc comment),
  1336	// lines beginning with '// +build' are taken as build directives.
  1337	//
  1338	// The file is accepted only if each such line lists something
  1339	// matching the file. For example:
  1340	//
  1341	//	// +build windows linux
  1342	//
  1343	// marks the file as applicable only on Windows and Linux.
  1344	//
  1345	// If shouldBuild finds a //go:binary-only-package comment in the file,
  1346	// it sets *binaryOnly to true. Otherwise it does not change *binaryOnly.
  1347	//
  1348	func (ctxt *Context) shouldBuild(content []byte, allTags map[string]bool, binaryOnly *bool) bool {
  1349		sawBinaryOnly := false
  1350	
  1351		// Pass 1. Identify leading run of // comments and blank lines,
  1352		// which must be followed by a blank line.
  1353		end := 0
  1354		p := content
  1355		for len(p) > 0 {
  1356			line := p
  1357			if i := bytes.IndexByte(line, '\n'); i >= 0 {
  1358				line, p = line[:i], p[i+1:]
  1359			} else {
  1360				p = p[len(p):]
  1361			}
  1362			line = bytes.TrimSpace(line)
  1363			if len(line) == 0 { // Blank line
  1364				end = len(content) - len(p)
  1365				continue
  1366			}
  1367			if !bytes.HasPrefix(line, slashslash) { // Not comment line
  1368				break
  1369			}
  1370		}
  1371		content = content[:end]
  1372	
  1373		// Pass 2.  Process each line in the run.
  1374		p = content
  1375		allok := true
  1376		for len(p) > 0 {
  1377			line := p
  1378			if i := bytes.IndexByte(line, '\n'); i >= 0 {
  1379				line, p = line[:i], p[i+1:]
  1380			} else {
  1381				p = p[len(p):]
  1382			}
  1383			line = bytes.TrimSpace(line)
  1384			if !bytes.HasPrefix(line, slashslash) {
  1385				continue
  1386			}
  1387			if bytes.Equal(line, binaryOnlyComment) {
  1388				sawBinaryOnly = true
  1389			}
  1390			line = bytes.TrimSpace(line[len(slashslash):])
  1391			if len(line) > 0 && line[0] == '+' {
  1392				// Looks like a comment +line.
  1393				f := strings.Fields(string(line))
  1394				if f[0] == "+build" {
  1395					ok := false
  1396					for _, tok := range f[1:] {
  1397						if ctxt.match(tok, allTags) {
  1398							ok = true
  1399						}
  1400					}
  1401					if !ok {
  1402						allok = false
  1403					}
  1404				}
  1405			}
  1406		}
  1407	
  1408		if binaryOnly != nil && sawBinaryOnly {
  1409			*binaryOnly = true
  1410		}
  1411	
  1412		return allok
  1413	}
  1414	
  1415	// saveCgo saves the information from the #cgo lines in the import "C" comment.
  1416	// These lines set CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS and pkg-config directives
  1417	// that affect the way cgo's C code is built.
  1418	func (ctxt *Context) saveCgo(filename string, di *Package, cg *ast.CommentGroup) error {
  1419		text := cg.Text()
  1420		for _, line := range strings.Split(text, "\n") {
  1421			orig := line
  1422	
  1423			// Line is
  1424			//	#cgo [GOOS/GOARCH...] LDFLAGS: stuff
  1425			//
  1426			line = strings.TrimSpace(line)
  1427			if len(line) < 5 || line[:4] != "#cgo" || (line[4] != ' ' && line[4] != '\t') {
  1428				continue
  1429			}
  1430	
  1431			// Split at colon.
  1432			line = strings.TrimSpace(line[4:])
  1433			i := strings.Index(line, ":")
  1434			if i < 0 {
  1435				return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
  1436			}
  1437			line, argstr := line[:i], line[i+1:]
  1438	
  1439			// Parse GOOS/GOARCH stuff.
  1440			f := strings.Fields(line)
  1441			if len(f) < 1 {
  1442				return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
  1443			}
  1444	
  1445			cond, verb := f[:len(f)-1], f[len(f)-1]
  1446			if len(cond) > 0 {
  1447				ok := false
  1448				for _, c := range cond {
  1449					if ctxt.match(c, nil) {
  1450						ok = true
  1451						break
  1452					}
  1453				}
  1454				if !ok {
  1455					continue
  1456				}
  1457			}
  1458	
  1459			args, err := splitQuoted(argstr)
  1460			if err != nil {
  1461				return fmt.Errorf("%s: invalid #cgo line: %s", filename, orig)
  1462			}
  1463			var ok bool
  1464			for i, arg := range args {
  1465				if arg, ok = expandSrcDir(arg, di.Dir); !ok {
  1466					return fmt.Errorf("%s: malformed #cgo argument: %s", filename, arg)
  1467				}
  1468				args[i] = arg
  1469			}
  1470	
  1471			switch verb {
  1472			case "CFLAGS", "CPPFLAGS", "CXXFLAGS", "FFLAGS", "LDFLAGS":
  1473				// Change relative paths to absolute.
  1474				ctxt.makePathsAbsolute(args, di.Dir)
  1475			}
  1476	
  1477			switch verb {
  1478			case "CFLAGS":
  1479				di.CgoCFLAGS = append(di.CgoCFLAGS, args...)
  1480			case "CPPFLAGS":
  1481				di.CgoCPPFLAGS = append(di.CgoCPPFLAGS, args...)
  1482			case "CXXFLAGS":
  1483				di.CgoCXXFLAGS = append(di.CgoCXXFLAGS, args...)
  1484			case "FFLAGS":
  1485				di.CgoFFLAGS = append(di.CgoFFLAGS, args...)
  1486			case "LDFLAGS":
  1487				di.CgoLDFLAGS = append(di.CgoLDFLAGS, args...)
  1488			case "pkg-config":
  1489				di.CgoPkgConfig = append(di.CgoPkgConfig, args...)
  1490			default:
  1491				return fmt.Errorf("%s: invalid #cgo verb: %s", filename, orig)
  1492			}
  1493		}
  1494		return nil
  1495	}
  1496	
  1497	// expandSrcDir expands any occurrence of ${SRCDIR}, making sure
  1498	// the result is safe for the shell.
  1499	func expandSrcDir(str string, srcdir string) (string, bool) {
  1500		// "\" delimited paths cause safeCgoName to fail
  1501		// so convert native paths with a different delimiter
  1502		// to "/" before starting (eg: on windows).
  1503		srcdir = filepath.ToSlash(srcdir)
  1504	
  1505		chunks := strings.Split(str, "${SRCDIR}")
  1506		if len(chunks) < 2 {
  1507			return str, safeCgoName(str)
  1508		}
  1509		ok := true
  1510		for _, chunk := range chunks {
  1511			ok = ok && (chunk == "" || safeCgoName(chunk))
  1512		}
  1513		ok = ok && (srcdir == "" || safeCgoName(srcdir))
  1514		res := strings.Join(chunks, srcdir)
  1515		return res, ok && res != ""
  1516	}
  1517	
  1518	// makePathsAbsolute looks for compiler options that take paths and
  1519	// makes them absolute. We do this because through the 1.8 release we
  1520	// ran the compiler in the package directory, so any relative -I or -L
  1521	// options would be relative to that directory. In 1.9 we changed to
  1522	// running the compiler in the build directory, to get consistent
  1523	// build results (issue #19964). To keep builds working, we change any
  1524	// relative -I or -L options to be absolute.
  1525	//
  1526	// Using filepath.IsAbs and filepath.Join here means the results will be
  1527	// different on different systems, but that's OK: -I and -L options are
  1528	// inherently system-dependent.
  1529	func (ctxt *Context) makePathsAbsolute(args []string, srcDir string) {
  1530		nextPath := false
  1531		for i, arg := range args {
  1532			if nextPath {
  1533				if !filepath.IsAbs(arg) {
  1534					args[i] = filepath.Join(srcDir, arg)
  1535				}
  1536				nextPath = false
  1537			} else if strings.HasPrefix(arg, "-I") || strings.HasPrefix(arg, "-L") {
  1538				if len(arg) == 2 {
  1539					nextPath = true
  1540				} else {
  1541					if !filepath.IsAbs(arg[2:]) {
  1542						args[i] = arg[:2] + filepath.Join(srcDir, arg[2:])
  1543					}
  1544				}
  1545			}
  1546		}
  1547	}
  1548	
  1549	// NOTE: $ is not safe for the shell, but it is allowed here because of linker options like -Wl,$ORIGIN.
  1550	// We never pass these arguments to a shell (just to programs we construct argv for), so this should be okay.
  1551	// See golang.org/issue/6038.
  1552	// The @ is for OS X. See golang.org/issue/13720.
  1553	// The % is for Jenkins. See golang.org/issue/16959.
  1554	// The ! is because module paths may use them. See golang.org/issue/26716.
  1555	const safeString = "+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$@%! "
  1556	
  1557	func safeCgoName(s string) bool {
  1558		if s == "" {
  1559			return false
  1560		}
  1561		for i := 0; i < len(s); i++ {
  1562			if c := s[i]; c < utf8.RuneSelf && strings.IndexByte(safeString, c) < 0 {
  1563				return false
  1564			}
  1565		}
  1566		return true
  1567	}
  1568	
  1569	// splitQuoted splits the string s around each instance of one or more consecutive
  1570	// white space characters while taking into account quotes and escaping, and
  1571	// returns an array of substrings of s or an empty list if s contains only white space.
  1572	// Single quotes and double quotes are recognized to prevent splitting within the
  1573	// quoted region, and are removed from the resulting substrings. If a quote in s
  1574	// isn't closed err will be set and r will have the unclosed argument as the
  1575	// last element. The backslash is used for escaping.
  1576	//
  1577	// For example, the following string:
  1578	//
  1579	//     a b:"c d" 'e''f'  "g\""
  1580	//
  1581	// Would be parsed as:
  1582	//
  1583	//     []string{"a", "b:c d", "ef", `g"`}
  1584	//
  1585	func splitQuoted(s string) (r []string, err error) {
  1586		var args []string
  1587		arg := make([]rune, len(s))
  1588		escaped := false
  1589		quoted := false
  1590		quote := '\x00'
  1591		i := 0
  1592		for _, rune := range s {
  1593			switch {
  1594			case escaped:
  1595				escaped = false
  1596			case rune == '\\':
  1597				escaped = true
  1598				continue
  1599			case quote != '\x00':
  1600				if rune == quote {
  1601					quote = '\x00'
  1602					continue
  1603				}
  1604			case rune == '"' || rune == '\'':
  1605				quoted = true
  1606				quote = rune
  1607				continue
  1608			case unicode.IsSpace(rune):
  1609				if quoted || i > 0 {
  1610					quoted = false
  1611					args = append(args, string(arg[:i]))
  1612					i = 0
  1613				}
  1614				continue
  1615			}
  1616			arg[i] = rune
  1617			i++
  1618		}
  1619		if quoted || i > 0 {
  1620			args = append(args, string(arg[:i]))
  1621		}
  1622		if quote != 0 {
  1623			err = errors.New("unclosed quote")
  1624		} else if escaped {
  1625			err = errors.New("unfinished escaping")
  1626		}
  1627		return args, err
  1628	}
  1629	
  1630	// match reports whether the name is one of:
  1631	//
  1632	//	$GOOS
  1633	//	$GOARCH
  1634	//	cgo (if cgo is enabled)
  1635	//	!cgo (if cgo is disabled)
  1636	//	ctxt.Compiler
  1637	//	!ctxt.Compiler
  1638	//	tag (if tag is listed in ctxt.BuildTags or ctxt.ReleaseTags)
  1639	//	!tag (if tag is not listed in ctxt.BuildTags or ctxt.ReleaseTags)
  1640	//	a comma-separated list of any of these
  1641	//
  1642	func (ctxt *Context) match(name string, allTags map[string]bool) bool {
  1643		if name == "" {
  1644			if allTags != nil {
  1645				allTags[name] = true
  1646			}
  1647			return false
  1648		}
  1649		if i := strings.Index(name, ","); i >= 0 {
  1650			// comma-separated list
  1651			ok1 := ctxt.match(name[:i], allTags)
  1652			ok2 := ctxt.match(name[i+1:], allTags)
  1653			return ok1 && ok2
  1654		}
  1655		if strings.HasPrefix(name, "!!") { // bad syntax, reject always
  1656			return false
  1657		}
  1658		if strings.HasPrefix(name, "!") { // negation
  1659			return len(name) > 1 && !ctxt.match(name[1:], allTags)
  1660		}
  1661	
  1662		if allTags != nil {
  1663			allTags[name] = true
  1664		}
  1665	
  1666		// Tags must be letters, digits, underscores or dots.
  1667		// Unlike in Go identifiers, all digits are fine (e.g., "386").
  1668		for _, c := range name {
  1669			if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
  1670				return false
  1671			}
  1672		}
  1673	
  1674		// special tags
  1675		if ctxt.CgoEnabled && name == "cgo" {
  1676			return true
  1677		}
  1678		if name == ctxt.GOOS || name == ctxt.GOARCH || name == ctxt.Compiler {
  1679			return true
  1680		}
  1681		if ctxt.GOOS == "android" && name == "linux" {
  1682			return true
  1683		}
  1684		if ctxt.GOOS == "illumos" && name == "solaris" {
  1685			return true
  1686		}
  1687	
  1688		// other tags
  1689		for _, tag := range ctxt.BuildTags {
  1690			if tag == name {
  1691				return true
  1692			}
  1693		}
  1694		for _, tag := range ctxt.ReleaseTags {
  1695			if tag == name {
  1696				return true
  1697			}
  1698		}
  1699	
  1700		return false
  1701	}
  1702	
  1703	// goodOSArchFile returns false if the name contains a $GOOS or $GOARCH
  1704	// suffix which does not match the current system.
  1705	// The recognized name formats are:
  1706	//
  1707	//     name_$(GOOS).*
  1708	//     name_$(GOARCH).*
  1709	//     name_$(GOOS)_$(GOARCH).*
  1710	//     name_$(GOOS)_test.*
  1711	//     name_$(GOARCH)_test.*
  1712	//     name_$(GOOS)_$(GOARCH)_test.*
  1713	//
  1714	// An exception: if GOOS=android, then files with GOOS=linux are also matched.
  1715	func (ctxt *Context) goodOSArchFile(name string, allTags map[string]bool) bool {
  1716		if dot := strings.Index(name, "."); dot != -1 {
  1717			name = name[:dot]
  1718		}
  1719	
  1720		// Before Go 1.4, a file called "linux.go" would be equivalent to having a
  1721		// build tag "linux" in that file. For Go 1.4 and beyond, we require this
  1722		// auto-tagging to apply only to files with a non-empty prefix, so
  1723		// "foo_linux.go" is tagged but "linux.go" is not. This allows new operating
  1724		// systems, such as android, to arrive without breaking existing code with
  1725		// innocuous source code in "android.go". The easiest fix: cut everything
  1726		// in the name before the initial _.
  1727		i := strings.Index(name, "_")
  1728		if i < 0 {
  1729			return true
  1730		}
  1731		name = name[i:] // ignore everything before first _
  1732	
  1733		l := strings.Split(name, "_")
  1734		if n := len(l); n > 0 && l[n-1] == "test" {
  1735			l = l[:n-1]
  1736		}
  1737		n := len(l)
  1738		if n >= 2 && knownOS[l[n-2]] && knownArch[l[n-1]] {
  1739			return ctxt.match(l[n-1], allTags) && ctxt.match(l[n-2], allTags)
  1740		}
  1741		if n >= 1 && (knownOS[l[n-1]] || knownArch[l[n-1]]) {
  1742			return ctxt.match(l[n-1], allTags)
  1743		}
  1744		return true
  1745	}
  1746	
  1747	var knownOS = make(map[string]bool)
  1748	var knownArch = make(map[string]bool)
  1749	
  1750	func init() {
  1751		for _, v := range strings.Fields(goosList) {
  1752			knownOS[v] = true
  1753		}
  1754		for _, v := range strings.Fields(goarchList) {
  1755			knownArch[v] = true
  1756		}
  1757	}
  1758	
  1759	// ToolDir is the directory containing build tools.
  1760	var ToolDir = getToolDir()
  1761	
  1762	// IsLocalImport reports whether the import path is
  1763	// a local import path, like ".", "..", "./foo", or "../foo".
  1764	func IsLocalImport(path string) bool {
  1765		return path == "." || path == ".." ||
  1766			strings.HasPrefix(path, "./") || strings.HasPrefix(path, "../")
  1767	}
  1768	
  1769	// ArchChar returns "?" and an error.
  1770	// In earlier versions of Go, the returned string was used to derive
  1771	// the compiler and linker tool names, the default object file suffix,
  1772	// and the default linker output name. As of Go 1.5, those strings
  1773	// no longer vary by architecture; they are compile, link, .o, and a.out, respectively.
  1774	func ArchChar(goarch string) (string, error) {
  1775		return "?", errors.New("architecture letter no longer used")
  1776	}
  1777	

View as plain text