bazelbuild / rules_go

Go rules for Bazel
Apache License 2.0
1.35k stars 638 forks source link

How to get GOROOT in 0.9.0 #1273

Closed nclinger closed 5 years ago

nclinger commented 6 years ago

Now that GOROOT is not available in the toolchain under toolcain.paths.root.path what is the correct way to get the GOROOT?

Both go_context.go.short_path & go_context.root seems to return the root directory for bazel (external/go_sdk), but not your local root directory (/usr/local/go in my case).

Thoughts?

Also is there a better place to post questions?

jayconrod commented 6 years ago

Are you looking for the GOROOT set in the host environment? There shouldn't be any way to get that value within the rules, since it may result in non-reproducible builds and would probably not be friendly to remote builds.

We construct a GOROOT internally in @go_sdk. This is what go.root points to. It can be based on a downloaded SDK or on your host SDK (GOROOT) if you call go_register_toolchains(go_version = "host") in your WORKSPACE file.

Could you tell us more about what you're trying to do? We might be able to figure out another solution.

nate-meta commented 6 years ago

Thanks for the response!

I am trying to use the following gomock rule suggested here: https://gist.github.com/jmhodges/8037c7fc072979aff8345c620834387d

I've added a go_context so I can get access to go.root, and changed lines 24-32 to be:

export GOROOT={goroot} &&
export PATH=$GOROOT/bin:$PATH &&
export GOPATH={gopath} &&
{mockgen} {args}
""".format(
goroot=go.root,
gopath=gopath,
mockgen="$(pwd)/"+ctx.file._mockgen.path,
args = " ".join(args)

However, I get the following error Loading input failed: exec: "go": executable file not found in $PATH

If bazel is using the internally downloaded go SDK (I haven't set anything in the WORKSPACE around this), then I would assume that my external paths set in my bash profile shouldn't affect this either correct? In which case I am not sure why this rule is failing to find the @go_sdk. Thoughts on what might be the issue?

jayconrod commented 6 years ago

@ianthehat would be a better person to answer this.

I believe you'll need to define the _gomock_sh rule using the go_rule wrapper (see The context in go/toolchains.rst). Once you get a GoContext object using go_context, you can access the go binary with go.go.

I expect that adding $GOROOT/bin to PATH is correct though. Maybe you need to add go.go to the list of inputs for that action? Perhaps some files are missing from the sandbox.

nate-meta commented 6 years ago

Yup, doing just that, added a go_context_data attribute in order to get the go_context. What I suspect is that the go binary is missing in the sandbox, but not sure yet how to check if that's the case.

jayconrod commented 6 years ago

Make sure to use the go_rule wrapper instead of adding _go_context_data directly. Some additional attributes may be expected by go_context in the future, and that will take care of them.

My favorite tool for sandbox debugging is just to run find (bash) or filepath.Walk (Go). Can be illuminating if you expect to see something that isn't there. You might also try --spawn_strategy=standalone to disable sandboxing.

awh commented 6 years ago

Has anyone got this working? I too have modified the gist to use go_context, but the root attribute is a relative path (external/go_sdk) which doesn't appear to be in the sandbox (checked by inserting a find . && in front of the run_shell command)...

nate-meta commented 6 years ago

@awh I ended up hard coding the path to my local go binary, which is terribly hacky but after getting the rule to work on a half dozen computers it failed to work on some other ones. I wasn't able to debug why it failed on some machines but not others (mix of macs and ubuntu). We filed a bug with Bazel as this seems to be an issue with Bazel but not sure.

jayconrod commented 5 years ago

Closing some old issues. GOROOT can now be accessed as go.root or go.env["GOROOT"] from the go_context object.

Note that GOROOT will point to the standard library for the target, which may be different than the host SDK. If you need the host SDK, check go.sdk.root_file.dirname.

These paths may be relative. Paths cannot be absolutized during analysis (we don't know where actions will execute). Take care when absolutizing paths in analysis; if machine-specific paths get baked into outputs, that breaks reproducibility.