]> Cypherpunks repositories - gostls13.git/commitdiff
go/build: move isStandardPackage to new internal/goroot package
authorIan Lance Taylor <iant@golang.org>
Tue, 25 Sep 2018 19:49:22 +0000 (12:49 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 25 Sep 2018 22:07:43 +0000 (22:07 +0000)
The module code in cmd/go sometimes needs to know whether it is
looking at a standard package, and currently uses gc-specific code for
that. This CL moves the existing isStandardPackage code in the
go/build package, which works for both gc and gccgo, into a new
internal/goroot package so that cmd/go can call it. The changes to
cmd/go will be in a subsequent CL.

Change-Id: Ic1ce4c022a932c6b3e99fa062631577085cc6ecb
Reviewed-on: https://go-review.googlesource.com/137435
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/go/build/build.go
src/go/build/deps_test.go
src/go/build/gc.go
src/go/build/gccgo.go
src/internal/goroot/gc.go [new file with mode: 0644]
src/internal/goroot/gccgo.go [new file with mode: 0644]

index b68a712a7daba2413c28da94e15457ba19cbae36..14b007c25a7a501a21b983b8135326b299dea1fc 100644 (file)
@@ -12,6 +12,7 @@ import (
        "go/doc"
        "go/parser"
        "go/token"
+       "internal/goroot"
        "io"
        "io/ioutil"
        "log"
@@ -656,7 +657,7 @@ func (ctxt *Context) Import(path string, srcDir string, mode ImportMode) (*Packa
                        }
                        tried.goroot = dir
                }
-               if ctxt.Compiler == "gccgo" && isStandardPackage(path) {
+               if ctxt.Compiler == "gccgo" && goroot.IsStandardPackage(ctxt.GOROOT, ctxt.Compiler, path) {
                        p.Dir = ctxt.joinPath(ctxt.GOROOT, "src", path)
                        p.Goroot = true
                        p.Root = ctxt.GOROOT
index 244c745d41df1417f10a712a74b34521b87e8cdc..91617714f6cc46984860766055800367014a9413 100644 (file)
@@ -258,7 +258,7 @@ var pkgDeps = map[string][]string{
        "encoding/pem":                   {"L4"},
        "encoding/xml":                   {"L4", "encoding"},
        "flag":                           {"L4", "OS"},
-       "go/build":                       {"L4", "OS", "GOPARSER"},
+       "go/build":                       {"L4", "OS", "GOPARSER", "internal/goroot"},
        "html":                           {"L4"},
        "image/draw":                     {"L4", "image/internal/imageutil"},
        "image/gif":                      {"L4", "compress/lzw", "image/color/palette", "image/draw"},
@@ -266,6 +266,7 @@ var pkgDeps = map[string][]string{
        "image/jpeg":                     {"L4", "image/internal/imageutil"},
        "image/png":                      {"L4", "compress/zlib"},
        "index/suffixarray":              {"L4", "regexp"},
+       "internal/goroot":                {"L4", "OS"},
        "internal/singleflight":          {"sync"},
        "internal/trace":                 {"L4", "OS"},
        "math/big":                       {"L4"},
index e2be2cbb1d18ff158849714caa3f19725a8ffc8f..3025cd5681591f0c2f0aaee701786be344dcdcc5 100644 (file)
 package build
 
 import (
-       "os"
-       "os/exec"
        "path/filepath"
        "runtime"
-       "strings"
-       "sync"
 )
 
 // getToolDir returns the default value of ToolDir.
 func getToolDir() string {
        return filepath.Join(runtime.GOROOT(), "pkg/tool/"+runtime.GOOS+"_"+runtime.GOARCH)
 }
-
-// isStandardPackage is not used for the gc toolchain.
-// However, this function may be called when using `go build -compiler=gccgo`.
-func isStandardPackage(path string) bool {
-       return gccgoSearch.isStandard(path)
-}
-
-// gccgoSearch holds the gccgo search directories.
-type gccgoDirs struct {
-       once sync.Once
-       dirs []string
-}
-
-// gccgoSearch is used to check whether a gccgo package exists in the
-// standard library.
-var gccgoSearch gccgoDirs
-
-// init finds the gccgo search directories. If this fails it leaves dirs == nil.
-func (gd *gccgoDirs) init() {
-       gccgo := os.Getenv("GCCGO")
-       if gccgo == "" {
-               gccgo = "gccgo"
-       }
-       bin, err := exec.LookPath(gccgo)
-       if err != nil {
-               return
-       }
-
-       allDirs, err := exec.Command(bin, "-print-search-dirs").Output()
-       if err != nil {
-               return
-       }
-       versionB, err := exec.Command(bin, "-dumpversion").Output()
-       if err != nil {
-               return
-       }
-       version := strings.TrimSpace(string(versionB))
-       machineB, err := exec.Command(bin, "-dumpmachine").Output()
-       if err != nil {
-               return
-       }
-       machine := strings.TrimSpace(string(machineB))
-
-       dirsEntries := strings.Split(string(allDirs), "\n")
-       const prefix = "libraries: ="
-       var dirs []string
-       for _, dirEntry := range dirsEntries {
-               if strings.HasPrefix(dirEntry, prefix) {
-                       dirs = filepath.SplitList(strings.TrimPrefix(dirEntry, prefix))
-                       break
-               }
-       }
-       if len(dirs) == 0 {
-               return
-       }
-
-       var lastDirs []string
-       for _, dir := range dirs {
-               goDir := filepath.Join(dir, "go", version)
-               if fi, err := os.Stat(goDir); err == nil && fi.IsDir() {
-                       gd.dirs = append(gd.dirs, goDir)
-                       goDir = filepath.Join(goDir, machine)
-                       if fi, err = os.Stat(goDir); err == nil && fi.IsDir() {
-                               gd.dirs = append(gd.dirs, goDir)
-                       }
-               }
-               if fi, err := os.Stat(dir); err == nil && fi.IsDir() {
-                       lastDirs = append(lastDirs, dir)
-               }
-       }
-       gd.dirs = append(gd.dirs, lastDirs...)
-}
-
-// isStandard returns whether path is a standard library for gccgo.
-func (gd *gccgoDirs) isStandard(path string) bool {
-       // Quick check: if the first path component has a '.', it's not
-       // in the standard library. This skips most GOPATH directories.
-       i := strings.Index(path, "/")
-       if i < 0 {
-               i = len(path)
-       }
-       if strings.Contains(path[:i], ".") {
-               return false
-       }
-
-       if path == "unsafe" {
-               // Special case.
-               return true
-       }
-
-       gd.once.Do(gd.init)
-       if gd.dirs == nil {
-               // We couldn't find the gccgo search directories.
-               // Best guess, since the first component did not contain
-               // '.', is that this is a standard library package.
-               return true
-       }
-
-       for _, dir := range gd.dirs {
-               full := filepath.Join(dir, path)
-               pkgdir, pkg := filepath.Split(full)
-               for _, p := range [...]string{
-                       full,
-                       full + ".gox",
-                       pkgdir + "lib" + pkg + ".so",
-                       pkgdir + "lib" + pkg + ".a",
-                       full + ".o",
-               } {
-                       if fi, err := os.Stat(p); err == nil && !fi.IsDir() {
-                               return true
-                       }
-               }
-       }
-
-       return false
-}
index 59e089d69db2cee93077b7ea20d075389ae836c0..c6aac9aa1bc2d6fb5eec8749a220f4b69ced5036 100644 (file)
@@ -12,9 +12,3 @@ import "runtime"
 func getToolDir() string {
        return envOr("GCCGOTOOLDIR", runtime.GCCGOTOOLDIR)
 }
-
-// isStandardPackage returns whether path names a standard library package.
-// This uses a list generated at build time.
-func isStandardPackage(path string) bool {
-       return stdpkg[path]
-}
diff --git a/src/internal/goroot/gc.go b/src/internal/goroot/gc.go
new file mode 100644 (file)
index 0000000..b9da9a5
--- /dev/null
@@ -0,0 +1,140 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build gc
+
+package goroot
+
+import (
+       "os"
+       "os/exec"
+       "path/filepath"
+       "strings"
+       "sync"
+)
+
+// IsStandardPackage returns whether path is a standard package,
+// given goroot and compiler.
+func IsStandardPackage(goroot, compiler, path string) bool {
+       switch compiler {
+       case "gc":
+               dir := filepath.Join(goroot, "src", path)
+               _, err := os.Stat(dir)
+               return err == nil
+       case "gccgo":
+               return gccgoSearch.isStandard(path)
+       default:
+               panic("unknown compiler " + compiler)
+       }
+}
+
+// gccgoSearch holds the gccgo search directories.
+type gccgoDirs struct {
+       once sync.Once
+       dirs []string
+}
+
+// gccgoSearch is used to check whether a gccgo package exists in the
+// standard library.
+var gccgoSearch gccgoDirs
+
+// init finds the gccgo search directories. If this fails it leaves dirs == nil.
+func (gd *gccgoDirs) init() {
+       gccgo := os.Getenv("GCCGO")
+       if gccgo == "" {
+               gccgo = "gccgo"
+       }
+       bin, err := exec.LookPath(gccgo)
+       if err != nil {
+               return
+       }
+
+       allDirs, err := exec.Command(bin, "-print-search-dirs").Output()
+       if err != nil {
+               return
+       }
+       versionB, err := exec.Command(bin, "-dumpversion").Output()
+       if err != nil {
+               return
+       }
+       version := strings.TrimSpace(string(versionB))
+       machineB, err := exec.Command(bin, "-dumpmachine").Output()
+       if err != nil {
+               return
+       }
+       machine := strings.TrimSpace(string(machineB))
+
+       dirsEntries := strings.Split(string(allDirs), "\n")
+       const prefix = "libraries: ="
+       var dirs []string
+       for _, dirEntry := range dirsEntries {
+               if strings.HasPrefix(dirEntry, prefix) {
+                       dirs = filepath.SplitList(strings.TrimPrefix(dirEntry, prefix))
+                       break
+               }
+       }
+       if len(dirs) == 0 {
+               return
+       }
+
+       var lastDirs []string
+       for _, dir := range dirs {
+               goDir := filepath.Join(dir, "go", version)
+               if fi, err := os.Stat(goDir); err == nil && fi.IsDir() {
+                       gd.dirs = append(gd.dirs, goDir)
+                       goDir = filepath.Join(goDir, machine)
+                       if fi, err = os.Stat(goDir); err == nil && fi.IsDir() {
+                               gd.dirs = append(gd.dirs, goDir)
+                       }
+               }
+               if fi, err := os.Stat(dir); err == nil && fi.IsDir() {
+                       lastDirs = append(lastDirs, dir)
+               }
+       }
+       gd.dirs = append(gd.dirs, lastDirs...)
+}
+
+// isStandard returns whether path is a standard library for gccgo.
+func (gd *gccgoDirs) isStandard(path string) bool {
+       // Quick check: if the first path component has a '.', it's not
+       // in the standard library. This skips most GOPATH directories.
+       i := strings.Index(path, "/")
+       if i < 0 {
+               i = len(path)
+       }
+       if strings.Contains(path[:i], ".") {
+               return false
+       }
+
+       if path == "unsafe" {
+               // Special case.
+               return true
+       }
+
+       gd.once.Do(gd.init)
+       if gd.dirs == nil {
+               // We couldn't find the gccgo search directories.
+               // Best guess, since the first component did not contain
+               // '.', is that this is a standard library package.
+               return true
+       }
+
+       for _, dir := range gd.dirs {
+               full := filepath.Join(dir, path)
+               pkgdir, pkg := filepath.Split(full)
+               for _, p := range [...]string{
+                       full,
+                       full + ".gox",
+                       pkgdir + "lib" + pkg + ".so",
+                       pkgdir + "lib" + pkg + ".a",
+                       full + ".o",
+               } {
+                       if fi, err := os.Stat(p); err == nil && !fi.IsDir() {
+                               return true
+                       }
+               }
+       }
+
+       return false
+}
diff --git a/src/internal/goroot/gccgo.go b/src/internal/goroot/gccgo.go
new file mode 100644 (file)
index 0000000..098e77d
--- /dev/null
@@ -0,0 +1,27 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build gccgo
+
+package goroot
+
+import (
+       "os"
+       "path/filepath"
+)
+
+// IsStandardPackage returns whether path is a standard package,
+// given goroot and compiler.
+func IsStandardPackage(goroot, compiler, path string) bool {
+       switch compiler {
+       case "gc":
+               dir := filepath.Join(goroot, "src", path)
+               _, err := os.Stat(dir)
+               return err == nil
+       case "gccgo":
+               return stdpkg[path]
+       default:
+               panic("unknown compiler " + compiler)
+       }
+}