fix(cmd): locate GOROOT when the build is trimmed
Assisted-by: GLM 5.3 Flash
This commit is contained in:
1 parent
ae1baa0e61
commit
0768b4dc84
2 files changed
+43
No files matched your search
@@ -13,6 +13,7 @@ import (
|
||||
"go/token"
|
||||
"go/types"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -217,6 +218,9 @@ type sourceImporter struct {
|
||||
func newSourceImporter(goos, goarch string) *sourceImporter {
|
||||
ctxt := new(build.Context)
|
||||
*ctxt = build.Default
|
||||
if root := resolveGOROOT(build.Default.GOROOT); root != "" {
|
||||
ctxt.GOROOT = root
|
||||
}
|
||||
ctxt.GOOS = goos
|
||||
ctxt.GOARCH = goarch
|
||||
ctxt.CgoEnabled = false
|
||||
@@ -228,6 +232,27 @@ func newSourceImporter(goos, goarch string) *sourceImporter {
|
||||
}
|
||||
}
|
||||
|
||||
// resolveGOROOT returns the root the type-checker reads standard packages
|
||||
// from, preferring a baked root that is a real directory. A binary built
|
||||
// with -trimpath carries no root: build.Default.GOROOT comes back empty and
|
||||
// every standard import fails with "GOROOT not set", so the toolchain is
|
||||
// asked, the way the corpus audit locates its own GOROOT. An empty result
|
||||
// leaves the context untouched and the failure stays the honest one.
|
||||
func resolveGOROOT(baked string) string {
|
||||
if st, err := os.Stat(baked); err == nil && st.IsDir() {
|
||||
return baked
|
||||
}
|
||||
out, err := exec.Command("go", "env", "GOROOT").Output()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
root := strings.TrimSpace(string(out))
|
||||
if st, err := os.Stat(root); err != nil || !st.IsDir() {
|
||||
return ""
|
||||
}
|
||||
return root
|
||||
}
|
||||
|
||||
// Import type-checks one imported package and memoises it. "unsafe" must
|
||||
// resolve to go/types' own package, never to the source in GOROOT/src/unsafe:
|
||||
// the source declares Sizeof and Offsetof as ordinary functions over
|
||||
|
||||
@@ -285,6 +285,24 @@ func TestGoAsmHeaderResolved(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestResolveGOROOT holds the two resolutions the header generator leans
|
||||
// on: a baked root that is a real directory passes through, and a missing
|
||||
// one falls back to what go env GOROOT names, which is what a -trimpath
|
||||
// build needs.
|
||||
func TestResolveGOROOT(t *testing.T) {
|
||||
out, err := exec.Command("go", "env", "GOROOT").Output()
|
||||
if err != nil {
|
||||
t.Skip("go env GOROOT unavailable:", err)
|
||||
}
|
||||
root := strings.TrimSpace(string(out))
|
||||
if got := resolveGOROOT(root); got != root {
|
||||
t.Fatalf("a real baked root must pass through, got %q", got)
|
||||
}
|
||||
if got := resolveGOROOT(filepath.Join(root, "nonexistent")); got != root {
|
||||
t.Fatalf("a missing baked root must resolve to %q, got %q", root, got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOtherGOOSFile(t *testing.T) {
|
||||
for path, want := range map[string]bool{
|
||||
"/x/sys_windows_amd64.s": true,
|
||||
|
||||
Reference in new issue
Block a user