在Windows VC++ 2010下静态链接编译Boost和ICU

10
我已经试了将近一个星期在Windows和VC++下构建可靠的Boost + ICU库,作为x86系统的静态库(这样我就不需要任何运行时dll)。 我主要需要支持Unicode的boost regex和boost.locale.icu。在网络上没有找到任何可靠的解决方案(不是在boost网站或ICU上),以便完成构建。尝试使用VC ++,Cygwin + VC ++进行构建,但至今没有成功。有经验的人可以帮忙吗?或者最坏的情况下,是否有预先构建好的ICU静态+boost静态软件包?
在构建了静态ICU并在Cygwin下配置之后:
bash runConfigureICU  --enable-debug --disable-release Cygwin/MSVC --prefix=/cygdrive/c/icu/dist --enable-static --disable-shared

我得到了以下静态库:

02/17/2014  12:57 AM        23,505,784 sicudt.lib
02/17/2014  12:56 AM         7,922,572 sicuin.lib
02/17/2014  12:56 AM           101,218 sicuio.lib
02/17/2014  12:56 AM         1,507,686 sicule.lib
02/17/2014  12:56 AM           157,632 siculx.lib
02/17/2014  12:56 AM           190,472 sicutest.lib
02/17/2014  12:56 AM         1,749,872 sicutu.lib
02/17/2014  12:56 AM         4,584,154 sicuuc.lib

我以ICU库为静态库编译了boost:

bjam --toolset=msvc-10.0 --build-dir="C:\local\build" address-model=32 threading=multi link=static runtime-link=static -sHAVE_ICU=1 -sICU_PATH="C:\icu" -sICU_LINK="/LIBPATH:C:\icu\lib sicuuc.lib sicuin.lib sicudt.lib"

然后,当我尝试运行一段简单的代码时,我得到了未解决的符号错误,所以我的编译库有问题:

cl.exe /MT /EHsc /O2 /I C:\local
\boost_1_55_0 uniregboost.cpp /I C:\icu\include /link /SUBSYSTEM:CONSOLE advapi3
2.lib sicuuc.lib sicuin.lib sicudt.lib /libpath:"C:\local\boost_1_55_0\stage\lib
" /libpath:"C:\icu\lib"
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

uniregboost.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:uniregboost.exe
/SUBSYSTEM:CONSOLE
advapi32.lib
sicuuc.lib
sicuin.lib
sicudt.lib
/libpath:C:\local\boost_1_55_0\stage\lib
/libpath:C:\icu\lib
uniregboost.obj
MSVCRT.lib(MSVCR100.dll) : error LNK2005: _memmove already defined in LIBCMT.lib
(memmove.obj)
MSVCRT.lib(MSVCR100.dll) : error LNK2005: _malloc already defined in LIBCMT.lib(
malloc.obj)
MSVCRT.lib(MSVCR100.dll) : error LNK2005: _realloc already defined in LIBCMT.lib
(realloc.obj)
MSVCRT.lib(MSVCR100.dll) : error LNK2005: _free already defined in LIBCMT.lib(fr
ee.obj)
MSVCRT.lib(MSVCR100.dll) : error LNK2005: _wcslen already defined in LIBCMT.lib(
wcslen.obj)
MSVCRT.lib(MSVCR100.dll) : error LNK2005: _strtoul already defined in LIBCMT.lib
(strtol.obj)
MSVCRT.lib(ti_inst.obj) : error LNK2005: "private: __thiscall type_info::type_in
fo(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in LIBC
MT.lib(typinfo.obj)
MSVCRT.lib(ti_inst.obj) : error LNK2005: "private: class type_info & __thiscall
type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) a
lready defined in LIBCMT.lib(typinfo.obj)
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; us
e /NODEFAULTLIB:library
uniregboost.obj : error LNK2019: unresolved external symbol "private: class boos
t::basic_regex<int,class boost::icu_regex_traits> & __thiscall boost::basic_rege
x<int,class boost::icu_regex_traits>::do_assign(int const *,int const *,unsigned
 int)" (?do_assign@?$basic_regex@HVicu_regex_traits@boost@@@boost@@AAEAAV12@PBH0
I@Z) referenced in function "public: class boost::basic_regex<int,class boost::i
cu_regex_traits> & __thiscall boost::basic_regex<int,class boost::icu_regex_trai
ts>::assign(int const *,int const *,unsigned int)" (?assign@?$basic_regex@HVicu_
regex_traits@boost@@@boost@@QAEAAV12@PBH0I@Z)
uniregboost.obj : error LNK2019: unresolved external symbol "public: class std::
vector<int,class std::allocator<int> > __thiscall boost::re_detail::icu_regex_tr
aits_implementation::do_transform(int const *,int const *,class icu_52::Collator
 const *)const " (?do_transform@icu_regex_traits_implementation@re_detail@boost@
@QBE?AV?$vector@HV?$allocator@H@std@@@std@@PBH0PBVCollator@icu_52@@@Z) reference
d in function "public: class std::vector<int,class std::allocator<int> > __thisc
all boost::re_detail::icu_regex_traits_implementation::transform(int const *,int
 const *)const " (?transform@icu_regex_traits_implementation@re_detail@boost@@QB
E?AV?$vector@HV?$allocator@H@std@@@std@@PBH0@Z)
uniregboost.obj : error LNK2019: unresolved external symbol "public: bool __this
call boost::icu_regex_traits::isctype(int,unsigned __int64)const " (?isctype@icu
_regex_traits@boost@@QBE_NH_K@Z) referenced in function "private: bool __thiscal
l boost::re_detail::perl_matcher<class boost::u8_to_u32_iterator<class std::_Str
ing_const_iterator<char,struct std::char_traits<char>,class std::allocator<char>
 >,int>,class std::allocator<struct boost::sub_match<class boost::u8_to_u32_iter
ator<class std::_String_const_iterator<char,struct std::char_traits<char>,class
std::allocator<char> >,int> > >,class boost::icu_regex_traits>::match_word_bound
ary(void)" (?match_word_boundary@?$perl_matcher@V?$u8_to_u32_iterator@V?$_String
_const_iterator@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@boost@@V?$alloca
tor@U?$sub_match@V?$u8_to_u32_iterator@V?$_String_const_iterator@DU?$char_traits
@D@std@@V?$allocator@D@2@@std@@H@boost@@@boost@@@std@@Vicu_regex_traits@2@@re_de
tail@boost@@AAE_NXZ)
uniregboost.exe : fatal error LNK1120: 3 unresolved externals

我在代码中没有忘记为ICU添加静态标志:

#define U_STATIC_IMPLEMENTATION

更新:

重新构建了所有ICU和Boost静态库,现在只有一个链接错误:

cl.exe /MT /EHsc /O2 /I C:\lib\b
oost-1.55.0-vs2010\include\boost-1_55 uniregboost.cpp /I C:\lib\icu-52.1-vs2010\
include /link /SUBSYSTEM:CONSOLE advapi32.lib sicuuc.lib sicuin.lib sicudt.lib s
icuuc.lib /libpath:"C:\lib\boost-1.55.0-vs2010\lib" /libpath:"C:\lib\icu-52.1-vs
2010\lib"
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

uniregboost.cpp
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:uniregboost.exe
/SUBSYSTEM:CONSOLE
advapi32.lib
sicuuc.lib
sicuin.lib
sicudt.lib
sicuuc.lib
/libpath:C:\lib\boost-1.55.0-vs2010\lib
/libpath:C:\lib\icu-52.1-vs2010\lib
uniregboost.obj
   Creating library uniregboost.lib and object uniregboost.exp
libboost_regex-vc100-mt-s-1_55.lib(icu.obj) : warning LNK4217: locally defined s
ymbol ??0Locale@icu_52@@QAE@ABV01@@Z (public: __thiscall icu_52::Locale::Locale(
class icu_52::Locale const &)) imported in function "public: class icu_52::Local
e __thiscall boost::re_detail::icu_regex_traits_implementation::getloc(void)cons
t " (?getloc@icu_regex_traits_implementation@re_detail@boost@@QBE?AVLocale@icu_5
2@@XZ)
libboost_regex-vc100-mt-s-1_55.lib(icu.obj) : warning LNK4217: locally defined s
ymbol ??0Locale@icu_52@@QAE@XZ (public: __thiscall icu_52::Locale::Locale(void))
 imported in function "public: class icu_52::Locale __thiscall boost::icu_regex_
traits::getloc(void)const " (?getloc@icu_regex_traits@boost@@QBE?AVLocale@icu_52
@@XZ)
libboost_regex-vc100-mt-s-1_55.lib(icu.obj) : warning LNK4217: locally defined s
ymbol ??1Locale@icu_52@@UAE@XZ (public: virtual __thiscall icu_52::Locale::~Loca
le(void)) imported in function "public: __thiscall boost::re_detail::icu_regex_t
raits_implementation::~icu_regex_traits_implementation(void)" (??1icu_regex_trai
ts_implementation@re_detail@boost@@QAE@XZ)
libboost_regex-vc100-mt-s-1_55.lib(icu.obj) : error LNK2019: unresolved external
 symbol "__declspec(dllimport) public: static class icu_52::Collator * __cdecl i
cu_52::Collator::createInstance(class icu_52::Locale const &,enum UErrorCode &)"
 (__imp_?createInstance@Collator@icu_52@@SAPAV12@ABVLocale@2@AAW4UErrorCode@@@Z)
 referenced in function "public: __thiscall boost::re_detail::icu_regex_traits_i
mplementation::icu_regex_traits_implementation(class icu_52::Locale const &)" (?
?0icu_regex_traits_implementation@re_detail@boost@@QAE@ABVLocale@icu_52@@@Z)
uniregboost.exe : fatal error LNK1120: 1 unresolved externals

我尝试过Boost邮件列表和IRC频道,但没有得到帮助。 - bsteo
1
这样的错误,例如MSVCRT.lib(MSVCR100.dll) : error LNK2005: _strtoul already defined in LIBCMT.lib (strtol.obj)通常是由于混合使用了C标准库的静态链接和非静态链接导致的。我知道你说你已经正确地做了,但是否值得再看一眼呢?也要确保始终使用多线程版本。 - Peter R
1
我没有你问题的答案,但我已经编写了一个脚本,可以静态构建一组库,包括Boost和ICU。它可能有你需要的东西。它在https://github.com/ferruccio/cclibs上。 - Ferruccio
我的错误。它将Boost构建为静态库,但仍将ICU构建为DLL。 - Ferruccio
@Ferruccio,是的,我的问题是需要将ICU作为静态库,因为我需要独立的可执行文件,而不需要外部第三方dll。 - bsteo
显示剩余9条评论
3个回答

1

我还不能发表评论,所以我把我的评论作为答案(很抱歉造成不便),因为我正在努力解决完全相同的问题。我检测到以下测试文件:

<boost>\libs\locale\build\has_icu_test.cpp

使用以下代码行:
#if defined(_MSC_VER) && !defined(_DLL)
#error "Mixing ICU with a static runtime doesn't work"
#endif

也许(至少在Windows上)无法静态编译带有ICU的Boost库?

是的,可能是这样...在Linux下很容易,但在Windows下,我不知道,没有成功... - bsteo

0
你正在正确构建。问题在于 Boost.Locale 构建系统似乎没有任何代码来检测静态 ICU 库,因此即使您设置了所有正确的参数,它也无法按预期使用库。如果您检查这些文件:
libs\locale\build\Jamfile.v2
libs\regex\build\Jamfile.v2

你会注意到似乎没有探测 sicuXX.XXX 文件的代码。我认为这可能是问题所在。

在 boost bug 追踪器上有一个功能请求:https://svn.boost.org/trac/boost/ticket/9685

如果更多人表达他们对实现此功能的兴趣,可能会有所帮助。


0

编辑 M:\work\code\qt\icu4c-68_2\icu4c\source\runConfigureICU

查找 Cygwin/MSVC

将 -MD -MDt 替换为 -MT -MTd


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接