We need to handle build tags correctly in the LSP. If a user is on Linux, they should still see completions, diagnostics, etc. for files tagged with any other OS.
Bitten by this also, lost an hour trying to figure out why after migrating to gopls
basic functionalities didn't work...no import-organize, no format, no nothing. Afterwards I found that it's was working properly for everything except for files with build tags as mentioned in #31286.
I'm wondering whether this is the right issue to become the umbrella issue for our long-running discussion about context?
This is killing me with integration tests that have build tags. Any workarounds known?
@sjdweb current workaround I'm using is to set the GOFLAGS environment variable. This is the configuration I'm using in VS Code:
"gopls.env": {
"GOFLAGS": "-tags=test"
},
This was brought up on Tuesday's golang-tools call.
@christiankiely - the "editor level" GOFLAGS
approach your describe works in some cases, but not all. Because setting the flag in that way sets the flag for _all_ modules and packages, i.e. for the gopls
instance used by the editor.
In discussions we've had thus far it seems for a complete solution we need to be able to define the sets of valid build flags at various levels:
We also need:
gopls
The conclusion on Tuesday's call was broadly that there are other higher priority issues right now; add to that, a solution that doesn't involve LSP spec changes isn't exactly jumping out at us.
cc @ianthehat @dominikh
Bitten by this as well. I use build tags to distinguish between normal builds and debug builds. Now VSCode reports logError redeclared in this block
error and the file is constantly marked as having errors.
Another populate use case: when using wire, there are two copies of the initializers:
gopls highlights them as duplicate definitions because it ignores build tags.
Is there a short term workaround in this simpler use case? Some way to make gopls ignore files with the wireinject build tag?
Thank you for sharing this info. We realize that this is an issue that affects a lot of people, so we're trying to come up with a viable solution. It's a complicated problem, but to start, I think we can try to disable diagnostics on files that would be excluded given your GOOS/GOARCH.
As a data point, I'm experiencing this today in any package that picks up os/user
because it uses build tags to decide how to wire in OS user lookup. In my case, it's that analysis fails because cgoLookupHost
isn't defined as files aren't being evaluated.
I understand that you'd like for gopls to allow for reading and analysis of files intended for a different GOOS that the one that the editor is on, but given how packages are structured, you'd having to perform analysis on the matrix of build tags. That seems.... time consuming at best. Plumbing through a default tag set seems like an easy way to at least get folks moving again.
I'm happy to look into how to do that if need be! Please just let me know.
Looks like it's also firing from net
looking like:
/usr/local/Cellar/go/1.12/libexec/src/net/lookup_unix.go:81:24: undeclared name: cgoLookupHost
@evanphx I also found this issue.
The workaround is launch gopls
use CGO_ENABLED=0
or something. Note that might be vscode can't that workaround AFAIK. Also not solved if set CGO_ENABLED=0
to env
. Because it is late to place.
https://github.com/golang/go/issues/29202#issuecomment-488469829
Now I develop the client
side for IDE written in Go, it's implemented set some env
to launch gopls
binary using set to exec.Command.Env
. I did solve the use it.
Anyway, We should including CGO_ENABLED=0
to gopls
send Build info
.
@zchee Ah! That makes a lot of sense, I'll start it with CGO_ENABLED=0 and see how it works.
@evanphx
Also, I was send CL (but I think still not user friendly) for support build tags.
https://go-review.googlesource.com/c/tools/+/178782
It solved if your code needs any build tags such as purego
, static
.
@evanphx
FYI, ref for your issue root cause:
https://github.com/golang/go/issues/31705
@stamblerre
Can we close this issue by below CL?
I think we will still need special handling for build tags so that users don't need special configurations to get gopls
features in files tagged for different build systems.
@stamblerre
I see, totally agreed.
@sjdweb current workaround I'm using is to set the GOFLAGS environment variable. This is the configuration I'm using in VS Code:
"gopls.env": { "GOFLAGS": "-tags=test" },
This incurs an Unknown configuration setting
error in VS Code
1.36.1 with gopls
v0.1.3, and instead I have to use the configuration below to make it work.
"go.toolsEnvVars": {
"GOFLAGS": "-tags=test"
},
I recently opened https://github.com/golang/go/issues/33389 to get a better sense of the use cases for build tags. Please add your own use cases if they are not yet listed in this issue - it will help us better understand how to solve this issue.
+1
I'm having issues with VSCode flagging my different function implementations for different versions of go as duplications
RS: You probably already know this, gopls does not handle mutually exclusive build tags at all. I have one file with '// +build debug', and an almost identical file in the same folder with '// +build !debug'. gopls flagged every constant, variable and function as being redefined between the two files. Good luck with the fix.
https://github.com/golang/go/issues/39005 might be of interest to the people following this thread. It's an attempt at defining a build-system-agnostic list of build configurations for a project, in a way that can be consumed by many tools like staticcheck and gopls.
For anyone having issues with wire + VSCode flagging auto generated function implementations as duplications, edit the project settings json and put this:
"go.buildTags": "wireinject"
This solved for me. Have a downside that now your wire.go file will not have any code completion and validation, but you can just uncomment the build flag when developing to get those back.
in coc.nvim+coc-go, for wire inject, add:
"go.goplsOptions": {
"buildFlags": ["-tags=wireinject"]
},
Is there any timeline on releasing support for build tags in gopls, and consequently in vscode?
We will not add any new behavior to improve build tag handling before gopls/v1.0
. For now, the best way to work with gopls
and build tags is by using the configurations suggested above.
@stamblerre What's the exact property that needs to be set in settings.json (vscode) to switch build tags?
I would suggest the work-around described in this comment: https://github.com/golang/go/issues/29202#issuecomment-488469829.
for a variable being overwritten based on build constraints, I tried every suggested config in this thread. it doesn't work.
here is the overwritten case:
the propose is to return the internal/lsp/lsprpc/autostart_posix.go , the behavior of 'definition' query should consider the 'build tags', in this case, it is "// +build darwin dragonfly freebsd linux netbsd openbsd solaris".
any suggestion on this case? @stamblerre
To be able to edit windows-specific golang code ("xxx_windows.go") requiring windows-only golang packages on my OSX machine, I had to add this to my VSCode settings:
"go.toolsEnvVars": {
"GOOS": "windows"
}
"gopls.env": {
"GOFLAGS": "-tags=test"
},
Where does this go? I tried settings.json and I get:
Unknown Configuration Setting
@Merrit: That's correct--the unknown configuration setting message is a warning, but it will still work.
I see. Am I misunderstanding the purpose then?
For example in one of my _linux.go files I am still getting No packages found for open file
, unable to access functions from this file, etc.
If I add // +build windows
everything works as expected.
Are you working on Windows / adding the Windows tag to the Linux file? OS-specific tags are detected based on your OS, so unless you set GOFLAGS
to -tags=linux
, you won't get editor features working for the _linux.go files.
Yes, currently working on Windows & having issues working with *_linux.go files. Not sure why I would _want_ to be unable to reference or work on Linux files just because I am on Windows, or vice versa.
Setting this in settings.json seems to have it working, so far:
"gopls.env": {
"GOFLAGS": "-tags=linux"
},
Thank you!
Spoke too soon.
Editor features work fine, but it then fails to run / debug.
undefined: funcFromLinuxFile
I tried adding "buildFlags": "-tags=linux"
to launch.json, but that makes it try to compile the linux version which fails quite spectacularly. :)
Also tried "buildFlags": "-tags=test"
, "buildFlags": "-tags=!linux"
and "buildFlags": "-tags '!linux test'"
.
Only solution so far is to just stop naming things with the *_os.go scheme, which I was given to understand was the preference for conditional compilation. FYI, naming the files featureLinux.go
and leaving it be works just fine. Adding // +build linux
to that same file breaks things the same as using the *_linux.go naming scheme.
Not sure why I would _want_ to be unable to reference or work on Linux files just because I am on Windows, or vice versa.
This is a current limitation of gopls
, and this issue is tracking improving that behavior.
I tried adding
"buildFlags": "-tags=linux"
to launch.json, but that makes it try to compile the linux version which fails quite spectacularly. :)
You won't actually be able to run code meant for Linux on Windows--my suggestion was just to get editor features for development purposes.
Right, I don't want to run or compile anything meant for a different OS. Just mentioning what I had tried to resolve my issue.
Ideally what I would like is:
Currently I can only get 2 & 3 on my list by _not_ naming files by OS nor using the // +build _____
-- which I understand means no conditional compilation.
Wanted to be able to use _go generate_ in a directory to get a _go run gen.go_ called and found gopls doesn't seem to work on the gen.go file because of a mix of build flags in other local files. Can I work around this by invoking vim on gen.go with an environment variable set to something for the benefit of gopls or is moving the gen.go into its own directory my best option?
_gopls definition_ does work from a file that has an _ignore_ build tag, but not if a plain go file in the same directory exists.
sh
$ cat -n gen.go
1 // +build ignore
2
3 package main
4
5 import (
6 "fmt"
7 )
8
9 func main() {
10 fmt.Println("Hello world!")
11 }
$ gopls definition gen.go:10:10
gopls: /<snip>/gen.go:10:10: no packages returned: packages.Load error
$ rm config.go
$ gopls definition gen.go:10:10
/<snip>/go1.15.5/src/fmt/print.go:273:6-13: defined here as func fmt.Println<snip>
The command line doesn't really give you much configurability, but you can set the GOFLAGS
environment variable before running the gopls
command. Otherwise, you can configure gopls.buildFlags
or GOFLAGS
as described in the examples above.
I am facing this issue as well, appending settings.json
with "gopls.env": {
"GOFLAGS": "-tags=debug"
},
does not resolve the issue for me.
In my case I have two files thermal.go
and thermal_mock.go
, with build tags // +build !debug
and // +build debug
respectively, so I can mock target HW specific functions.
My biggest issue is that Intellisense completely stopped working in the _mock
version (as in, worked the other day, next day poof) , and the gopls.env in settings.json
didn't help either.
Go 1.15.5, gopls v0.6.0
Any follow up on the issue?
Edit: Loss of intellisense can be temporarily fixed by removing the build tag instruction, saving and readding it.
In my case I have two files
thermal.go
andthermal_mock.go
, with build tags// +build !debug
and// +build debug
respectively, so I can mock target HW specific functions.My biggest issue is that Intellisense completely stopped working in the
_mock
version (as in, worked the other day, next day poof) , and the gopls.env insettings.json
didn't help either.
Would be happy to help investigate this, but please file a new issue with the following information: https://github.com/golang/tools/blob/master/gopls/doc/troubleshooting.md.
Most helpful comment
@sjdweb current workaround I'm using is to set the GOFLAGS environment variable. This is the configuration I'm using in VS Code: