`go build` 重新构建了不必要的内容。

huangapple go评论78阅读模式
英文:

`go build` rebuilds unnecessarily

问题

go build和go run在我拥有的一个小程序上非常慢(特别是cgo调用)。我希望go可以缓存二进制文件,只有在源代码更新时才重新构建。我可以使用一个简单的Makefile和一个%规则,但是语言设计者声称go的构建支持不需要Makefile。

我是否忽视了其他的选择?go社区是否更喜欢另一种构建系统,比如基于哈希的系统,用于缓存和重用构建产物?

英文:

go build and go run are very slow on a tiny program I have (cgo invocations in particular). I'd like go to cache the binary so that it only rebuilds when the source is newer. I would use a simple Makefile with a % rule, but the language designers claim that go's build support doesn't need Makefiles.

Is there another alternative I've overlooked? Does the go community prefer another build system, maybe hash-based instead, for caching and reusing build products?

答案1

得分: 7

go buildgo install将很快(Go 1.10,2018年第一季度)变得更快:请参阅此线程草案文档。

go命令现在维护一个构建包和其他小型元数据的缓存(CL 68116CL 75473)。缓存默认为操作系统定义的用户缓存目录,但可以通过设置$GOCACHE来移动。
运行"go env GOCACHE"以查看当前的有效设置。现在,go命令从不从缓存中删除任何内容。如果缓存变得太大,请运行"go clean -cache"而不是删除目录。该命令将保留缓存的log.txt文件。几周后,我将要求人们将他们的log.txt文件发布到Github问题中,以便我们可以评估缓存大小管理方法。

构建缓存的主要效果是,像"go test"和"go build"这样的命令运行快速,并始终进行增量构建,尽可能地重用过去的构建步骤。
您不必使用"go test -i"或"go build -i"或"go install"来获得快速的增量构建。我们将不再需要教新用户这些变通方法。一切都将变得快速。

请注意,go install不会安装指定包的依赖项:请参阅"go build构建了什么?"。

英文:

go build and go install will soon (Go 1.10, Q1 2018) be much faster: see this thread and this draft document.

> 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.

Note that go install won't installs dependencies of the named packages: see "What does go build build?".

答案2

得分: 1

我写了一个工具,恰好可以作为副作用解决这个问题。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每次调用都会进行链接,就像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的替代工具作为标准工具选项。

英文:

I wrote a tool that happens to solve this as a side effect. go build alone will not check if the executable it's producing is already up to date. go install does, and if you tweak it to install to a location of your choice, then you'll get the desired result, similar to go build.

You can see the behaviour you describe by doing something like this:

$ 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

That's on a warm run. go run will link on every invocation, just as go build would. Note that github.com/anacrolix/missinggo/cmd/nop is an program that does absolutely nothing.

Here's invoking the same package, using my tool, godo:

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

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

For larger programs, the difference should be more pronounced.

So in summary, your standard tooling option is to use go install, or an alternative like godo.

huangapple
  • 本文由 发表于 2015年8月18日 08:26:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/32061750.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定