|
2 | 2 | // Use of this source code is governed by a BSD-style
|
3 | 3 | // license that can be found in the LICENSE file.
|
4 | 4 |
|
5 |
| -// This file contains the FindPkg and Import functions for tests |
6 |
| -// to use gc-generated object files. |
| 5 | +// This file implements the Import function for tests to use gc-generated object files. |
7 | 6 |
|
8 | 7 | package importer
|
9 | 8 |
|
10 | 9 | import (
|
11 | 10 | "bufio"
|
12 |
| - "bytes" |
13 |
| - "errors" |
14 | 11 | "fmt"
|
15 |
| - "go/build" |
| 12 | + "internal/exportdata" |
16 | 13 | "internal/pkgbits"
|
17 | 14 | "internal/saferio"
|
18 | 15 | "io"
|
19 | 16 | "os"
|
20 |
| - "os/exec" |
21 |
| - "path/filepath" |
22 | 17 | "strings"
|
23 |
| - "sync" |
24 | 18 |
|
25 | 19 | "cmd/compile/internal/types2"
|
26 | 20 | )
|
27 | 21 |
|
28 |
| -var exportMap sync.Map // package dir → func() (string, error) |
29 |
| - |
30 |
| -// lookupGorootExport returns the location of the export data |
31 |
| -// (normally found in the build cache, but located in GOROOT/pkg |
32 |
| -// in prior Go releases) for the package located in pkgDir. |
33 |
| -// |
34 |
| -// (We use the package's directory instead of its import path |
35 |
| -// mainly to simplify handling of the packages in src/vendor |
36 |
| -// and cmd/vendor.) |
37 |
| -func lookupGorootExport(pkgDir string) (string, error) { |
38 |
| - f, ok := exportMap.Load(pkgDir) |
39 |
| - if !ok { |
40 |
| - var ( |
41 |
| - listOnce sync.Once |
42 |
| - exportPath string |
43 |
| - err error |
44 |
| - ) |
45 |
| - f, _ = exportMap.LoadOrStore(pkgDir, func() (string, error) { |
46 |
| - listOnce.Do(func() { |
47 |
| - cmd := exec.Command(filepath.Join(build.Default.GOROOT, "bin", "go"), "list", "-export", "-f", "{{.Export}}", pkgDir) |
48 |
| - cmd.Dir = build.Default.GOROOT |
49 |
| - cmd.Env = append(os.Environ(), "PWD="+cmd.Dir, "GOROOT="+build.Default.GOROOT) |
50 |
| - var output []byte |
51 |
| - output, err = cmd.Output() |
52 |
| - if err != nil { |
53 |
| - if ee, ok := err.(*exec.ExitError); ok && len(ee.Stderr) > 0 { |
54 |
| - err = errors.New(string(ee.Stderr)) |
55 |
| - } |
56 |
| - return |
57 |
| - } |
58 |
| - |
59 |
| - exports := strings.Split(string(bytes.TrimSpace(output)), "\n") |
60 |
| - if len(exports) != 1 { |
61 |
| - err = fmt.Errorf("go list reported %d exports; expected 1", len(exports)) |
62 |
| - return |
63 |
| - } |
64 |
| - |
65 |
| - exportPath = exports[0] |
66 |
| - }) |
67 |
| - |
68 |
| - return exportPath, err |
69 |
| - }) |
70 |
| - } |
71 |
| - |
72 |
| - return f.(func() (string, error))() |
73 |
| -} |
74 |
| - |
75 |
| -var pkgExts = [...]string{".a", ".o"} // a file from the build cache will have no extension |
76 |
| - |
77 |
| -// FindPkg returns the filename and unique package id for an import |
78 |
| -// path based on package information provided by build.Import (using |
79 |
| -// the build.Default build.Context). A relative srcDir is interpreted |
80 |
| -// relative to the current working directory. |
81 |
| -// |
82 |
| -// This function should only be used in tests. |
83 |
| -func FindPkg(path, srcDir string) (filename, id string, err error) { |
84 |
| - // TODO(taking): move FindPkg into src/internal and dedup src/go/internal/gcimporter.FindPkg |
85 |
| - |
86 |
| - if path == "" { |
87 |
| - return "", "", errors.New("path is empty") |
88 |
| - } |
89 |
| - |
90 |
| - var noext string |
91 |
| - switch { |
92 |
| - default: |
93 |
| - // "x" -> "$GOPATH/pkg/$GOOS_$GOARCH/x.ext", "x" |
94 |
| - // Don't require the source files to be present. |
95 |
| - if abs, err := filepath.Abs(srcDir); err == nil { // see issue 14282 |
96 |
| - srcDir = abs |
97 |
| - } |
98 |
| - var bp *build.Package |
99 |
| - bp, err = build.Import(path, srcDir, build.FindOnly|build.AllowBinary) |
100 |
| - if bp.PkgObj == "" { |
101 |
| - if bp.Goroot && bp.Dir != "" { |
102 |
| - filename, err = lookupGorootExport(bp.Dir) |
103 |
| - if err == nil { |
104 |
| - _, err = os.Stat(filename) |
105 |
| - } |
106 |
| - if err == nil { |
107 |
| - return filename, bp.ImportPath, nil |
108 |
| - } |
109 |
| - } |
110 |
| - goto notfound |
111 |
| - } else { |
112 |
| - noext = strings.TrimSuffix(bp.PkgObj, ".a") |
113 |
| - } |
114 |
| - id = bp.ImportPath |
115 |
| - |
116 |
| - case build.IsLocalImport(path): |
117 |
| - // "./x" -> "/this/directory/x.ext", "/this/directory/x" |
118 |
| - noext = filepath.Join(srcDir, path) |
119 |
| - id = noext |
120 |
| - |
121 |
| - case filepath.IsAbs(path): |
122 |
| - // for completeness only - go/build.Import |
123 |
| - // does not support absolute imports |
124 |
| - // "/x" -> "/x.ext", "/x" |
125 |
| - noext = path |
126 |
| - id = path |
127 |
| - } |
128 |
| - |
129 |
| - if false { // for debugging |
130 |
| - if path != id { |
131 |
| - fmt.Printf("%s -> %s\n", path, id) |
132 |
| - } |
133 |
| - } |
134 |
| - |
135 |
| - // try extensions |
136 |
| - for _, ext := range pkgExts { |
137 |
| - filename = noext + ext |
138 |
| - f, statErr := os.Stat(filename) |
139 |
| - if statErr == nil && !f.IsDir() { |
140 |
| - return filename, id, nil |
141 |
| - } |
142 |
| - if err == nil { |
143 |
| - err = statErr |
144 |
| - } |
145 |
| - } |
146 |
| - |
147 |
| -notfound: |
148 |
| - if err == nil { |
149 |
| - return "", path, fmt.Errorf("can't find import: %q", path) |
150 |
| - } |
151 |
| - return "", path, fmt.Errorf("can't find import: %q: %w", path, err) |
152 |
| -} |
153 |
| - |
154 | 22 | // Import imports a gc-generated package given its import path and srcDir, adds
|
155 | 23 | // the corresponding package object to the packages map, and returns the object.
|
156 | 24 | // The packages map must contain all packages already imported.
|
@@ -178,7 +46,7 @@ func Import(packages map[string]*types2.Package, path, srcDir string, lookup fun
|
178 | 46 | rc = f
|
179 | 47 | } else {
|
180 | 48 | var filename string
|
181 |
| - filename, id, err = FindPkg(path, srcDir) |
| 49 | + filename, id, err = exportdata.FindPkg(path, srcDir) |
182 | 50 | if filename == "" {
|
183 | 51 | if path == "unsafe" {
|
184 | 52 | return types2.Unsafe, nil
|
@@ -207,7 +75,7 @@ func Import(packages map[string]*types2.Package, path, srcDir string, lookup fun
|
207 | 75 | defer rc.Close()
|
208 | 76 |
|
209 | 77 | buf := bufio.NewReader(rc)
|
210 |
| - hdr, size, err := FindExportData(buf) |
| 78 | + hdr, size, err := exportdata.FindExportData(buf) |
211 | 79 | if err != nil {
|
212 | 80 | return
|
213 | 81 | }
|
|
0 commit comments