fix(cmd): locate GOROOT when the build is trimmed

Assisted-by: GLM 5.3 Flash
This commit is contained in:
petrbalvin committed 2026-10-06 20:24:39 +02:00
1 parent ae1baa0e61
commit 0768b4dc84
2 files changed
+43

No files matched your search

+25
View File
@@ -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
+18
View File
@@ -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,