Closed stamblerre closed 8 months ago
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.
$ 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.
Note for VSCode settings.json in case it's helpful. A bit after upgrading gopls
to 0.6.2 I noticed some No packages found for open file...
errors. I was using GOFLAGS
to list build tags.
"gopls": {
"env": {
"GOFLAGS": "-tags=<tag1>,<tag2>"
},
},
Switching to the go.buildFlags
configuration below seemed to solve the problem. I no longer use GOFLAGS
.
go.buildFlags: "<tag1>,<tag2>",
There might have also been a vscode-go release around the time I bumped my gopls
version, but not sure.
The workarounds here didn't work for me.
I found env GOOS="openbsd" code
Worked for me at the editor instance level
P.s. Irrelevant tip: if you also set HISTFILE and open a module folder after "code" then you can have dedicated terminal history and a project folder opened together.
Hello,
I'm facing this issue on linux using emacs. Have tried suggestions above and the one that is working is to delete and re-adding build tag line. I also tried using VS Code with the same result.
I was finally able to get this working in VS Code by using the following and restarting VS Code.
{
"go.buildTags": "tag1,tag2"
}
I think gopls shouldn't care about build constraints, or it only cares about the file I'm editing, which I call "constraint aware".
This and #49657 were the only relevant results for my internet searches, so, for historical reasons, my solution for emacs
is to use setenv
at the global scope and modify GOFLAGS
. This isn't perfect but has worked for me:
(setenv "GOFLAGS" "-tags=linux,windows")
Is there a plan to make something like this a permanent in gopls
? Is there some problem with just specifying multiple platform tags by default? It hasn't seemed to cause any problems for me specifically. It doesn't make much sense to me that gopls
would care about the platform, and simply failing for platform-tagged files breaks the entire workflow of developing cross-platform applications. This is almost certainly an undocumented bug in gopls
, unless I missed some documentation some where (which I'd be happy if someone shared :smile:).
@calebstewart That's insteresting. gopls
heavily depends on go list
and other go
commands to parse go code, and by your setting -tags=linux,windows
, the flag is passed to all the go commands gopls
uses. If you see gopls
and so go
commands work with -tags=linux,windows
, that's by accident, not intentional.
And, more puzzling thing is that AFAIK platform (os/arch) are special and go commands select them based on GOOS
/GOARCH
environment variables, not based on the -tags
flag in most cases. So, I am not sure what's working and what's not working with specifying OSes using -tags
.
for vscode users, update your PROJECT_ROOT/.vscode/settings.json
like below may resolve this problem:
{
"go.toolsEnvVars": {
"GOOS": "js",
"GOARCH": "wasm"
}
}
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.