【问题标题】:`go build` rebuilds unnecessarily`go build` 不必要地重建
【发布时间】:2015-11-10 18:15:33
【问题描述】:

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

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

【问题讨论】:

  • go install 和/或go build -i;他们将安装依赖包,除非更改,否则将来不会重建这些包。一个普通的go build 将重建更改的依赖包,但不会保存结果。
  • 这正是go install 的用途。
  • go build -x 告诉我时间花在重建小程序上。依赖项缓存好了。
  • go install 没有参数有效,谢谢! (但不是build -i)。此时我正在研究go list 格式、makedepends 和持续构建。
  • 查看What does go build build?的答案

标签: go build


【解决方案1】:

go buildgo install 很快(Go 1.10,2018 年第一季度)将更快:请参阅 this threadthis 草案文档。

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 不会安装指定包的依赖项:请参阅“What does go build build?”。

【讨论】:

    【解决方案2】:

    我写了一个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 将链接到每个调用,就像 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 这样的替代方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多