VS2005(VC8)編譯Xalan-C_1_10_0

VS2005(VC8)編譯Xalan-C_1_10_0


概述
本人設計和研發的一個類似Altova MapForce的文檔轉換產品,該產品支持常用格式文檔間的互相轉換,包括XML、Excel、CVS、Txt、HTML、XHTML、EDIFACT、SAP IDoc、Database等。項目採用C++語言,VS2005開發環境。
該產品採用適配器(Adapter)的概念在源文檔和目標文檔中進行適配或者說是轉換。其中一個重要的適配器是Xml2Txt,該適配器將XML文檔轉換(Transform)爲其他純文本文檔(Plain Text,在本項目中指XML、Txt、CVS、HTML、XHTML、EDIFACT等)。該適配器採用XSLT(EXtensible Stylesheet Language Transformations),因此需要一個XSLT的解析器。XSLT解析器的開源項目中Apache下的Xalan項目是首選,Xalan有Xalan-C和Xalan-J兩種版本,分別支持C++和Java兩種語言。Xalan-C的當前版本爲1.10.0。Xalan-C需要使用Apache下的Xerces-C項目來解析XML,本項目使用的版本是Xerces-C 2.8.0。
本文意圖不是介紹產品的完整方案,而是介紹本人在技術預研時遇到的一個問題的解決方案,即Xalan-C_1_10_0在VS2005下的編譯問題。本着發揚互聯網的分享精神,心想可能會有朋友遇到同樣的問題,因此將解決方案記錄下來與朋友們分享,文中錯誤之處請指正。


相關資源
Xalan-C的官網地址:
http://xml.apache.org/xalan-c/

Xalan-C_1_10_0的下載地址:
http://xml.apache.org/xalan-c/download.html

Xerces-C的官網地址:
http://xerces.apache.org/xerces-c/

Xerces-C_2_8_0的下載地址:
http://xerces.apache.org/xerces-c/download.cgi

文檔約定
$XercesSrcHome:指Xerces-C_2_8_0的源碼所在文件夾
$XalanSrcHome:指Xalan-C_1_10_0的源碼所在文件夾

步驟
(1)使用vs2005編譯Xerces-C_2_8_0
Xerces-C_2_8_0的VS2005解決方案在$XercesSrcHome\Projects\Win32\VC8\xerces-all文件夾下,用VS2005打開。
修改XercesLib的工程屬性,在屬性對話框中的配置屬性\C++\語言選項卡中,設置“將wchar_t視爲內置類型”爲“否”。


(2)設置XERCESCROOT環境變量
新建XERCESCROOT環境變量,其值設置爲Xerces-C_2_8_0源碼的根路徑,即$XercesSrcHome。
右鍵我的電腦\屬性\高級\環境變量

(3)設置VS2005開發環境的Xerces-C_2_8_0路徑
工具\選項\項目解決方案\VC++目錄,
添加“包含文件”路徑:$XercesSrcHome\src
添加“庫文件”:$XercesSrcHome\Build\Win32\VC8\Debug

(4)由於Xalan-C_1_10_0不提供VC8(VS2005)解決方案,但其提供了VS7.1(VS2003)的解決方案。因此需要將解決方案從VC7.1裝換爲VC8。。
Xalan-C_1_10_0的VC7.1的解決方案位於$XalanSrcHome\c\Projects\Win32\VC7.1。將$XalanSrcHome\c\Projects\Win32\VC7.1文件夾複製爲$XalanSrcHome\c\Projects\Win32\VC8,然後用VS2005打開$XalanSrcHome\c\Projects\Win32\VC8\Xalan.sln,開發環境自動將工程轉換爲VC8。

(5)編譯Localization工程
編譯Xalan庫之前,需要先編譯Localization工程。編譯過程中將會出現若干錯誤,下文將逐個解決。
a)修改$XalanSrcHome\c\Projects\Win32\VC8\Utils\Localization\BuildMessages.mak文件,在第一行處加入如下語句:
include tools.ini
並修改$XalanSrcHome\c\Projects\Win32\VC8\Utils\Localization\tools.ini,

[NMAKE]
CFG=Release
改爲
#[NMAKE]
#CFG=Release
即註冊掉NMAKE段。
否則,會出現如下編譯錯誤:BuildMessages.mak(26) : fatal error U1050: Invalid configuration BITS="" specified. 

b)修改$XalanSrcHome\c\Projects\Win32\VC8\Utils\MsgCreator\MsgCreator.mak文件,修改debug的編譯選項,增加/Zc:wchar_t-,即不將wchar_t視爲內置類型。

CPP_PROJ=/nologo /MLd /W4 /Gm /GX /ZI /Od /I ".\\" /I $(XALANINCLUDE) $(XERCESINCLUDE) /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fr"$(INTDIR)\\" /Fp"$(INTDIR)\MsgCreator.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c 
修改爲:
CPP_PROJ=/Zc:wchar_t- /nologo /MLd /W4 /Gm /GX /ZI /Od /I ".\\" /I $(XALANINCLUDE) $(XERCESINCLUDE) /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fr"$(INTDIR)\\" /Fp"$(INTDIR)\MsgCreator.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c 
否則,會出現如下編譯錯誤:
1>ICUResHandler.cpp
1>f:\2-研發庫\xml\xslt\xml-xalan\c\src\xalanc\utils\msgcreator\icureshandler.cpp(89) : error C2664: 'void XalanFileOutputStream::write(const UTF16Ch *,unsigned int)' : cannot convert parameter 1 from 'XMLCh [512]' to 'const UTF16Ch *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>f:\2-研發庫\xml\xslt\xml-xalan\c\src\xalanc\utils\msgcreator\icureshandler.cpp(150) : error C2664: 'void XalanFileOutputStream::write(const UTF16Ch *,unsigned int)' : cannot convert parameter 1 from 'XMLCh *' to 'const UTF16Ch *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

c)修改$XalanSrcHome\c\Projects\Win32\VC8\Utils\MsgCreator\MsgCreator.mak文件,修改debug的編譯選項,將/MLd改爲/MDd。

CPP_PROJ=/nologo /MLd /W4 /Gm /GX /ZI /Od /I ".\\" /I $(XALANINCLUDE) $(XERCESINCLUDE) /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fr"$(INTDIR)\\" /Fp"$(INTDIR)\MsgCreator.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c 
修改爲:
CPP_PROJ=/Zc:wchar_t- /nologo /MDd /W4 /Gm /GX /ZI /Od /I ".\\" /I $(XALANINCLUDE) $(XERCESINCLUDE) /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fr"$(INTDIR)\\" /Fp"$(INTDIR)\MsgCreator.pch" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c 
否則會出現如下連接錯誤:
MsgCreator.obj : error LNK2019: 無法解析的外部符號 __CrtSetReportFile,該符號在函數 _main 中被引用
1>MsgCreator.obj : error LNK2019: 無法解析的外部符號 __CrtSetReportMode,該符號在函數 _main 中被引用
1>MsgCreator.obj : error LNK2019: 無法解析的外部符號 __CrtSetDbgFlag,該符號在函數 _main 中被引用
1>libcpmtd.lib(xmbtowc.obj) : error LNK2001: 無法解析的外部符號 __CrtDbgReportW
1>SAX2Handler.obj : error LNK2019: 無法解析的外部符號 __CrtDbgReportW,該符號在函數 "public: char & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::operator[](unsigned int)" (??A?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAADI@Z) 中被引用
1>libcpmtd.lib(cerr.obj) : error LNK2001: 無法解析的外部符號 __CrtDbgReportW
1>libcpmtd.lib(cout.obj) : error LNK2001: 無法解析的外部符號 __CrtDbgReportW
1>libcpmtd.lib(stdthrow.obj) : error LNK2001: 無法解析的外部符號 __CrtDbgReportW
1>libcpmtd.lib(xdebug.obj) : error LNK2019: 無法解析的外部符號 __malloc_dbg,該符號在函數 "void * __cdecl operator new(unsigned int,struct std::_DebugHeapTag_t const &,char *,int)" (??2@YAPAXIABU_DebugHeapTag_t@std@@PADH@Z) 中被引用
1>libcpmtd.lib(xmbtowc.obj) : error LNK2001: 無法解析的外部符號 __malloc_dbg
1>NMAKE : fatal error U1077: 
1>libcpmtd.lib(xdebug.obj) : error LNK2019: 無法解析的外部符號 __free_dbg,該符號在函數 "void __cdecl operator delete(void *,struct std::_DebugHeapTag_t const &,char *,int)" (??3@YAXPAXABU_DebugHeapTag_t@std@@PADH@Z) 中被引用
1>libcpmtd.lib(xmbtowc.obj) : error LNK2001: 無法解析的外部符號 __free_dbg
1>Stop.
1>libcpmtd.lib(_tolower.obj) : error LNK2019: 無法解析的外部符號 __calloc_dbg,該符號在函數 __Getctype 中被引用
1>..\..\..\..\..\Build\Win32\VC7.1\Debug\MsgCreator.exe : fatal error LNK1120: 7 個無法解析的外部命令


d)修改$XalanSrcHome\c\Projects\Win32\VC8\Utils\Localization\BuildMessages.mak文件,

XERCESPATH=$(XERCESCROOT)/bin;$(XERCESCROOT)\Build\Win32\VC7.1\Release;$(XERCESCROOT)\Build\Win32\VC7.1\Debug;$(XERCESCROOT)\Build\Win64\VC7.1\Release;$(XERCESCROOT)\Build\Win64\VC7.1\Debug
修改爲:
XERCESPATH=$(XERCESCROOT)/bin;$(XERCESCROOT)\Build\Win32\VC8\Release;$(XERCESCROOT)\Build\Win32\VC8\Debug;$(XERCESCROOT)\Build\Win64\VC8\Release;$(XERCESCROOT)\Build\Win64\VC8\Debug
否則會出現如下連接錯誤:
1>NMAKE : fatal error U1077: 
1>Stop.
1>Project : error PRJ0019: 工具從"正在執行生成文件項目操作"
1>生成日誌保存在“file://f:\2-研發庫\xml\xslt\xml-xalan\c\Projects\Win32\VC8\Utils\Localization\BuildLog.htm”
1>Localization - 2 個錯誤,62 個警告

(6)編譯AllInOne
a)修改AllInOne的工程屬性,在屬性對話框中的配置屬性\C++\語言選項卡中,設置“將wchar_t視爲內置類型”爲“否”。

b)增加宏定義_HAS_ITERATOR_DEBUGGING=0
否則會出現如下編譯錯誤:
2>C:\Program Files\Microsoft Visual Studio 8\VC\include\xutility(1360) : error C2678: binary '<' : no operator found which takes a left-hand operand of type 'xalanc_1_10::XalanDequeIterator<XalanDequeTraits,XalanDeque>' (or there is no acceptable conversion)
2>        with
2>        [
2>            XalanDequeTraits=xalanc_1_10::XalanDequeConstIteratorTraits<xalanc_1_10::NameSpace>,
2>            XalanDeque=xalanc_1_10::XalanDeque<xalanc_1_10::NameSpace,xalanc_1_10::ConstructWithMemoryManagerTraits<xalanc_1_10::NameSpace>>
2>        ]

(7)編譯XalanExe(可選)
a)刪除輸入庫largeint.lib
b)去掉XALAN_USE_WINDOWS_TIMING宏定義

#if defined(_MSC_VER) && !defined(_WIN64)
#define XALAN_USE_WINDOWS_TIMING
#endif
改爲
#if defined(_MSC_VER) && !defined(_WIN64)
//#define XALAN_USE_WINDOWS_TIMING
#endif
否則會出現如下錯誤:
3>LINK : fatal error LNK1104: 無法打開文件“largeint.lib”


參考文獻
a)http://marc.info/?l=xalan-c-users&m=113116861129527
b)http://lists.gnu.org/archive/html/make-w32/2004-03/msg00027.html
c)http://mail-archives.apache.org/mod_mbox/xml-xalan-c-users/201001.mbox/%[email protected]%3E
d)http://mail-archives.apache.org/mod_mbox/xml-xalan-c-users/200709.mbox/%3c001301c7fc82$047987d0$4001a8c0@estec5syvrnjfw%3e
e)http://marc.info/?l=xalan-c-users&m=113215252420764


總結
本文成功的解決了Xalan-C_1_10_0在VS2005(VC8)下的編譯問題。Xalan-C_1_10_0僅實現了XPath1.0,且不支持數據庫擴展(SQLExt),因此在數據轉換功能上大受限制。本人擬在產品中實現XalanXPath2.0ExtLib(XPath2.0擴展庫)和XalanSQLExtLib(SQL擴展庫),以便支持強大的數據轉換功能。並在此過程中遇到的技術難點和有價值的方案與朋友們分享。


發佈了71 篇原創文章 · 獲贊 9 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章