やろうとしたこと
GolangのスクリプトをAmazon Linux上で動すためにクロスコンパイルをしようとした
起きたこと
Mac向けにビルドすると普通にビルドできて動くが、linux向けにビルドするとエラーに。
linux向けのクロスコンパイルの設定が間違っているのかと思って調べたら違い、どうもsqlite3のみで起きていそう。
MacOS向けは上手くいく
使用したコマンド
$ GOOS=darwin GOARCH=amd64 go build -o main_for_mac ./main.go
ビルドに成功し、動作も正常だった。
linuxはsqlite3でundefinedが出る
使用したコマンド
$ GOOS=linux GOARCH=amd64 go build -o main_for_linux ./main.go
出たエラー
# github.com/dinedal/textql/storage
../{中略}/.go/pkg/mod/github.com/dinedal/textql{中略}/sqlite.go:30:28: undefined: sqlite3.SQLiteConn
../{中略}/.go/pkg/mod/github.com/dinedal/textql{中略}/sqlite.go:49:4: undefined: sqlite3.SQLiteDriver
...
調べて分かったこと:
go-sqlite3を使っているMacユーザーがたくさんはまっていた。
該当のissues
https://github.com/mattn/go-sqlite3/issues/384
原因はC言語のクロスコンパイルにおいては実行環境がOS依存であることだった。
sqliteの実装においてえ使用されている模様。
Cross-compiling C code (and by extension, cgo code) is tricky because the choice of C compiler depends on both the OS (Windows/Linux/Mac) and architecture (x86, x64, arm) of both the host and target. On top of that, there are multiple flavors of compilers for a given combination. I don't think listing all of them is feasible. But I do think it would be helpful to more thoroughly explain what a cross-compiler is and why it is needed, and list out some of the more common options. It would also be helpful to mention using docker as a means of "cross-compiling" (at least when targeting Linux)
解決した方法
MacにおけるC言語のコンパイル環境に問題があるので gcc-4.8.1-for-linux32-linux64 をインストールすることで解決する。
手順
Mac用のgccをインストール
gcc-4.8.1-for-linux32-linux64 をダウンロードしてインストール。
オプションをつけて実行
実行するコマンドは以下
build as usual env GOOS=linux GOARCH=amd64 CGO_ENABLED=1 CC=/usr/local/gcc-4.8.1-for-linux64/bin/x86_64-pc-linux-gcc go build
参考
多くの人が上記issueで問題にぶつかっていたため、親切な方が手順を別のissueにまとめてくれていた。
install [http://crossgcc.rts-software.org/download/gcc-4.8.1-for-linux32-linux64/gcc-4.8.1-for-linux64.dmg]gcc-4.8.1-for-linux32-linux64
build as usual env GOOS=linux GOARCH=amd64 CGO_ENABLED=1 CC=/usr/local/gcc-4.8.1-for-linux64/bin/x86_64-pc-linux-gcc go build
該当のissue
https://github.com/mattn/go-sqlite3/issues/797