
PostgreSQL(以降、Postgresとします)っていうデータベース管理システムがあって、使ってみたいと思ってたんですが、コンパイルエラーが色々出てきて悩んだ結果、解決しましたという話です。
前々からデータベースシステムには興味があって、触ってみたい、できればCかC++から制御できるものがあれば嬉しいと思ってたんですな。で、PostgresかMySQLを使おうと思ったんですが、どうやらシェアがMySQLの方が大きいらしく、シェアの大きいデータベース管理システムを使うのは癪だなぁと思ったので、とりあえずPostgresの方を使ってみることにしました。
PostgresにはlibpqxxというC++用のインターフェイスがあるらしく(多分、MySQLとか他のRDBMSにもあるでしょうが)、そのインターフェイスはPostgres本体とは別でインストールしなければなりません。ちなみに、C言語用のインターフェイスについてはPostgresの本体と一緒になっていますので、追加のダウンロード作業は不要です。
というわけで、よし!PostgresをC++でいじって遊んでみよー!と思っていたのですが、いざコンパイルしてみようとすると、ところどころで詰まったので、今回は詰まったこととかを書いていきます(まぁ、Postgresを使うほどプログラミングをされている方であれば、そもそもこんなことで悩まないんでしょうけども^^;)。
Postgresをインストール(というか、コンパイル)
まずは、Postgres本体のダウンロードからです。本体がPostgresのインストール方法には2種類用意されていて、インストーラを使ってインストールする方法と、ソースコードをダウンロードして自分で実行ファイルをコンパイルする方法とがあります。
今回は、最終目標が「libpqxxを使って、PostgresをC++から操作すること」なので、ファイル構成とかを把握していないとlibpqxxとの連携がやりにくいだろうって思ったので、ソースコードからコンパイルする方法を選びました。
というわけで、ソースコードの入手です。Postgresのソースコードは僕はここから入手しましたが、GitHubもあったので、こちらから入手しても問題ないかと思います。
僕はMSYS2に用意されているMINGW64を使ってコンパイルしたので、./configure、make、make installを実行して、無事にPostgres本体とlibpqを入手できました。ここでのつまずきは特にありませんでした(大ウソです。見栄を張りたかったんです。。最初、Postgresをいじろうと思ってコンパイル方法を調べてるときに、”./configure”ってなんだ?と思ってめちゃくちゃ詰まりました。Postgresのルートにあるスクリプトファイルのことかと分かってからは詰まりませんでしたけど、それが分かるまでに2週間近くかかりました)。
具体的には、カレントディレクトリをPostgresのルートディレクトリ(configureが置かれてるディレクトリ)に移動してから、まずconfigureスクリプトを実行してMakefileを作りました。次にmakeコマンドで実行ファイルのコンパイル、最後にmake installで既定のライブラリフォルダにlibpq.aなんかのライブラリファイルをコピー、既定のインクルードフォルダにlibpq-fs.h(まぁ、実際にはlibpqというフォルダの中にlibpq-fs.hがあるって構成になってたので、libpq/libpq-fs.hと書くべきなのでしょうが)をコピーしました。
最終的には、Postgres本体とライブラリファイルが生成されて、既定のライブラリフォルダにlibpq.aとかが入ってればオッケーです。
Postgres本体のインストール(というか、コンパイル)はこれで完了です。
C++用のインターフェイスをコンパイル
libpqxxはGitHubに用意されていますので、そこからソースコードを落としてきてコンパイルします。バージョン7.0.0以降はC++17がないとコンパイルできないらしいのでご注意くださいませ~。
今回僕がコンパイルしたのは、バージョン6.4.5です。7.0.0はなんとなくややこしそうに感じたので止めときましたが、基本的にはここに書いてある方法でコンパイルできるかと思います。
libpqxxのコンパイルも、基本的にはルートフォルダに移動して、./configure、make、make installを順に実行していくだけで問題ありません。ただし、ルートディレクトリ中にあるinstallというファイルと、win32ファイルの中にあるinstall.txtにいくつか注意点が書かれていますので、何か問題が起こったときはそちらを参照すると良さげです。
一応、僕のやったことをピックアップしときます。全部で2つです。広告を区切りにしてます。
まずは、win32のなかにあるcommon-sampleをコピーして、コピーしたファイルの名前をcommonに変更します。で、コピーしたcommonをテキストエディタで開いて、PGSQLSRCという変数をPostgresのソースファイルがあるフォルダに変更します。
僕の場合はC:/PostgreSQL/11_5/srcに変更しました。Visual Studioを使ってコンパイルする場合は”/”ではなく”\”で区切らないといけないらしいですが、僕はWindows上のLinuxライクな環境(MSYS2)でコンパイルするので、”/”で区切りました。
そして、同じcommonファイルの45行目から50行目に
LIBPQPATH=$(PGSQLSRC)\interfaces\libpq\Release
LIBPQDLL=libpq.dll
LIBPQLIB=libpqdll.lib
#LIBPQPATH=$(PGSQLSRC)\lib
#LIBPQDLL=libpq.dll
#LIBPQLIB=libpq.lib
というのがあって、64行目から71行目に
LIBPQDPATH=$(PGSQLSRC)\interfaces\libpq\Debug
LIBPQDDLL=libpqd.dll
LIBPQDLIB=libpqddll.lib
#LIBPQDPATH=$(PGSQLSRC)\lib
#LIBPQDDLL=libpq.dll
#LIBPQDLIB=libpq.lib
というのがあるので、ここを編集します。Postgresをインストーラを使ってインストールした場合はそれぞれ上3行をコメントアウト(行頭に#を付ける)して、下3行のコメントアウトを外せばいいらしいです(僕はインストーラを使わなかったので、実際のところは分かりませんが)。
インストーラを使わなかった場合は、それぞれのLIBPQPATHの最後に付けられている/RELEASEと/DEBUGを削除するだけで構いません。最終的に45行目から50行目は、
LIBPQPATH=$(PGSQLSRC)/interfaces/libpq
LIBPQDLL=libpq.dll
LIBPQLIB=libpqdll.lib
#LIBPQPATH=$(PGSQLSRC)/lib
#LIBPQDLL=libpq.dll
#LIBPQLIB=libpq.lib
として、64行目から71行目までは
LIBPQDPATH=$(PGSQLSRC)/interfaces/libpq
LIBPQDDLL=libpqd.dll
LIBPQDLIB=libpqddll.lib
#LIBPQDPATH=$(PGSQLSRC)/lib
#LIBPQDDLL=libpq.dll
#LIBPQDLIB=libpq.lib
としました。
commonの作成と編集が終わったら、次はconfigファイルをinclude/pqxxにコピーします。
config/sample-headers/compilerというところに、gcc-[バージョン]というフォルダとVisualStudio[バージョン]というフォルダがあるかと思いますが、自分の使っているコンパイラに近い方のフォルダの中にあるヘッダファイルをコピーします(gcc-[バージョン]の中にpqxxというフォルダがあって、その中にヘッダファイルがあります)。
僕の場合であれば、使っているコンパイラがgcc9.2.0だったので、gcc-7.2/pqxxの中にある2つヘッダファイルをコピーしました。
ここまでで準備完了です。あとは、libpqxxのルートディレクトリにあるconfigureスクリプトの実行(つまり、./configure)、makeコマンドの実行、make installの実行という3つの手順で、コンパイラのライブラリフォルダにはlibpqxx.aのようなライブラリファイルが、コンパイラのインクルードフォルダにはpqxxというフォルダが作成されているかと思います。
下のような感じで、MSYS2のコマンドラインで”pkg-config –libs libpq”と打ち込んで実行すると”-lpq”みたいに表示されて、”pkg-config –libs libpqxx”と打ち込んで実行すると”-LC:/msys64/mingw64/lib -lpqxx”みたいに表示されるかと思います。環境によって違う表示がされることもあると思いますが、だいたいこんな感じで表示されるかと思います。
$ pkg-config --libs libpq
-lpq
$ pkg-config --libs libpqxx
-LC:/msys64/mingw64/lib -lpqxx
というわけで、PostgresをC++からlibpqxxを使って操作するための準備は出来ました。
と、書いていると長くなりすぎたので、プログラムをコンパイルするときの注意点とか詰まったことなんかをまた今度書きます。
さぁて、Postgresを使ってくだらん遊びをやってくぞ~。