Skip to content
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

cmd/go: for unset GOROOT, try to derive from os.Executable() before runtime.GOROOT() #18678

Closed
minux opened this issue Jan 17, 2017 · 17 comments
Closed

Comments

@minux
Copy link
Member

minux commented Jan 17, 2017

Proposal:

For Go 1.9, I'd like to have cmd/go use the new os.Executable APi to find GOROOT automatically. And then we can eliminate all mentions of GOROOT in user facing documents (in fact, we should actively discourage setting GOROOT in user facing documents.)

In fact, I'd like to go so far as to display a warning if the $GOROOT setting contradicts with auto-detected one.

The proposed GOROOT logic is (error handling omitted):

// if the embedded goroot is wrong, then:
gorootAuto = filepath.Dir(filepath.Dir(filepath.EvalSymlinks(os.Executable())))
// issue a warning if gorootAuto is correct (having matching VERSION) and the VERSION file
// is not os.SameFile with $GOROOT/VERSION.
// use $GOROOT if set, otherwise gorootAuto. [*]

Potential problems:

  1. hardlinking bin/go to another location.
  2. moving bin/go to another location.

In both cases, the active fallback step [*] will preserve the current behavior.

  1. distribution changes that don't follow the official GOROOT layout.

In this case, the distribution must already carry patches on the go command, so they will have to adapt the patch if this proposal is accepted.

@davecheney
Copy link
Contributor

I'd sell my firstborn male heir to get rid of GOROOT once and for all.

@rsc
Copy link
Contributor

rsc commented Jan 23, 2017

I don't object to this in theory, but I don't understand the exact proposal.

// if the embedded goroot is wrong, then:

Please define "wrong".

@rsc rsc changed the title Proposal: cmd/go: use os.Executable to find GOROOT if the embedded one is incorrect proposal: cmd/go: use os.Executable to find GOROOT if the embedded one is incorrect Jan 23, 2017
@rsc
Copy link
Contributor

rsc commented Jan 23, 2017

@davecheney Do you still have to use GOROOT regularly? I don't see why.

@davecheney
Copy link
Contributor

davecheney commented Jan 23, 2017 via email

@minux
Copy link
Member Author

minux commented Jan 23, 2017 via email

@rsc
Copy link
Contributor

rsc commented Jan 23, 2017

My $GOROOT/VERSION never exists, since I'm always building from a git checkout. Maybe this should be split into two things:

  1. Make empty $GOROOT fall back to os.Executable before the baked-in runtime.defaultGoroot.
  2. Make go command fail loudly if runtime.Version != $(cat GOROOT/VERSION).

I've wanted each of those separately, and I don't think they necessarily need to be mixed. It sounds like you are proposing:

  1. Instead of making go command fail loudly, override $GOROOT silently.

I think that might not be necessary. If we have 1, then all the people who never set $GOROOT are taken care of, and if we have 2, then that avoids silent misbehavior. Trying to go further in 3 and correct silent misbehavior into silent maybe-correct-but-maybe-still-wrong behavior is where things get tricky.

@ianlancetaylor
Copy link
Contributor

I'm concerned that your number 1 (Make empty $GOROOT fall back to os.Executable before the baked-in runtime.defaultGoroot) will break packages that install the go tool in a system-wide bin directory, and expect the baked-in defaultGoroot to let it know where to find the packages.

@davecheney
Copy link
Contributor

Make go command fail loudly if runtime.Version != $(cat GOROOT/VERSION).

I tried to implement this in gb about a year ago because gb, but sadly operating system distros ruined the party because they strip files they think aren't important.

constabulary/gb#325 :(

@rsc
Copy link
Contributor

rsc commented Jan 24, 2017

Re 1, there is a test in the go command already for identifying a $GOROOT. Something like src/cmd/go/doc.go existing or some other similar file. We could use os.Executable first, but if that doesn't produce a valid GOROOT, then fall back to defaultGoroot.

Re 2, reading VERSION is probably not good enough anyway, but the go command could invoke go tool compile version before any compilation steps.

@rsc
Copy link
Contributor

rsc commented Jan 30, 2017

It sounds like we should probably do 1 (use os.Executable for default GOROOT instead of defaultGoroot).

For 2, we'd need to make sure this does not make a noticeable change to compile times. Running

time $(go tool -n compile) -V

in a loop I get times of about 0.050 seconds.

Maybe this issue should be restricted to 1 (what to do when GOROOT is unset).

@davecheney
Copy link
Contributor

davecheney commented Jan 31, 2017 via email

@rsc
Copy link
Contributor

rsc commented Feb 13, 2017

@davecheney Yes, I think so. Filed #19064 for that.

This issue is now down to just changing the default for an unset GOROOT. I've heard no objections to trying os.Executable before falling back to defaultGoroot.

@rsc rsc changed the title proposal: cmd/go: use os.Executable to find GOROOT if the embedded one is incorrect cmd/go: for unset GOROOT, try to derive from os.Executable() before runtime.GOROOT() Feb 13, 2017
@rsc rsc modified the milestones: Go1.9, Proposal Feb 13, 2017
@davecheney
Copy link
Contributor

Yes, I think so. Filed #19064 for that.

Thanks @rsc

@gopherbot
Copy link

CL https://golang.org/cl/42533 mentions this issue.

@egonelbre
Copy link
Contributor

I have test failure after CL 42533:

--- FAIL: TestExecutableGOROOT (0.27s)
        go_test.go:3986: C:\Users\Egon\AppData\Local\Temp\gotest815240476\newgoroot\bin\go.exe env GOROOT = "c:\\Go.tip", want "C:\\Go.tip"
FAIL
FAIL    cmd/go  134.329s

Windows paths are still case-insensitive (at least usually).

@alexbrainman
Copy link
Member

--- FAIL: TestExecutableGOROOT

Issue #20336 ?

Alex

@bradfitz
Copy link
Contributor

bradfitz commented Jun 8, 2017

This was a dup of #17833. Closing that one too.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

8 participants