読者です 読者をやめる 読者になる 読者になる

libpqxxがビルド出来ない時 VC++2010によるlibpqxxのビルド方法

 

環境

  • Windows7 64bit
  • Visual C++ 2010
  • PostgreSQL9.1.1 32bit
  • libpqxx4.0.1

成果物

  • VC++2010用32bit版libpqxxライブラリ群
    • libpqxxはlibpqC++ラッパーである。これを使わない場合、使いづらいC言語インターフェイスPostgreSQLに対する操作を記述することになるので、最新版PostgreSQLを使えなくてもいい場合などには導入したほうがいいだろう。

libpqxx4.0.1をPostgreSQL9.3付属のライブラリを用いてビルドしようとしたところエラーを吐くので、INSTALL.txtを見てみると、PostgreSQL9.1.1ぐらいまでしか対応してなさそうな記述があったため、9.1.1のPostgreSQLインストーラーからインストールしなおしてビルド。nmakeでビルドする際に必要な手順は以下。展開したソースディレクトリをlibpqxxとして記述する。

 下記手順は、ソースファイルに付属しているINSTALL.txtの流れで、必要だったものだけを抽出してある。必要に応じてINSTALL.txtを読むべし。

1.nmake前の設定とnmakeによるビルド

  • libpqxx/win32/common-sampleをlibpqxx/win32/commonとして複製。
  • commonの内容の下記部分を、説明にしたがってコメントアウト又は、アンコメントする。下記の様になる。具体的には、PGSQLSRC環境変数に絡む部分を、WindowsインストーラーでPostgreSQLをインストールした場合に変更していく。ごちゃごちゃ書いてあるが難しい作業ではなく、上に書いたように、ほぼコメントとアンコメント作業である。インストールディレクトリが変わった場所にあると手動で書き換える必要があるかも。

# Depending on your STL library min/max need to be defined. Using STLport

# there is no need for libpqxx to redefine these for me.

# The next line gives us the directory under which all PostgreSQL include

# directories, DLLs and LIB files can be found.

#

# If you built PostgreSQL from source, this is probably the only line you

# will need to change.

#

# If you installed PostgreSQL using the One Click Installer from EnterpriseDB,

# comment out the following line and uncomment the line after it.

#

# Edit the appropriate line to match your specific installation.

#PGSQLSRC="E:\dev\lib\libpqxx-4.0.1"

PGSQLSRC="C:\Program Files (x86)\PostgreSQL\9.1"

# This is the directory where the Postgres header files, e.g. postgres_ext.h,

# are found.

PGSQLINC=$(PGSQLSRC)\include

# This is the directory where the libpq header files, e.g. libpq-fe.h,

# are found. If you used the One Click Installer, comment out the next line

# and uncomment the one following it:

#LIBPQINC=$(PGSQLSRC)\interfaces\libpq

LIBPQINC=$(PGSQLSRC)\include

# This is the directory where the release build of the libpq DLL

# and its corresponding LIB file are found, as well as the names of

# those two files.

#

# If you installed PostgreSQL using the One Click Installer from EnterpriseDB,

# comment out the next three lines and uncomment the following three:

#LIBPQPATH=$(PGSQLSRC)\interfaces\libpq\Release

#LIBPQDLL=libpq.dll

#LIBPQLIB=libpqdll.lib

LIBPQPATH=$(PGSQLSRC)\lib

LIBPQDLL=libpq.dll

LIBPQLIB=libpq.lib

# This is the directory where the debug build of the libpq DLL

# and its corresponding LIB file are found, as well as the names of

# those two files.

#

# NOTE: If you don't have access to a debug build of libpq, just

# provide the same information as above here. The debug builds of

# libpqxx will reference the release version of libpq, which will

# only limit your ability to debug libpq sources but otherwise should

# work just fine.

#

# If you installed PostgreSQL using the One Click Installer from EnterpriseDB,

# comment out the next three lines and uncomment the following three.

#LIBPQDPATH=$(PGSQLSRC)\interfaces\libpq\Debug

#LIBPQDDLL=libpqd.dll

#LIBPQDLIB=libpqddll.lib

LIBPQDPATH=$(PGSQLSRC)\lib

LIBPQDDLL=libpq.dll

LIBPQDLIB=libpq.lib

  • libpqxx/config/sample-headers/compiler/VisualStudio2010/pqxx以下にあるヘッダーファイルをlibpqxx/include/pqxx以下にコピーする。
  • nmakeでエラーが出る場合、libpqxx/config/sample-headers/libpq/9.0/pqxx以下にあるヘッダーファイルもlibpqxx/include/pqxx以下にコピーする。
  • Visual Studio Command Prompt(32bit版)を起動し、libpqxxにディレクトリ移動し、下記コマンドを実行。

nmake /f win32/vc-libpqxx.mak ALL

※nmake等にパスが通っていない場合は、VCVARS32.BATをVisualStudioのインストールディレクトリから探して実行。VCVARS32.BATがなんであるかの説明はあまりにも有名なため省略。

  • エラーがでなければlibpqxx/lib以下に成果物が出来ている。DLL版libpqには下記DLLが必要となるので、手に入れて同じ場所に配置する必要がある。

libeay32.dll

libiconv-2.dll

libintl-8.dll

ssleay32.dll

2.VisualC++のプロジェクト設定

  • libpqxx/includeをインクルードパスに追加する。
  • libpqxx/libをライブラリパスに追加する。
  • libpqxx_static.libを依存関係に追加。今回はスタティックリンク版のlibpqxxを使用。Debug版ビルドの際はlibpqxx_staticD.libを使用しないと、_ITERATOR_DEBUG_LEVELが合わないというリンカーエラーが出るだろう。仮にVCの標準ライブラリと依存関係でコンフリクトが起こる場合はDLL版を使う。

3.libpqxxヘッダーファイルインクルード時の注意

This has been giving people no end of trouble. The Visual C++ compiler, by default, defines min() and max() as preprocessor macros… meaning that a lot of correct, standard-conforming code will not compile properly.

The libpqxx headers disable this feature by defining the NOMINMAX preprocessor macro, which tells the Visual C++ headers not to #define min() and max(). However this seems to cause some of Visual C++'s own headers to fail to compile.

One way around this is always to include libpqxx headers before system headers, and #undef NOMINMAX between the two sets of #includes. Another workaround, suggested by Trigve Siver, is to include first the system headers and then the libpqxx headers (for older libpqxx versions that don't define NOMINIMAX it's the other way around), and finally:

#include
#define max(x,y) std::max(x,y)
#define min(x,y) std::min(x,y)

  • 上記は、VC++コンパイラで定義されているmin、maxマクロにバグが有るためlibpqxxでは使わないように、インクルード時に工夫しろというもの。具体的には、すべてのWindowsシステムヘッダーファイルの前に以下のように記述したりする。ちなみにこれは、stdafx.hに記述している。

#define NOMINMAX

#include
#undef NOMINMAX

    • VCでは、windows.hで定義されているmin()、max()の問題に即時的に対応するためか、NOMINMAXというマクロが定義されており、これによって、Windowsシステムライブラリで定義されているmin()、max()を無効化する。
    • まだあまりいじってないのでこれで不具合が出ないかどうかわからない。

 以上がlibpqxxをとりあえず使うための手順である。Webブラウザ等ではSQLiteが使われており、アプリケーション内で使うぐらいのデータ処理にはSQLiteでもいいのかもしれないが、サーバーへのデータ移行等、色々考えると本格的なデータベースを操作するためのライブラリを使えたほうが良い。まぁブラウザではクッキー管理等、限定的に使う場合にSQLiteが便利だから使っているだけだろうけど・・・

 

使用感

  • クラスを幾つか用いるだけで大体の処理は出来、文字列としてクエリーを作成し、それを実行するクラスに渡して関数を呼び出すだけ。DBにおけるクエリーの排他処理や同期有りと無し用にクラスが分けられており、使い分けが簡単。
  • 接続と切断処理さえしていれば、リソース管理はあまり気にしなくていいようだ。
  • エラー処理はtry-catch構文によって行えるように出来ているのでやりやすい。
  • libpqxx自体のビルドと依存関係(ライブラリ群)を整えるのが若干面倒だが、C言語インターフェイスよりも断然労力が少ない。あたりまえだけど。
  • どうもVC++2013への対応は遅れているようだ。これは早く何とかして欲しいところだ。