いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

Goメモ-134 (go build 時にバージョン情報などを埋め込み)(ldflags, -X)

概要

前回、git でビルド番号とかを取得する記事を書いたのでついでに。

devlights.hatenablog.com

Go では、ビルド時に -ldflags オプションをつかって、プログラム内の変数に値を埋め込むことが出来ます。

以下のような形でコマンド実行します。

$ go build -ldflags "-X main.xx=埋め込みたい値"

値が複数ある場合は、-X を複数つけます。

$ go build -ldflags "-X main.xx1=埋め込みたい値 -X main.xx2=埋め込みたい値"

最近、こういう作業は goreleaser などを利用するのが多いと思いますが、

github.com

自分で作ったちょっとしたツールなどでは 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

参考情報

blog.alexellis.io

christina04.hatenablog.com


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com