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