概要
前回、git でビルド番号とかを取得する記事を書いたのでついでに。
Go では、ビルド時に -ldflags
オプションをつかって、プログラム内の変数に値を埋め込むことが出来ます。
以下のような形でコマンド実行します。
$ go build -ldflags "-X main.xx=埋め込みたい値"
値が複数ある場合は、-X
を複数つけます。
$ go build -ldflags "-X main.xx1=埋め込みたい値 -X main.xx2=埋め込みたい値"
最近、こういう作業は goreleaser などを利用するのが多いと思いますが、
自分で作ったちょっとしたツールなどでは goreleaser 使うまでもないものが結構あります。
そういうときに自前でバージョン情報とかを埋め込む方法しっておくと便利かもしれません。
git からビルド番号などを取得して go のビルド時に埋め込む
以下のようにコマンドを実行します。
$ go build -race -ldflags \ " \ -X main.version=$(git describe --tag --abbrev=0) \ -X main.revision=$(git rev-list -1 HEAD) \ -X main.build=$(git describe --tags) \ "
予め、mainパッケージに 変数 を定義しておく必要はあります。
サンプル
以下のような プログラム があるとします。
/* go build 時に -ldflags を指定して内部の変数に外部から値を注入するサンプルです. 例: $ go build -race -ldflags \ " \ -X main.version=$(git describe --tag --abbrev=0) \ -X main.revision=$(git rev-list -1 HEAD) \ -X main.build=$(git describe --tags) \ " $ go run -race -ldflags \ " \ -X main.version=$(git describe --tag --abbrev=0) \ -X main.revision=$(git rev-list -1 HEAD) \ -X main.build=$(git describe --tags) \ " . */ package main import ( "fmt" "os" ) // Version and Revision // // REFERENCES: // - https://blog.alexellis.io/inject-build-time-vars-golang/ // - https://christina04.hatenablog.com/entry/2016/12/08/101114 // - https://stackoverflow.com/questions/1404796/how-to-get-the-latest-tag-name-in-current-branch-in-git // - https://stackoverflow.com/a/7261049 // - https://git-scm.com/book/ja/v2/Appendix-C%3A-Git%E3%81%AE%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89-%E6%A4%9C%E6%9F%BB%E3%81%A8%E6%AF%94%E8%BC%83 // - https://git-scm.com/book/ja/v2/Git-%E3%81%A7%E3%81%AE%E5%88%86%E6%95%A3%E4%BD%9C%E6%A5%AD-%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E9%81%8B%E5%96%B6#r_build_number // var ( version string revision string build string ) func main() { os.Exit(run()) } func run() int { fmt.Printf("Version : %s\n", version) fmt.Printf("Revision: %s\n", revision) fmt.Printf("Build : %s\n", build) return 0 }
以下のようにしてビルドします。
$ go build -race -ldflags \ " \ -X main.version=$(git describe --tag --abbrev=0) \ -X main.revision=$(git rev-list -1 HEAD) \ -X main.build=$(git describe --tags) \ "
実行すると以下のようになります。
$ ./with_ldflags Version : v0.2.3 Revision: 241add946ebe947458cc6ef03fefbdc292a8e941 Build : v0.2.3-77-g241add9
ついでに、Makefile に書いたものもメモ
ldflags_example: @echo '--- go build with -ldflags ---' cd ./cmd/version_and_revision/with_ldflags \ && $(GOBUILD) -race -ldflags \ " \ -X main.version=$(shell git describe --tag --abbrev=0) \ -X main.revision=$(shell git rev-list -1 HEAD) \ -X main.build=$(shell git describe --tags) \ " @cd ./cmd/version_and_revision/with_ldflags && ./with_ldflags @cd ./cmd/version_and_revision/with_ldflags && go clean @echo '' @echo '--- go run with -ldflags ---' cd ./cmd/version_and_revision/with_ldflags \ && $(GORUN) -race -ldflags \ " \ -X main.version=$(shell git describe --tag --abbrev=0) \ -X main.revision=$(shell git rev-list -1 HEAD) \ -X main.build=$(shell git describe --tags) \ " . @echo ''
実行すると以下のようになります。
gitpod /workspace/try-golang $ make ldflags_example --- go build with -ldflags --- cd ./cmd/version_and_revision/with_ldflags \ && go build -race -ldflags \ " \ -X main.version=v0.2.3 \ -X main.revision=241add946ebe947458cc6ef03fefbdc292a8e941 \ -X main.build=v0.2.3-77-g241add9 \ " Version : v0.2.3 Revision: 241add946ebe947458cc6ef03fefbdc292a8e941 Build : v0.2.3-77-g241add9 --- go run with -ldflags --- cd ./cmd/version_and_revision/with_ldflags \ && go run -race -ldflags \ " \ -X main.version=v0.2.3 \ -X main.revision=241add946ebe947458cc6ef03fefbdc292a8e941 \ -X main.build=v0.2.3-77-g241add9 \ " . Version : v0.2.3 Revision: 241add946ebe947458cc6ef03fefbdc292a8e941 Build : v0.2.3-77-g241add9
参考情報
過去の記事については、以下のページからご参照下さい。
- いろいろ備忘録日記まとめ
サンプルコードは、以下の場所で公開しています。
- いろいろ備忘録日記サンプルソース置き場