Skip to content

Goのバイナリが再現可能にならなくなる要因

This content is a draft and will not be included in production builds.

完全に同一なソースコードを使って、ターゲットOS(GOOS)やアーキテクチャ(GOARCH+GOARM)も同一だった場合でも、ビルド結果が変わることがある。Perfectly Reproducible, Verified Go Toolchainsによると、以下の種類が再現可能なビルドを不可能にする。

  • ビルド環境のCコンパイラやライブラリの差異
  • Goコンパイラのバージョン
  • ビルドするディレクトリ名
  • 動的リンクするライブラリのバージョン(net, os/user)
  • ホストOSのパス区切り文字
  • ビルドしたときの日時
  • パッケージングの方法
  • 最適化レベル

CコンパイラはCGO_ENABLED=0で使わないように抑制できる。 Goコンパイラはgo.modtoolchainディレクティブまたはTOOLCHAIN環境変数で切り替える。 ディレクトリ名は-trimpathオプションで消せる。 最適化レベルはAMD64ならGOAMD64環境変数で制御できる。

例えば

Terminal window
$ export GOTOOLCHAIN=go1.22.1
$ export GOOS=plan9
$ export GOARCH=amd64
$ export GOAMD64=v1
$ export CGO_ENABLED=0
$ go install -trimpath github.com/go-acme/lego/v4/cmd/lego@v4.16.1
$ sha1sum lego
ee2e9c121604c1f52cb53c0d0824288d772de1e7

setup-goでgo-version-fileすると古いバージョンが使われるなどの問題もある。