Windowsでmatn/go-oci8を使おうとしてとても苦労している話
0. 唐突にOracle Databaseを使おうと思い立った
Oracle Databaseを使ったシステムなど、お仕事くらいでしか使うことはなかったんだけど、Oracle Cloud Free Tierとして使えるDBのPaaSがOracle Databaseだけ、というので、かなり仕方なく使う、というネガティブな話だったりする。
Javaや.NETには公式のデータベースドライバが出ているので、それらを使えば簡単にDBを利用できるけど、せっかくなので今回はGoでやってみることにした。
なお、結論から書くとこの話、実現できてないorz
1. 環境
ビルドには以下が必要。
- C/C++コンパイラ
- pkg-config
- プラットフォームとバージョンに応じたOracle InstantClient
このほか、当然のことながらGitやGoが必要。
1-1. MSYS2
僕のWindows PC(Windows 10 pro version 1909)にはSphinxでPDFをビルドするため、MSYS由来のGNU Makeとshが入っていたので、GCCを入れるためpacmanを起動。
しかしながら、なぜか何もフィードバックを出さずpacmanが途中で終了してしまい、パッケージのインストールもアップデートもできずハマる。
おかしい、version 1809のころはふつうにpacmanが動いていたはずなのに。
これでは何もできないので、MSYS2はあきらめることに。
1-2. Cygwin
ならば、ということでMSYS2をアンインストールしてCygwin x64を入れてみた。
Baseパッケージグループのほか、makeやGCCをCygwin Installerで一とおりインストールし、C:\cygwin64\binなどをWindowsのPath環境変数に追加していった。
Cygwin shellではなくDOS窓からgo get github.com/mattn/go-oci8
とやったところ、
# runtime/cgo
gcc_libinit_windows.c: 関数 ‘x_cgo_sys_thread_create’ 内:
gcc_libinit_windows.c:57:12: エラー: implicit declaration of function ‘_beginthread’; did you mean ‘OpenThread’? [-Werror=implicit-function-declaration]
thandle = _beginthread(func, 0, arg);
^~~~~~~~~~~~
OpenThread
cc1: all warnings being treated as errors
go: failed to remove work dir: GetFileInformationByHandle C:\cygwin64\tmp\go-build601027150\NUL: Incorrect function.
と出てビルドできず。後でググると本体のGitHub WikiのInstallFromSourceに
Go does not support the Cygwin toolchain.
などど書かれていた。なん....だと....?
1-3. WSL
最近のエディションにはWSL(Windows Subsystem for Linux)という、読んで字のごとくLinux互換環境を提供するサブシステムが標準搭載されている。デーモンを常駐させられない以外はほぼLinuxそのままなので、こいつで頑張ってみることに。
僕は普段UbuntuのWSLを使っているけど、GCCもpkg-configもapt install
で導入できるのでお手軽だ。
ということでapt install
でGCCやらpkg-configやらをインストールしてgo get
してみる。
結果、エラー表示は出ず。
いけた、のか? ということで付属のexampleで動作確認。
$ cd $GOPATH/src/github.com/mattn/go-oci8/_example/nls
$ GO_OCI8_CONNECT_STRING=system/Orcl19cAdmin@//localhost:1521/ORCLCDB go run main.go
ORA-12571: TNS:packet writer failure
パケット到達不能、だと....? まぁ、Oracle Databaseは親環境のDockerで動かしているとはいえ、WSLからDockerを制御できているので、親環境とは通信できているはずだが。
てなわけで、この方法もダメということに。
1-4. TDM-GCC
Goの公式としてはTDM-GCCを推奨しているようなので、Cygwin GCCをアンインストールしてこちらに切り替えてみた。
パッケージマネージャは付属していないので、pkg-configを自力でセットアップしなければならない。やり方自体はStackOverflowの記事を参考にやってみた。
一応、直リンクを置いておく。
- http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/pkg-config_0.23-2_win64.zip
- http://ftp.gnome.org/pub/gnome/binaries/win64/dependencies/gettext-runtime_0.18.1.1-2_win64.zip
- http://ftp.gnome.org/pub/gnome/binaries/win64/glib/2.26/glib_2.26.1-1_win64.zip
準備自体はGistを残してくれている方がいたので、それを使わせてもらうことに。
> go get github.com/mattn/go-oci8
# pkg-config --cflags -- oci8
pkg-config: exit status 3221225595
3221225595をWindowsの電卓に通すと0xC000007Bになるのだが、pkg-configが正常起動できていない、ということのようだ。どうやらABIが違うようなので、win64ではなくwin32に変えることで正常起動するようになった。
で、再挑戦。
> go get github.com/mattn/go-oci8
# github.com/mattn/go-oci8
In file included from GOPATH\src\github.com\mattn\go-oci8\cHelpers.go:3:0:
./oci8.go.h:1:17: fatal error: oci.h: No such file or directory
compilation terminated.
....pkg-configがインクルードパスを正常に処理できていないようだ。もちろん、oci.h
の場所は-Iオプションの行で指定しているんだが。
おわりに
最後のTDM-GCCパターンではあと一歩なような気もする。
そんな気はするんだが、MySQLやPostgreSQLのドライバだったり、GoではなくJavaを選択していた場合だと、もっと簡単にデータアクセスを実装できていたであろう、と考えると、「なぜ僕はこんな苦行を....?」などと考えてしまう。
最近のコメント