log4cpp-1.0をVisualStudio2005でビルドする。

http://sourceforge.net/projects/log4cpp/files/

(最新版のlog4cpp-1.1.xをやってみたがどうにもうまくいかなかった。梱包されているVC6構成はコンバートができなかったし、VS2003構成 は「Boost」がないって怒られる。Boostをインストールする必要があるみたいで面倒なのであきらめた。VS2010構成は、VS2005には逆変 換できないし。)


解凍してできたフォルダの中に、「msvc6」というフォルダがある。
VC6でのビルド構成ファイルが用意されているが、これをVS2005用にコピーする。

「msvc8」

VisualStudio2005を起動し、msvc8の下にある「msvc6.dsw」を読み込む。
「変換しますか?」と聞かれるので「はい」を選択。

「log4cppDLL_stlport_boost.dsp」「testMain_stlport_boost.dsp」・・・が開けないと6つ警告が出るが気にしない。


とりあえず、log4cppプロジェクトをビルドしてみる。

カスタム ビルド ステップを実行しています。
指定されたパスが見つかりません。
指定されたパスが見つかりません。
指定されたパスが見つかりません。
Project : error PRJ0019: ツールはエラー コードを返しました : "カスタム ビルド ステップ実行しています。"
ブラウザ情報ファイルを作成しています...
Microsoft Browse Information Maintenance Utility Version 8.00.50727
Copyright (C) Microsoft Corporation. All rights reserved.
BSCMAKE: error BK1506 : : No such file or directory


さっぱり理由がつかめない。エラー内容。
ちゃんと変換せいやーと思いながら、生成された「BuildLog.htm」を眺める。

「コマンドライン」で何をしているのかが記録されている。

"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\..\..\VC98\Bin\mc.exe" -h .\Debug -r .\Debug c:\Documents and Settings\user\デスクトップ\tmp\log4cpp-1.0\msvc8\log4cpp\.. \NTEventLogCategories.mc
   
"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\Bin\RC.exe" -r -fo .\Debug\NTEventLogCategories.res .\Debug\NTEventLogCategories.rc
   
"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\..\..\VC98\Bin\link.exe" /MACHINE:IX86 -dll -noentry -out:.\Debug\NTEventLogAppender.dll .\Debug\NTEventLogCategories.res

「指定されたパスが見つかりません。」が3回出ていることから、
まず、ここでいう、mc.exe、RC.exe、link.exeがちゃんとあるのか調べてみる。

すると、
「C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\..\..\VC98\Bin」
「C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\Bin」
なんてフォルダは存在しないことに気づく。

これらを正しいパスに指定してやる必要がある。そこで、ネット上の情報やフォルダ検索を使って特定する。

C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin\MC.Exe
C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\Bin\RC.Exe
  (C:\Program Files\Microsoft Visual Studio 8\VC\bin\rc.exeにもある)
C:\Program Files\Microsoft Visual Studio 8\VC\bin\link.exe


正しい位置がわかったところで、これらのツールを指定しているファイルを探すと、各プロジェクトの「.vcproj」ファイルの最後の方にNTEventLogCategories.mcをビルドするために上記3つのexeを指定していた。

$(DevEnvDir)..\Tools\Bin\mc.exe
$(DevEnvDir)..\Tools\Bin\RC.exe
$(VCInstallDir)Bin\link.exe

とテキストエディタで変更する。(Release用、Debug用の2箇所)



ビルドする・・・エラー


1>カスタム ビルド ステップを実行しています。
1>MC: may only specify one message file to compile.
1>MC: may only specify one message file to compile.
1>Microsoft (R) Message Compiler  Version 1.12.2505
1>Copyright (c) Microsoft Corporation. All rights reserved.
1>usage: MC [-?aAcdnosuUvw] [-m maxmsglen] [-h dirspec] [-e extension] [-r dirspec] [-x dbgFileSpec] filename.mc
1>       -? - displays this message
1>       -a - input file is ANSI (default).
1>       -A - messages in .BIN file should be ANSI.
1>       -b - .BIN filename should have .mc filename_ included for uniqueness.
1>       -c - sets the Customer bit in all the message Ids.
1>       -d - FACILTY and SEVERITY values in header file in decimal.
1>            Sets message values in header to decimal initially.
1>       -e extension - Specify the extension for the header file.
1>                      From 1 - 3 chars.
1>       -h pathspec - gives the path of where to create the C include file
1>                     Default is .\
1>       -m maxmsglen - generate a warning if the size of any message exceeds
1>                      maxmsglen characters.
1>       -n - terminates all strings with null's in the message tables.
1>       -o - generate OLE2 header file (use HRESULT definition instead of
1>            status code definition)
1>       -r pathspec - gives the path of where to create the RC include file
1>                     and the binary message resource files it includes.
1>                     Default is .\
1>       -s - insert symbolic name as first line of each message.
1>       -u - input file is Unicode.
1>       -U - messages in .BIN file should be Unicode (default).
1>       -v - gives verbose output.
1>       -w - warns if message text contains non-OS/2 compatible inserts.
1>       -x pathspec - gives the path of where to create the .dbg C include
1>                        file that maps message Ids to their symbolic name.
1>       filename.mc - gives the names of a message text file
1>                     to compile.
1>       Generated files have the Archive bit cleared.
1>fatal error RC1110: could not open .\Debug\NTEventLogCategories.rc
1>Microsoft (R) Incremental Linker Version 8.00.50727.762
1>Copyright (C) Microsoft Corporation.  All rights reserved.
1>LINK : fatal error LNK1181: 入力ファイル '.\Debug\NTEventLogCategories.res' を開けません。
1>Project : error PRJ0019: ツールはエラー コードを返しました : "カスタム ビルド ステップを実行しています。"
1>ブラウザ情報ファイルを作成しています...
1>Microsoft Browse Information Maintenance Utility Version 8.00.50727
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>BSCMAKE: error BK1506 : : No such file or directory


mc.exeの使い方に関する情報が出力されている。どうも引数が良くないらしい。
ふと、デスクトップ上で扱っているからかと思い、フォルダを「c:\」直下に移動して再度ビルドしてみる。


1>カスタム ビルド ステップを実行しています。
1>MC: Compiling c:\log4cptmp\log4cpp-1.0\msvc8\log4cpp\..\NTEventLogCategories.mc
1>Microsoft (R) Incremental Linker Version 8.00.50727.762
1>Copyright (C) Microsoft Corporation.  All rights reserved.
1>コンパイルしています...
1>Appender.cpp
1>AppenderSkeleton.cpp
        ・・・
1>Microsoft Browse Information Maintenance Utility Version 8.00.50727
1>Copyright (C) Microsoft Corporation. All rights reserved.
1>ビルドログは "file://c:\log4cptmp\log4cpp-1.0\msvc8\log4cpp\Debug\BuildLog.htm" に保存されました。
1>log4cpp - エラー 0、警告 26
========== すべてリビルド: 1 正常終了、0 失敗、0 スキップ ==========

成功。

続いて、testMainプロジェクトをビルドしてみる。


1>コンパイルしています...
1>testmain.cpp
1>c:\log4cptmp\log4cpp-1.0\tests\testmain.cpp(83) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>        c:\program files\microsoft visual studio 8\vc\include\stdio.h(345) : 'sprintf' の宣言を確認してください。
1>マニフェストをリソースにコンパイルしています...
1>リンクしています...
1>   ライブラリ .\Debug/testMain.lib とオブジェクト .\Debug/testMain.exp を作成中
1>log4cppD.lib(FileAppender.obj) : error LNK2019: 未解決の外部シンボル "public: class std::_Tree<class std::_Tmap_traits<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > >,0> >::const_iterator __thiscall log4cpp::FactoryParams::find(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)const " (?find@FactoryParams@log4cpp@@QBE?AVconst_iterator@?$_Tree@V?$_Tmap_traits@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@U?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V12@@std@@@2@$0A@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@5@@Z) が関数 "public: class log4cpp::details::required_params_validator const & __thiscall log4cpp::details::required_params_validator::operator()<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(char const *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)const " (??$?RV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@required_params_validator@details@log4cpp@@QBEABV012@PBDAAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) で参照されました。
1>.\Debug/testMain.exe : fatal error LNK1120: 外部参照 1 が未解決です。


何々?
log4cpp::FactoryParamsがリンクできないと読み取れる。

さっきビルドしたlog4cppプロジェクトを見てみると、確かにソース一覧に表示されていない。
このプロジェクトのソースコードの実態は、「..\src」フォルダにあって、
log4cppプロジェクトをそこにあるソースコードを引っ張ってきて参照している。

srcフォルダを覗いてみると、「FactoryParams.cpp」がある。
けれどもlog4cppでは取り込んでいない模様。

なら取り込んでしまえばよい。ということでlog4cppプロジェクトに戻って、
「Source Files」右クリック-「追加」「既存の項目」でsrcフォルダの「FactoryParams.cpp」を追加する。

log4cppを再ビルド。
testMainを再ビルド。

1>コンパイルしています...
1>testmain.cpp
1>c:\log4cptmp\log4cpp-1.0\tests\testmain.cpp(83) : warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
1>        c:\program files\microsoft visual studio 8\vc\include\stdio.h(345) : 'sprintf' の宣言を確認してください。
1>マニフェストをリソースにコンパイルしています...
1>リンクしています...
1>   ライブラリ .\Debug/testMain.lib とオブジェクト .\Debug/testMain.exp を作成中
1>マニフェストを埋め込んでいます...
1>ビルドログは "file://c:\log4cptmp\log4cpp-1.0\msvc8\testMain\Debug\BuildLog.htm" に保存されました。
1>testMain - エラー 0、警告 1
========== すべてリビルド: 1 正常終了、0 失敗、0 スキップ ==========


成功。

実行してみると、テストコードのとおり、大量にコンソールにログが出力された。



今度はVS2008でもやってみる。
VS2008Stdでは、mc.exeとrc.exeが「C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin」にある。(Expressでは、mc.exe、rc.exeなどのツールは提供されていないらしい)

$(FrameworkSDKDir)Bin\mc.exe
$(FrameworkSDKDir)Bin\RC.exe
$(VCInstallDir)Bin\link.exe

として、ビルド。
他はVS2005でも同じ。






しかし、、、
Eclipseと違ってVisualStudioはバージョンが変わると何でこうも変わるのだろうか・・・?

あと、log4jは簡単に導入できるけれど、log4cppは何でこんなに面倒なのだろうか・・・?