Goで多数実行ファイルでディスク使用量を削減する


はじめに

ここの内容は基本Linux専用の話です!
RaspberryPiなどへの組み込みでディスク使用量が問題な場合などに使えるTipsのご紹介。

Goランタイムのダイナミックリンクファイルをインストール

goの実行環境を整えたら以下のコマンドを実行しよう。

> go install -buildmode=shared std

すると、/usr/lib/go/pkg/linux_<arch>_dynlink/libstd.soというファイルが作られます。

実行ファイルのビルド方法

> mkdir sample
> cd sample
> go mod init sample

sample/main.go

package main

import (
	"fmt"
)

func main() {
	fmt.Println("Hello World!")
}

ビルド

> go build -linkshared .

結果

dockerのalpine:edge環境での結果。

ダイナミックリンク依存の様子

> ldd sample
	/lib/ld-musl-x86_64.so.1 (0x7f95d85d6000)
	libstd.so => /usr/lib/go/pkg/linux_amd64_dynlink//libstd.so (0x7f95d5e39000)
	libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f95d85d6000)

作られたsample実行ファイルのサイズは?

> ls -lh sample
-rwxr-xr-x    1 root     root       19.9K Mar 31 02:37 sample

20KBを切りました!

普通にビルドすると?

> go build .
> ls -lh sample
-rwxr-xr-x    1 root     root        1.7M Mar 31 02:49 sample

1.7MBだったものが20KBになるということですね!

まとめ

  • 標準のビルド方法の場合、組み込み関数しか使わない状態でも1MB程度、fmtパッケージをがっつり使った時点で数MBくらい膨れる
  • 今回のやり方だと自分の書いたコードや標準以外のライブラリコードのみのサイズになる
  • 多数の実行ファイルをRaspberryPiなどに入れる予定がある場合などに有効
  • libstd.soファイルが実は35MBほどある
  • コンパイル時間は標準よりちょっと遅くなる