Description
What version of Go are you using (go version
)?
$ go version go version go1.21.0 darwin/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env
)?
go env
Output
$ go env
What did you do?
Gopls underlying calls go list
with -compiled=true
flag to get CompiledGoFiles
field, which contains original go source file in a package, and also cgo-generated go source files. That's enough for gopls to working, but the go list
command will
also compile c/c++ files to object files, this is totally redundant for gopls.
My work heavily relies on cgo, when loading workspace or doing some changes that affects the cgo package in vscode, the edtor becomes very slow and cpu usage goes 100% because of the compilation of c/c++ files, especially when the codebase is very large, as i described in #50151 years ago.
I have do some experiments in cmd/go source code by skip the compilation of c/c++ code by wrapping these code in the if statement:
if !b.IsCmdList {
// .......
}
go/src/cmd/go/internal/work/exec.go
Lines 3319 to 3401 in 1f8f2ab
Gopls works fine after recompiled the go command, it seems nothing broken. I'm not sure whether this change will break go build cache or not.
There is also another solution, gopls could call go list
with -compiled=false
and generate CompiledGoFiles
by calling cgo command by itself, but it requires gopls to parse the go source files to get C include paths and pass it to cgo command.
I think it worth a change in go toolchain for go list
and go vet
, it improves dev experience very much, i don't see any necessaries to compile c/c++ file to objects in these two cases, not only for gopls, but also other tools that uses go list
, of course we could introduce some new env/flag to keep backward compatibility if need.