go-sqlite3 を使った Go のプログラムを Mac でクロスコンパイルして Linux や Windows に持っていくと、次のようなエラーが出て実行できませんでした。
Binary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub
そこで cgo を使った Go のプログラムを Mac でクロスコンパイルして Linux や Windows で実行できるようにした時のメモです。
Linux
musl-cross をインストール
brew install FiloSottile/musl-cross/musl-cross
ld-musl-x86_64 をスタティックリンクしてビルド
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 CC=/usr/local/bin/x86_64-linux-musl-cc go build --ldflags '-linkmode external -extldflags "-static"' -a -v hoge.go
上記の方法を使うと実行時に必要なライブラリがスタティックリンクされ、コンパイルして出力された実行ファイルを Linux にコピーするだけで実行されました。
ld-musl-x86_64 をダイナミックリンクするようにビルド
一方、次のようにすると、ライブラリが実行時に参照されるためか、実行ファイルは少し小さくなりますが、ライブラリファイルを Linux 環境に配置しておく必要がありました。
ビルド
GOOS=linux GOARCH=amd64 CGO_ENABLED=1 CC=/usr/local/bin/x86_64-linux-musl-cc go build -a -v hoge.go
ld-musl-x86_64.so を配置
scp -p /usr/local/Cellar/musl-cross/0.9.7_1/libexec/x86_64-linux-musl/lib/libc.so root@192.168.1.1:/usr/local/lib64/ld-musl-x86_64.so
ln -s /usr/local/lib64/ld-musl-x86_64.so /lib/ld-musl-x86_64.so.1
ld-musl-x86_64.so がないと、次のようなメッセージが表示され、実行できませんでした。
/lib/ld-musl-x86_64.so.1: bad ELF interpreter: そのようなファイルやディレクトリはありません
普通にビルドして実行するぶんには、スタティックリンクがおすすめかと思います。
Windows
Windows の場合は、次の手順で実行できるようになりました。
mingw をインストール
brew install mingw-w64
ビルド
GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc CGO_ENABLED=1 go build -a -v hoge.go