`go build` 不必要地重建

`go build` rebuilds unnecessarily

go build 和 go 运行 在我的一个小程序上非常慢(尤其是 cgo 调用)。我想去缓存二进制文件,以便它只在源更新时重建。我会使用带有 % 规则的简单 Makefile,但语言设计者声称 Go 的构建支持不需要 Makefile。

还有我忽略的其他选择吗? Go 社区是否更喜欢另一种构建系统,也许是基于哈希的构建系统来缓存和重用构建产品?

我写了一个 tool 作为副作用解决了这个问题。 go build 单独不会检查它生成的可执行文件是否已经是最新的。 go install 可以,如果您调整它以安装到您选择的位置,那么您将获得所需的结果,类似于 go build

您可以通过执行以下操作来查看您描述的行为:

$ go get -d github.com/anacrolix/missinggo/cmd/nop
$ time go run "$GOPATH"/src/github.com/anacrolix/missinggo/cmd/nop/*.go

real    0m0.176s
user    0m0.142s
sys     0m0.048s

天气暖和 运行。 go run 将在每次调用时 link,就像 go build 一样。请注意,github.com/anacrolix/missinggo/cmd/nop 是一个什么都不做的程序。

这里是调用同一个包,使用我的工具 godo:

$ time godo github.com/anacrolix/missinggo/cmd/nop

real    0m0.073s
user    0m0.029s
sys     0m0.033s

对于较大的程序,差异应该更明显。

所以总而言之,您的标准工具选项是使用 go install,或者像 godo 这样的替代方法。

go buildgo install 很快(Go 1.10,2018 年第一季度)会快得多:请参阅 this thread and this 文档草案。

The go command now maintains a cache of built packages and other small metadata (CL 68116 and CL 75473). The cache defaults to the operating system-defined user cache directory but can be moved by setting $GOCACHE.
Run "go env GOCACHE" to see the current effective setting. Right now the go command never deletes anything from the cache. If the cache gets too big, run "go clean -cache" instead of deleting the directory. That command will preserve the cache's log.txt file. In a few weeks I'll ask people to post their log.txt files to a Github issue so that we can evaluate cache size management approaches.

The main effect of the build cache is that commands like "go test" and "go build" run fast and do incremental builds always, reusing past build steps as aggressively as possible.
You do not have to use "go test -i" or "go build -i" or "go install" just to get fast incremental builds. We will not have to teach new users those workarounds anymore. Everything will just be fast.

请注意 go install 不会安装指定包的依赖项:请参阅“”。