flyhigh

Home AboutRSS

go build -tagsを使ってRelease/Debugを切り替える

  • golang

Goでウェブアプリのクライアントを書いている。 ローカルでテストする場合は、サーバもローカルにたてるので、アクセスする先はlocalhostになる。 リリースするときは正しいウェブアプリのURLを指定しなければならない。 この際、切り替えはナイーブにコメントアウトで行ってきた。

const (
  // APIServer = "http://www.mywebapp.com"
  APIServer = "http://localhost:8080"
  )

当然、デバッグ用を有効にしたままリリースしてしまったり、その逆だったりと、混乱があった。 このような、デバッグ・リリースで機能を切り替えたい場合はBuild constrainsを使えば良いらしい。

Build Constrainsとは?

従来の機能が充実しているGoに抜かりはない。Build constrainsとは必要に応じてビルドするファイルを切り替える、Goの機能だ。 公式ドキュメントに紹介されている例は、アーキテクチャ毎にビルドするソースを切り替える方法だ。

ビルドするファイルを切り替える方法は以下の3つ。

1. コメントで切り替える

// +build linux

このコメント行をファイルの先頭に書いておくと、GOOS=linuxの場合のみビルドされる。i386などのGOARCHもタグとして使うことが可能だ。 ちなみに、否定は以下のように記述する。

// +build !linux

2. ファイル名で切り替える

ファイル名でもBuild constrainsが行える。以下のファイルは、GOOS=windows, GOARCH=amd64の環境でしかビルドされない。 ファイル名からビルド対象がわかるため、開発者にも優しい。ここについては、後に補足を入れた。

source_windows_amd64.go

3. build -tagsで切り替える

これはCheney氏のブログをきっかけで知ったのだが、 +buildの後に付加されるシンボルはタグと呼ばれ、go build -tags tagAのようにオプションで指定できる(らしい)。 Build constrainsがBuild tagともよばれる所以か?これを使えば以下のようにコメントされたファイルは、先のコマンドからのみビルドされることになる。

// +build tagA

build -tagsを使ってRelease/Debugを切り替える

さて、上に挙げた3番目の手法を使えば、debug/releaseのビルドを切り替えられる。没頭にあげたように、テスト時はlocalhostを。 リリース時は正しいアドレスを使いたい場合、以下のように2つのファイルを記述すればよい。

release.go

// +build !debug

package main

const APIServer = "http://localhost:8080"

debug.go

// +build debug

package main

const APIServer = "http://www.mywebapp.com"

注意すべきは、1行目のコメントに続く3行目の間に空行が必要な点だ。

そして、debug時は以下のようにビルドを行う。

go build -tags debug

まとめ

  • Build constrainsを使えばファイル単位でビルドを制御することができる
  • go build -tags tagNameで好きなタグを指定できる
  • タグは// +buildで指定する。コメントの後の空行を忘れずに。

補足1

ちなみに、手法1, 2ともに適用する必要はなく、どちらかで良い。どちらか選ぶ場合は、ファイル名で切り替えを選べば、grepなどで簡単に ビルド対象のファイルを選別できるのでおすすめだそうだ。

補足2

デフォルトで用意されているbcは、GOOSGOARCH以外に、ignoreがある。

// +build ignore

と書かれたファイルはビルドされない。 個人的にもっとわかりやすくて、よく使うのは、以下のように_でファイル名を始めることだ。

_source.go

エラーが多いファイルなどをとりあえず無視したいときに良い。

参考

go/build from Go Document

Using //+build to swtich between debug and release builds by Dave Cheney

How to properly use build tags? from Stackoverflow