regenerate cgo definitions: vscode里gopls对cgo的新支持

因为之前都是让IDE/VScode(goreturns)自动处理的import,所以今天在用vscode重新format的时候才看到,在import "C"的上面有个可以点的regenerate cgo definitions按钮。

这里就根据这个github issue来阐述一下这个按钮是干啥的,该怎么用。答案是根据reddit上这个帖子的回复找到的

解决的问题

使用了import "C"的源代码文件不是真正有效的Go。它们在严重依赖于go tool在构建软件包时所产生的额外信息。尽管可以通过设置types.Config.FakeImportC flag来解决这些问题,可以对它们进行解析,但不能进行类型检查。

许多人建议gopls使用包中的GoFiles而不是其CompiledGoFiles。
GoFiles是原始的(即无效的)文件。使用它们可能会给编辑包的人带来更好的体验,但是由于包将不再进行类型检查,因此它将完全破坏依赖于类型信息的所有内容。在当前架构中进行更改之前,我们必须非常仔细地评估效果。

我们可以考虑两次检查cgo软件包的类型,一次使用实际代码,一次使用用户的代码。那将会是一个重大的架构变化。

或者,我们可以在.go文件更改时运行cgo工具,以生成实际代码。这是一种更加可靠的方法,但是运行cgo处理的成本可能太高,尤其是在大型的包上。

无论如何,这是一个大项目,需要大量的测试和思考。我们不太可能很快在这里做出巨大的改进。

Beta测试指令

这是当前的状态:如果您使用tip Go(即gotip安装的golang, gotip是从开发分支上编译并运行go的命令)在master分支上构建gopls,那么您应该具有很好的cgo创作经验。
据我所知有一个bug在自动代码补全上,它会提供_cgo_foo之类的符号,而不是正确的C.foo。

不过,有一个障碍是,除非您告知,否则它不会重新生成cgo绑定。
为此,在使用cgo的文件中,在import "C"行的顶部应该有一个regenerate cgo的按钮。
当您引用C中的新标识符时,或使用影响Go可以看到的符号的方式更改魔术注释时,将需要使用它。

要进行设置,请按照以下说明进行操作:

1
2
3
4
5
6
7
8
9
10
$ go get golang.org/dl/gotip
$ gotip download # 安装开发版golang
[...]
Success. You may now run 'gotip'!
$ cd /
$ GO111MODULE=on gotip get golang.org/x/tools/gopls@master
$ gotip version
... devel +f7f9c8f ...
$ gotip version $(which gopls)
... devel +f7f9c8f ...

您无需使用tip Go即可在自己的项目上工作,仅需用其构建gopls。(这是2020.05.01的更新,现在2020.10.24估计是不用了)

说人话

就是,go自己读不懂cgo,要靠别的工具。但是别的工具一直调用会很浪费资源,那就让大家通过按钮手动让go通过工具读cgo。

但是看起来bug还是挺多的,所以issue也没close