diff options
Diffstat (limited to 'libgo/go/go/build/build.go')
-rw-r--r-- | libgo/go/go/build/build.go | 86 |
1 files changed, 56 insertions, 30 deletions
diff --git a/libgo/go/go/build/build.go b/libgo/go/go/build/build.go index eece7610562..d749aef1513 100644 --- a/libgo/go/go/build/build.go +++ b/libgo/go/go/build/build.go @@ -34,7 +34,7 @@ type Context struct { CgoEnabled bool // whether cgo can be used BuildTags []string // additional tags to recognize in +build lines UseAllFiles bool // use files regardless of +build lines, file names - Gccgo bool // assume use of gccgo when computing object paths + Compiler string // compiler to assume when computing target paths // By default, Import uses the operating system's file system calls // to read directories and files. To read from other sources, @@ -228,6 +228,7 @@ func defaultContext() Context { c.GOOS = envOr("GOOS", runtime.GOOS) c.GOROOT = runtime.GOROOT() c.GOPATH = envOr("GOPATH", "") + c.Compiler = runtime.Compiler switch os.Getenv("CGO_ENABLED") { case "1": @@ -277,11 +278,12 @@ type Package struct { PkgObj string // installed .a file // Source files - GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) - CgoFiles []string // .go source files that import "C" - CFiles []string // .c source files - HFiles []string // .h source files - SFiles []string // .s source files + GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) + CgoFiles []string // .go source files that import "C" + CFiles []string // .c source files + HFiles []string // .h source files + SFiles []string // .s source files + SysoFiles []string // .syso system object files to add to archive // Cgo directives CgoPkgConfig []string // Cgo pkg-config directives @@ -314,42 +316,58 @@ func (ctxt *Context) ImportDir(dir string, mode ImportMode) (*Package, error) { return ctxt.Import(".", dir, mode) } +// NoGoError is the error used by Import to describe a directory +// containing no Go source files. +type NoGoError struct { + Dir string +} + +func (e *NoGoError) Error() string { + return "no Go source files in " + e.Dir +} + // Import returns details about the Go package named by the import path, -// interpreting local import paths relative to the src directory. If the path -// is a local import path naming a package that can be imported using a -// standard import path, the returned package will set p.ImportPath to -// that path. +// interpreting local import paths relative to the srcDir directory. +// If the path is a local import path naming a package that can be imported +// using a standard import path, the returned package will set p.ImportPath +// to that path. // // In the directory containing the package, .go, .c, .h, and .s files are // considered part of the package except for: // // - .go files in package documentation -// - files starting with _ or . +// - files starting with _ or . (likely editor temporary files) // - files with build constraints not satisfied by the context // // If an error occurs, Import returns a non-nil error also returns a non-nil // *Package containing partial information. // -func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package, error) { +func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Package, error) { p := &Package{ ImportPath: path, } var pkga string - if ctxt.Gccgo { + var pkgerr error + switch ctxt.Compiler { + case "gccgo": dir, elem := pathpkg.Split(p.ImportPath) pkga = "pkg/gccgo/" + dir + "lib" + elem + ".a" - } else { + case "gc": pkga = "pkg/" + ctxt.GOOS + "_" + ctxt.GOARCH + "/" + p.ImportPath + ".a" + default: + // Save error for end of function. + pkgerr = fmt.Errorf("import %q: unknown compiler %q", path, ctxt.Compiler) } binaryOnly := false if IsLocalImport(path) { - if src == "" { + pkga = "" // local imports have no installed path + if srcDir == "" { return p, fmt.Errorf("import %q: import relative to unknown directory", path) } if !ctxt.isAbsPath(path) { - p.Dir = ctxt.joinPath(src, path) + p.Dir = ctxt.joinPath(srcDir, path) } // Determine canonical import path, if any. if ctxt.GOROOT != "" { @@ -369,7 +387,7 @@ func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package, // but check that using it wouldn't find something // else first. if ctxt.GOROOT != "" { - if dir := ctxt.joinPath(ctxt.GOROOT, "src", sub); ctxt.isDir(dir) { + if dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg", sub); ctxt.isDir(dir) { goto Found } } @@ -396,7 +414,7 @@ func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package, if ctxt.GOROOT != "" { dir := ctxt.joinPath(ctxt.GOROOT, "src", "pkg", path) isDir := ctxt.isDir(dir) - binaryOnly = !isDir && mode&AllowBinary != 0 && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga)) + binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(ctxt.GOROOT, pkga)) if isDir || binaryOnly { p.Dir = dir p.Goroot = true @@ -407,7 +425,7 @@ func (ctxt *Context) Import(path string, src string, mode ImportMode) (*Package, for _, root := range ctxt.gopath() { dir := ctxt.joinPath(root, "src", path) isDir := ctxt.isDir(dir) - binaryOnly = !isDir && mode&AllowBinary != 0 && ctxt.isFile(ctxt.joinPath(root, pkga)) + binaryOnly = !isDir && mode&AllowBinary != 0 && pkga != "" && ctxt.isFile(ctxt.joinPath(root, pkga)) if isDir || binaryOnly { p.Dir = dir p.Root = root @@ -426,14 +444,16 @@ Found: } p.PkgRoot = ctxt.joinPath(p.Root, "pkg") p.BinDir = ctxt.joinPath(p.Root, "bin") - p.PkgObj = ctxt.joinPath(p.Root, pkga) + if pkga != "" { + p.PkgObj = ctxt.joinPath(p.Root, pkga) + } } if mode&FindOnly != 0 { - return p, nil + return p, pkgerr } if binaryOnly && (mode&AllowBinary) != 0 { - return p, nil + return p, pkgerr } dirs, err := ctxt.readDir(p.Dir) @@ -467,7 +487,13 @@ Found: ext := name[i:] switch ext { case ".go", ".c", ".s", ".h", ".S": - // tentatively okay + // tentatively okay - read to make sure + case ".syso": + // binary objects to add to package archive + // Likely of the form foo_windows.syso, but + // the name was vetted above with goodOSArchFile. + p.SysoFiles = append(p.SysoFiles, name) + continue default: // skip continue @@ -586,7 +612,7 @@ Found: } } if p.Name == "" { - return p, fmt.Errorf("no Go source files in %s", p.Dir) + return p, &NoGoError{p.Dir} } p.Imports, p.ImportPos = cleanImports(imported) @@ -601,7 +627,7 @@ Found: sort.Strings(p.SFiles) } - return p, nil + return p, pkgerr } func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.Position) { @@ -614,8 +640,8 @@ func cleanImports(m map[string][]token.Position) ([]string, map[string][]token.P } // Import is shorthand for Default.Import. -func Import(path, src string, mode ImportMode) (*Package, error) { - return Default.Import(path, src, mode) +func Import(path, srcDir string, mode ImportMode) (*Package, error) { + return Default.Import(path, srcDir, mode) } // ImportDir is shorthand for Default.ImportDir. @@ -848,7 +874,7 @@ func splitQuoted(s string) (r []string, err error) { // !cgo (if cgo is disabled) // tag (if tag is listed in ctxt.BuildTags) // !tag (if tag is not listed in ctxt.BuildTags) -// a slash-separated list of any of these +// a comma-separated list of any of these // func (ctxt *Context) match(name string) bool { if name == "" { @@ -862,11 +888,11 @@ func (ctxt *Context) match(name string) bool { return false } if strings.HasPrefix(name, "!") { // negation - return !ctxt.match(name[1:]) + return len(name) > 1 && !ctxt.match(name[1:]) } // Tags must be letters, digits, underscores. - // Unlike in Go identifiers, all digits is fine (e.g., "386"). + // Unlike in Go identifiers, all digits are fine (e.g., "386"). for _, c := range name { if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' { return false |