$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

Goでどのパッケージが再コンパイル予定か確認する

build cacheがうまく使えているかを調べる必要があり、どのパッケージが再コンパイル予定かを確認するコマンドを調べたのでメモ。ちょっと自信がない部分もあるので間違っているところがあったら教えてください。

先に結論から言うと、go listを使った以下のコマンドで確認できる。-depsで依存関係も含めて辿り、StaleなpackageだけStaleな理由も併記して表示する。

go list -deps -f '{{if .Stale}}{{.ImportPath}}:{{.StaleReason}}{{end}}' ./...

たとえば https://github.com/golang/protobuf を使って試してみる。

go clean -cacheで全てのbuild cacheを飛ばした状態の表示。標準ライブラリなども含めて全てコンパイルする予定であることがわかる。

$ go list -deps -f '{{if .Stale}}{{.ImportPath}}:{{.StaleReason}}{{end}}' ./...
internal/goarch:build ID mismatch
internal/abi:stale dependency: internal/goarch
internal/unsafeheader:build ID mismatch
internal/cpu:build ID mismatch
internal/bytealg:stale dependency: internal/cpu
internal/coverage/rtcov:build ID mismatch
internal/godebugs:build ID mismatch
...
google.golang.org/protobuf/internal/detrand:stale dependency: internal/goarch
google.golang.org/protobuf/internal/errors:stale dependency: internal/goarch
google.golang.org/protobuf/encoding/protowire:stale dependency: internal/goarch
...

続いてgo test -list . ./...などを用いて一度色々とコンパイルを走らせた後にコマンドを実行する。ほとんどがコンパイル不要になっている。ここに出てきているのは他のパッケージから依存がなかったもので、もともとgo installを使っておく必要がなかったものに見える。厳密には次の実行で再コンパイルはしないっぽいのだが、Staleの意味がwould 'go install' do anything for this package?となっているので出てきてしまっている。

$ go list -deps -f '{{if .Stale}}{{.ImportPath}}:{{.StaleReason}}{{end}}' ./...
github.com/golang/protobuf/descriptor:build ID mismatch
github.com/golang/protobuf/internal/cmd/generate-alias:build ID mismatch
github.com/golang/protobuf/jsonpb:build ID mismatch
github.com/golang/protobuf/protoc-gen-go:build ID mismatch

続いてprotoc-gen-go/generator/generator.goを編集してからコマンドを実行する。protoc-gen-go/generatorが再コンパイルになったことで、protoc-gen-go/grpcも再コンパイルされる様子がわかる。

$ go list -deps -f '{{if .Stale}}{{.ImportPath}}:{{.StaleReason}}{{end}}' ./...
github.com/golang/protobuf/descriptor:build ID mismatch
github.com/golang/protobuf/internal/cmd/generate-alias:build ID mismatch
github.com/golang/protobuf/jsonpb:build ID mismatch
github.com/golang/protobuf/protoc-gen-go:build ID mismatch
github.com/golang/protobuf/protoc-gen-go/generator:build ID mismatch
github.com/golang/protobuf/protoc-gen-go/grpc:stale dependency: github.com/golang/protobuf/protoc-gen-go/generator

こんな感じでgo listを使うだけで、なんとなく再コンパイル予定のpackageが分かるので便利に使っています。