Goプログラムのサイズを小さくする
Goで作られるプログラムサイズはそこそこ大きい。配布する場合はやはり小さい方が良い。 そんなときは、リンカの設定を利用するといいようだ。
go build -ldflags '-s -w'
Linuxならバイナリサイズが小さくなるはずだ。拙作、comstockでは8MiBから5.2MiBに縮んだ。
何をやっているか?
-ldflagsは、gccなどを使ったことある方はよくご存知だろうが、ldへの引数である。
ldとはgccが使うリンカであり、Goもリンカを持っている。Goのリンカは、例えば、go tool 6l(番号はアーキテクチャ依存)から呼び出せる。伝統的にリンカへのフラグは
LDFLAGSであるので、goでは小文字で指定するようになってる。
go buildはリンカへの引数を-ldflagsの後で文字列として渡すことができる。
指定できるリンカフラグは様々で、標準ドキュメントよりもgo 1.4では数が増えているように見える。とりあえず、上で使ったのは以下の2つだ。
-s disable symbol table
-w disable DWARF generation
シンボルテーブルは、シンボルと、シンボルの位置(アドレス)が記述された表である。
➜ nm `which comstock-cli` | grep Log | grep Printf
000000000007d8c0 t log.(*Logger).Printf
例えば、上はLogger.Printf()の位置を示している。
このシンボルテーブルは外部から参照することがない限り、
不必要だ。
よって、-sを渡して削る。
ちなみに、ビルドしてるのがライブラリだったり、ビルド後に
デバッガを使う場合は、シンボルテーブルは必要になるので、削ってはいけない。
DWARFというのは、Linuxの実行可能形式であるELFに付属する
デバッグ情報である。
こちらも配布用のプログラムには必要無い。よって-wで削る。
こちらはデバッグしない限り、ライブラリでも削って良い。
darwinではELFではなくMach-Oという実行可能形式を用いるため、DWARFはそもそも生成されない。
シンボルテーブルは削れると思うが、私の環境では削れてなかった。
とりあえずLinuxで縮んだので良しとする。
参考
Golang application auto build versioning ※直接関係ないが、ldflag利用の一例。
« Mac OSXで、IntelliJをJDK1.7で動かす
recoverでGoのテストのスタックトレースを省略する »