TIG DX ユニットの多賀です。 Go 1.18連載 の最後6本目です。
最近業務で久々に Go を触ることになりそうで、少し思い出しながらコードを実装してみたりしてます。
TL;DR
- Go 1.18 から build 時に含まれるメタデータに VCS, ビルド情報が追加
- メタデータを参照可能な実装が
debug/buildinfo
パッケージとして公開
Go 1.18 アップデート概要
Go 1.18 ではビルドして生成される実行ファイル中のメタデータに関連して、2点アップデートが入っています。
1点目は、メタデータの追加です。Go のビルドした実行ファイルには、Go 1.17 以前からメタデータとしてコンパイルした Go のバージョンや、依存 module の情報が含まれていました。 Go 1.18 からは、元々の情報に加えて Git の commit id や commit した時刻等の VCS 情報と、build したアーキテクチャやOS等のビルド情報が追加されました。
2 点目は、実行ファイルのメタデータをパッケージを通して参照できるようになったことです。
Go 1.17 以前は、実行ファイルのメタデータを外部から取得するためには、 go version -m ${実行ファイル}
コマンドを実行するしか方法がありませんでした(※1)。 go version コマンドの実装を利用しようにも、 internal
パッケージ下に含まれてしまい、外部から利用することはできず、コードをコピーして実装したりする状況が生まれていました。
そのため、Go 1.18 にて go version の実装を移植した外部利用可能な debug/buildinfo パッケージが追加されました。
※1: 正確には runtime/debug.BuildInfo を利用すれば、実装したコード自身のメタデータへアクセスすることはできました。 BuildInfo
をコンパイルコード内で取得、Print しておけば実行時に出力できたりします。
アップデート詳細
Go 1.18 はまだリリース前なので、ベータバージョン(go1.18beta2
)で動作確認してます。
正式リリース時に挙動が変更されている可能性がありますので、ご注意ください。
メタデータ追加
追加されるメタデータを、各バージョンの出力を参考に比較してみます。build
項目以下が、 Go 1.18 で追加予定です。
Go 1.17.6
❯ go version -m 1.17.6 |
Go 1.18beta2
❯ go1.18beta2 version -m 1.18beta2 |
よく使いそうな項目について補足します。
GOARCH
/GOOS
- コンパイル後にbuild した アーキテクチャと OS を見ることができるようになります
vcs.revision
/vcs.time
- (Gitの場合) build したタイミングの commit id と時刻を保持します
vcs.modified
- (Gitの場合) build したタイミングに、commit していない変更が残されている場合に
true
となり、変更漏れがないか確認できます
- (Gitの場合) build したタイミングに、commit していない変更が残されている場合に
debug/buildinfo
実行ファイルからメタデータを読み取れる、debug/buildinfo パッケージが追加されました。
ドキュメントを見ると、API としては以下が定義されています。実行ファイルを io.ReaderAt
か ファイルから読み込む実装だけですね。
type BuildInfo |
読み込んだ返却値である BuildInfo
型は、 runtime/debug.BuildInfo の型エイリアスになっています。 Go 1.18 でメタデータが追加されているため、 runtime/debug.BuildInfo の定義も以下の通りアップデートされています。
Go 1.17.6
type BuildInfo struct { |
Go 1.18beta2
type BuildInfo struct { |
試しに実行ファイルを読み込んだコードを動かしてみます。 BuildInfo
を JSON にして中身も確認してみます。
package main |
出力はこちらになりました。 Go 1.18 で追加予定の項目は Settings
へ詰め込まれるようです。
{ |
関連 issue
- build 時に含まれるメタデータを追加したい要望
go version -m
の実装コード version.go が internal package のため、外部から利用できるようにしたい
関連 パッチ
- build 時の挙動変更
- debug/buildinfo 追加
所感
Go 1.18 で変更される実行ファイルに含まれるメタデータ関連について、整理してみました。
Git の commit id が参照できるようになるのも良いですが、 GOOS
/ GOARCH
を見ることができるようになったのも良さそうです。 複数環境向けの build 後に、どの実行ファイルがどの環境向けかわからなくなっても確認するのに使えそうです。 (わからなくなったときは、とりあえず実行してみて確認したりしてました)debug/buildinfo
パッケージの登場により、実行されているバイナリをスキャンしてツールへ連携する実装がやりやすくなったのも良さそうですね。
Go 1.18 連載は以上で終了です。
一般的に待望されていたジェネリクスや、コードの安全性を高める fuzzing にサポートしたりと盛り沢山なリリースだったかと思います。リリースは 3 月にずれ込みそうとのことですが、それまでのつなぎとして楽しんでいただけていたら幸いです。