-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
runtime: deprecate func GOROOT #51473
Comments
I think this is an interesting proposal, and I agree with the current confusion causing problems at times. I assume that, if a program wants to try both approaches, they could have code that first tries one approach (like |
I fully agree with your suggestion to use So when it comes to |
One possible solution would be to add a private flag to Lines 1182 to 1188 in 81767e2
|
Would that help with the added init cost, though, if its init func may still call |
@mvdan I'm not suggesting that the init func for go/build call Alternatively, at the top of |
Ah, I see. I was thinking mainly of end users directly reading |
The one case I can think of where At least in principle, it is possible for the |
@bcmills I'm not sure what the use cases are for looking up |
That's true, but if you compile a test binary with Even so, I suspect that most tests that depend on |
Gotcha. Actually, as an optimization, since we know that I guess another approach would be to have |
This proposal has been added to the active column of the proposals project |
@bradfitz reports that he has uses of runtime.GOROOT in GitHub actions where built binaries want to find the toolchain that built them, so they can invoke it to do other things. It seems like we probably need to enumerate the uses people have for runtime.GOROOT and what they should do instead. It doesn't help to just say "Deprecated". We have to say what to use instead. |
For example:
|
@bradfitz I'm not sure which repos those are, but this seems to at least partially align with with what @bcmills mentioned above re: tests. In that situation, we can make With regards to non-test binaries that intend to find the toolchain that built them, this feels somewhat ill-defined, for the reasons mentioned above, as well as issues with In short:
|
@bradfitz, thanks for those examples. I cloned the (They happen to pass when run with
There is also no guarantee in general that even a non-empty That's of course fine for tailscale's own code if you're ok with those failure modes, but may be further evidence that we should discourage that pattern in general. 😅 A more robust approach might be to simply look for |
Is "finding the go command" the only thing we need GOROOT for? Probably? Possibilities:
Number 3 would fit well with non-test code like go/build and go/packages that already assume that looking for "go" in your PATH is the one you want. Thoughts on finding the go command? And thoughts on any other needs from GOROOT? |
That wouldn't necessarily even require a new environment variable: a flag might suffice. I think the API is the tricky part. Maybe: package testing
// GOROOT reports the GOROOT with which the test was built, if known.
// This function may report a non-empty GOROOT even if runtime.GOROOT
// returns the empty string (such as if the test was built with -trimpath).
func GOROOT() (string, bool) |
Having I think this option is not really much better than deciding not to deprecate |
I like that approach a lot overall. It looks like That would also make it fairly trivial to identify the |
It sounds like people like "Have 'go test' put the Go bin directory at the front of $PATH before running the test binary." so let's start with that. @bcmills, want to write a CL for that? Then tests and things like go/packages that exec "go" will work fine without runtime.GOROOT. At that point, what is left for use cases for runtime.GOROOT? |
@rsc making sure I understand your last response: would |
@danderson, the |
Are there any other problems with deprecating runtime.GOROOT, once we've guaranteed that "go in the PATH" is the right go during a test? |
Change https://go.dev/cl/404134 mentions this issue: |
Change https://go.dev/cl/564142 mentions this issue: |
Change https://go.dev/cl/564275 mentions this issue: |
The runtime.GOROOT function is about to be marked as deprecated, which will generate a diagnostic that isn't expected in format.txt test case. Pick another hopefully somewhat future-proof identifier, since dealing with this doesn't seem to be in scope of this test case. For golang/go#51473. Change-Id: I54d7ed0b43860bcd41938328211797a0cdd60e36 Reviewed-on: https://go-review.googlesource.com/c/tools/+/564275 Auto-Submit: Dmitri Shuralyov <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> Reviewed-by: Robert Findley <[email protected]>
A fix CL is available but hasn't been reviewed before Go 1.23 freeze. Moving to the next milestone. |
https://pkg.go.dev/time#LoadLocation still relies on The cost of |
I should also note that |
We originally introduced the fallback to $GOROOT/lib/time for Windows and Plan 9 (https://golang.org/cl/5656101, #2964). Since then it looks like maybe iOS needs it also. For iOS in particular I'm not sure that running |
To add to that, As @ianlancetaylor alluded to, the application may be running on a system that doesn't even have a Go installation, so running For now I think |
Out of curiosity, why does https://pkg.go.dev/time#LoadLocation need to read $GOROOT/lib/time/zoneinfo.zip? What GOOS/GOARCH or mode uses it instead of the OS zoneinfo/tzdata? |
@willfaught See @ianlancetaylor's comment above, and burrowers/garble#878. |
For environments where Personally I would prefer if we nudged everyone towards https://pkg.go.dev/time/tzdata in the longer term, but assuming that we want to preserve the current zip loading logic from GOROOT, I think we should switch it to
I would also not be surprised by this either, but I think those users would continue to be satisfied by the switch to |
@mvdan Today I can compile an application that calls |
Proposal for a proposal: Add |
@rittneje fair enough, but that has nothing to do with the embedded GOROOT value. The logic could be to query the GOROOT env var first, and if empty, fall back to @DeedleFake that is a separate proposal so it's best to not mix the two. |
@mvdan Let's say I have Windows machine with Go installed at C:\Go. I then use that to compile my application (without @DeedleFake This can already be achieved in practice via |
@rittneje that seems to me like a rare use case which relies on the embedded path, which is now being discouraged via this deprecation. I'm not arguing we need to break it right away, and it could be a phased approach via a GODEBUG, but I definitely think we need to stop supporting such a use case. |
If we are going to keep checking |
@ianlancetaylor I'm not sure what you mean by "keep checking
In my view, as the documentation for In short, there are really three choices:
|
Using |
@rittneje For your point 2, the |
@ianlancetaylor I do not personally believe it is actively harmful for Meanwhile, if someone really wants to augment |
The
runtime.GOROOT()
function is currently implemented as follows:GOROOT
environment variable is set, return its value.Unfortunately, this implementation cannot be relied upon to have any semantic meaning in general.
If the intent is to know what GOROOT the binary was compiled with, then consulting the
GOROOT
environment variable is wrong. Instead, the burned in value should be added todebug.BuildInfo
.If the intent is to know the GOROOT on the current machine, then consulting the burned in value is wrong, as it cannot handle the following (non-exhaustive) scenarios:
GOROOT
.PATH
environment variable may have changed since the binary was compiled.Instead, the
go env GOROOT
command should be used. In particular, this change needs to be made forgo/build.Default
to function properly in all cases.The text was updated successfully, but these errors were encountered: