Boland C++ Builder (Compiler) で log4cpp を使ってみる

以前導入した *1 log4cpp をずっと放ったらかしにしていましたが、いい加減触ってみようということでとりあえずサンプルプログラムを動かしてみました。コンパイルして実行……すると、プログラム終了時にエラーが出て落っこちてしまいました。デバッグモードで再コンパイルしてみると、どうも終了時に必ず通る部分で多重 delete かましている様子。いくらなんでもこんなのテストするまでもなく見つかるはずでは……と、嫌な予感がしたのでソースを追う前にサイトにアクセスして最新を取得してみると、ソースが全然違う。同じところから落としたはずなのに……。

しかしソースを最新にするだけで解決するほど甘くないようで、最新版では用意されているプロジェクトに存在しないファイルが登録されていたり、コンパイルが通らなかったりなど障害多数。ひとつひとつ潰していって、どうにか無事に終了。再びサンプルプログラムをコンパイルして (こちらはすんなり通った) 試したところ、終了時に落ちるエラーは無事解決していました。よかったよかった。

今後またこの作業やることになった時のために、はまった箇所をメモしておきます。なお環境は Borland C++ Builder 6 です。用意されているプロジェクトはバージョン 5 向けのものだったので、バージョン 5 なら何もしなくても通るのかもしれません。

ConfiguratorSkeleton.cpp というファイルは存在しない

なぜかプロジェクト (bpr) に登録されていますが、こんなファイルは存在していない上どこからも使用されていないので、プロジェクトから外します。残しておくとコンパイルできません。

config-win32.hh を修正する。

config-win32.hh ファイル内に typedef int mode_t; という typedef が存在していますが、これは標準で添付されている sys/types.h で既に定義済みのため、コンパイルエラーになります。とりあえず以下のように書き換えて対処しました。

#ifndef __BORLANDC__
typedef int mode_t;
#endif

しかし sys/types.h で定義されている mode_t の正体は short なのでもしかしたら危険かもしれませんが、とりあえず自分は問題が起こってから考えればいいか、というスタンスでいってるので気にしません。

std 名前空間の省略を修正する

sprintf などの関数呼び出しが ::sprintf名前空間を省略して呼んでいますが、 include しているヘッダは cstdio なのでエラーになります。のでそれぞれ std を付与します。 std::sprintf という感じで。「関数名が見つからない」というエラーは他にもいくつかありますが、みんなこれが原因です。

include 漏れ

MSThreads.cpp で sprintf を呼んでいる箇所がありますが、 sprintf を知らないとエラーになります。頭に #include <cstdio> を追加してやりましょう。

#if WIN32

SimpleConfigurator.cpp の 132 行目で「式の構文エラー」でコンパイルに失敗します。これはすぐ真上にある #if WIN32 が原因。 #ifdef WIN32 に書き換えます。

プロジェクトに cpp を追加する

ここまでくるとコンパイルには成功するのですが、最後の最後でリンクエラーが発生します。一番最初のエラーの反対で、必要なファイルがプロジェクトに登録されていないのが原因。

  • Win32DebugAppender.cpp
  • AbortAppender.cpp

上記のファイルをプロジェクトに追加します。

しかし、これだけでは先ほども出てきた WIN32 定数 (というかマクロというか) が定義されるタイミングが遅いのか、 Win32DebugAppender と NTEventAppender のリンクには依然失敗してしまいます。そこで、プロジェクトオプションに WIN32 を追加してやります。 bcc のみの環境であれば、コマンドラインオプションに -D_WIN32 を追加すれば良いのかな?

長くなりましたが、以上の手順でソースを修正することで、 BCB6 でもコンパイルすることができると思います。さて、次はソケット通信を試してみようかな。

*1:http://d.hatena.ne.jp/wata_d/20051107/1131356464