Open lacombar opened 1 year ago
In general you need to set GOROOT_FINAL
to a clean path.
That said, as of Go 1.21 there isn't much point in setting GOROOT_FINAL
at all (see #62047).
I wonder, though: perhaps cmd/link
should call filepath.Clean
or similar on the value obtained from the environment?
(https://cs.opensource.google/go/go/+/master:src/cmd/link/internal/ld/pcln.go;l=813;drc=0460c61e5fd2242d27451f527dafc4d9a098fef4)
It couldn’t quite be filepath, right? A Linux build of the linker cross compiling for Windows would need to clean a Windows path. We need path/filepath/windows, etc.
In theory, yes.
In practice, I don't actually know how the embedded GOROOT
value interacts with cross-compilation. 😅
I feel that the linker doesn't need to understand the meaning of GOROOT_FINAL
. Could the go command clean it up before passing it to the linker?
At the moment cmd/go
isn't doing anything to it unless -trimpath
is set:
https://cs.opensource.google/go/go/+/master:src/cmd/go/internal/work/gc.go;l=649;drc=fbcf43c60ba5170309a238b0e42fd5879d419776
it just assumes that the linker will do something with whatever value is in the environment:
https://cs.opensource.google/go/go/+/master:src/cmd/go/internal/work/exec.go;l=1389-1395;drc=3857a89e7eb872fa22d569e70b7e076bec74ebbb
I agree that if we keep GOROOT_FINAL
it would be reasonable for cmd/go
to clean it up in the environment. (That would at least fix invocations via go build
, although it would still leave a bit of a gap for cmd/link
invocations via third-party build tools.)
I wonder why we write "$GOROOT" at compile time and expand to the actual GOROOT at link time... I guess this may be useful previously when we had compiled .a files in GOROOT. If one moves GOROOT after compilation, those .a files are still valid. But now we don't have those .a files anymore. We probably could write the actual GOROOT (GOROOT_FINAL, if set) at compile time. Then we don't need to expand it in the linker. (We'd need to recompile if GOROOT_FINAL changes, previously we only need to relink. But that seems pretty minor.)
GOROOT_FINAL has been removed following https://github.com/golang/go/issues/62047 and the referred code uses a cleaned GOROOT path as it ends with a filepath.Join when GOROOT is set. All comments seem answered.
func expandGoroot(s string) string {
const n = len("$GOROOT")
if len(s) >= n+1 && s[:n] == "$GOROOT" && (s[n] == '/' || s[n] == '\\') {
if final := buildcfg.GOROOT; final != "" {
return filepath.ToSlash(filepath.Join(final, s[n:]))
}
}
return s
}
[same environment as #62620]
$ cd src $ GOROOT_FINAL=/final/destination/ ./all.bash
Notice the expected prefix' double path separator,
/final/destination//src/
, removing the trailing/
from the environment variable works.