golangで書いたアプリケーションのstatic link化
「goで書いたアプリケーションは実行ファイルひとつコピーするだけでいいのでインスコ超ラクチン」なんて思ってたんですが、 go1.4からnetパッケージを使っているアプリケーションは、フツーにビルドするとdynamic linkになるようになってました。
$ cd /path/to/your_app $ go build $ file your_app your_app: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
そんなわけで別環境にバイナリコピーしても動かないケースが発生して超絶アタマを悩ませることになるのですが、 そんなときは以下のようにbuildすればstatic linkになってくれるようです。
$ go build -a -tags netgo -installsuffix netgo $ file your_app your_app: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
参考 https://github.com/golang/go/issues/9369
cgoを完全に使ってない場合は以下のようにcgoを無効化してビルドしてもstatic linkになります。
$ CGO_ENABLED=0 go build $ file your_app your_app: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
なお、アプリケーションやライブラリ側でcgo使ってる場合は、glibcの関係でそれでもdynamic linkになります。 でも以下のようにstatic linkするようにオプションを追加してあげればOKです。
$ go build -a -tags netgo -installsuffix netgo --ldflags '-extldflags "-static"'
# CentOSの場合、glibc-staticがインスコされてないと、ldでコケます。
build後のバイナリを配布したいとか、dockerでalpineにバイナリコピーしてイメージ作ったんだけど動かねぇ……とかっていう場合にどーぞー。