2014-10-28 70 views
2

我试图在Visual Studio 2013下构建log4cxx版本0.10.0。我已经完成了所有修补程序,如building log4cxx in vs 2010 c++中所述。在visual studio 2013下构建log4cxx

然而,它现在在链接阶段,当试图创建log4cxx.lib,失败与以下错误:

unresolved external symbol __InterlockedIncrement referenced in function [email protected] 
unresolved external symbol __InterlockedExchangeAdd referenced in function [email protected] 
unresolved external symbol __InterlockedExchange referenced in function [email protected] 
unresolved external symbol __InterlockedDecrement referenced in function [email protected] 
unresolved external symbol __InterlockedCompareExchange referenced in function [email protected] 

根据MSDN,这些功能应该是在KERNEL32.LIB,和我已经将这添加到链接器中,没有任何效果。看看ht elib,这似乎包含_InterlockedIncrement(单下划线)和_imp_InterlockedIncrement

有谁知道我能做些什么才能使它工作?

此外,修复程序Building log4cxx with VS 2012 on Windows 7建议不作任何不同

回答

3

下面的过程为VS2013下构建Log4CXX,对于32位和64位构建一个完整的过程。请注意,32位构建已经进行了非常轻微的测试,并且64位版本已经进行了更广泛的测试(I.E,这是我们使用的版本)。

  1. 下载apache-log4cxx-0.10.0.zipapr-x.y.z-win32.src.zipapr-util-1.5.4-win32.src.zip,其中xyz是最新版本。
  2. 将内容解压到共享目录。
  3. 重命名apr-x.y.zapr-utls-x.y.z删除版本号。
  4. 将修补程序应用于log4cxx中的文件。见下文。
  5. 对于32位版本,修补程序apr\atomic\win32\apr_atomic.c

    1. 更换所有出现defined(_M_IA64) || defined(_M_AMD64))defined(_M_IA64) || defined(_M_AMD64) || (_MSC_VER == 1800))

      这是唯一真正一个临时的解决办法,但它的作品。

  6. 运行apache-log4cxx-0.10.0\configure.bat
  7. 补丁apr-util
    1. include\apu.hw,改变APU_HAVE_APR_ICONV被定义为0
    2. include\apr_ldap.hw,改变APR_HAS_LDAP被定义为0
  8. 负载apache-log4cxx-0.10.0\projects\log4cxx.dsw到Visual Studio 2013年您将被提示升级项目。接受并等待转换完成。这将创建log4cxx.sln,您应在下次打开项目时使用
  9. 选择菜单选项Build->Configuration Manager。为log4cxx创建x64项目上下文,包括发布和调试。检查这些项目的构建框。
  10. 需要时升级项目。上一步将导致所有其他项目都需要这样做。右键单击解决方案资源管理器中的项目,然后选择Upgrade VC++ compiler ...
  11. 如果您希望调试库具有与发行版不同的文件名,请右键单击log4cxx项目,然后选择properties
    1. 选择Debug/All platforms配置设置。
    2. 设置Configuration Properties/General/Target name将“_d”作为文件名的结尾。
    3. 设置Linker/All Options/Output File将“_d”作为文件名的结尾。
    4. 设置Linker/All Options/Import Library将“_d”作为文件名的结尾。
  12. 在菜单Build -> Configuration manager中选择适当的活动解决方案配置和平台。
  13. 构建项目。

下面是log4cxx所需的补丁。

diff -r .\archives\apache-log4cxx-0.10.0/src/main/cpp/loggingevent.cpp .\build_official_2\apache-log4cxx-0.10.0/src/main/cpp/loggingevent.cpp 
127c127 
< LoggingEvent::KeySet LoggingEvent::getMDCKeySet() const 
--- 
> KeySet LoggingEvent::getMDCKeySet() const 
129c129 
<   LoggingEvent::KeySet set; 
--- 
>   KeySet set; 
188c188 
< LoggingEvent::KeySet LoggingEvent::getPropertyKeySet() const 
--- 
> KeySet LoggingEvent::getPropertyKeySet() const 
190c190 
<   LoggingEvent::KeySet set; 
--- 
>   KeySet set; 
diff -r .\archives\apache-log4cxx-0.10.0/src/main/cpp/propertiespatternconverter.cpp .\build_official_2\apache-log4cxx-0.10.0/src/main/cpp/propertiespatternconverter.cpp 
62c62 
<  LoggingEvent::KeySet keySet(event->getMDCKeySet()); 
--- 
>  KeySet keySet(event->getMDCKeySet()); 
64c64 
<  for(LoggingEvent::KeySet::const_iterator iter = keySet.begin(); 
--- 
>  for(KeySet::const_iterator iter = keySet.begin(); 
diff -r .\archives\apache-log4cxx-0.10.0/src/main/cpp/xmllayout.cpp .\build_official_2\apache-log4cxx-0.10.0/src/main/cpp/xmllayout.cpp 
104,105c104,105 
<    LoggingEvent::KeySet propertySet(event->getPropertyKeySet()); 
<    LoggingEvent::KeySet keySet(event->getMDCKeySet()); 
--- 
>    KeySet propertySet(event->getPropertyKeySet()); 
>    KeySet keySet(event->getMDCKeySet()); 
109c109 
<     for (LoggingEvent::KeySet::const_iterator i = keySet.begin(); 
--- 
>     for (KeySet::const_iterator i = keySet.begin(); 
123c123 
<    for (LoggingEvent::KeySet::const_iterator i2 = propertySet.begin(); 
--- 
>    for (KeySet::const_iterator i2 = propertySet.begin(); 
diff -r .\archives\apache-log4cxx-0.10.0/src/main/include/log4cxx/asyncappender.h .\build_official_2\apache-log4cxx-0.10.0/src/main/include/log4cxx/asyncappender.h 
52a53 
>  LOG4CXX_LIST_DEF(LoggingEventList, log4cxx::spi::LoggingEventPtr); 
197c198 
<     LOG4CXX_LIST_DEF(LoggingEventList, log4cxx::spi::LoggingEventPtr); 
--- 
>     
diff -r .\archives\apache-log4cxx-0.10.0/src/main/include/log4cxx/helpers/bytearrayinputstream.h .\build_official_2\apache-log4cxx-0.10.0/src/main/include/log4cxx/helpers/bytearrayinputstream.h 
38a39 
>   LOG4CXX_LIST_DEF(ByteList, unsigned char); 
42c43 
<    LOG4CXX_LIST_DEF(ByteList, unsigned char); 
--- 
>    
diff -r .\archives\apache-log4cxx-0.10.0/src/main/include/log4cxx/helpers/bytearrayoutputstream.h .\build_official_2\apache-log4cxx-0.10.0/src/main/include/log4cxx/helpers/bytearrayoutputstream.h 
40a41 
>   LOG4CXX_LIST_DEF(ByteList, unsigned char); 
44c45 
<     LOG4CXX_LIST_DEF(ByteList, unsigned char); 
--- 
>     
diff -r .\archives\apache-log4cxx-0.10.0/src/main/include/log4cxx/helpers/simpledateformat.h .\build_official_2\apache-log4cxx-0.10.0/src/main/include/log4cxx/helpers/simpledateformat.h 
45a46 
>   LOG4CXX_LIST_DEF(PatternTokenList, log4cxx::helpers::SimpleDateFormatImpl::PatternToken*); 
78c79 
<     LOG4CXX_LIST_DEF(PatternTokenList, log4cxx::helpers::SimpleDateFormatImpl::PatternToken*); 
--- 
>     
diff -r .\archives\apache-log4cxx-0.10.0/src/main/include/log4cxx/helpers/socketoutputstream.h .\build_official_2\apache-log4cxx-0.10.0/src/main/include/log4cxx/helpers/socketoutputstream.h 
35c35 
< 
--- 
>    LOG4CXX_LIST_DEF(ByteList, unsigned char); 
53c53 
<       LOG4CXX_LIST_DEF(ByteList, unsigned char); 
--- 
>       

diff -r .\archives\apache-log4cxx-0.10.0/src/main/include/log4cxx/net/sockethubappender.h .\build_official_2\apache-log4cxx-0.10.0/src/main/include/log4cxx/net/sockethubappender.h 
105c105 
< 
--- 
>    LOG4CXX_LIST_DEF(ObjectOutputStreamList, log4cxx::helpers::ObjectOutputStreamPtr); 
115c115 
<       LOG4CXX_LIST_DEF(ObjectOutputStreamList, log4cxx::helpers::ObjectOutputStreamPtr); 
--- 
>       
diff -r .\archives\apache-log4cxx-0.10.0/src/main/include/log4cxx/net/telnetappender.h .\build_official_2\apache-log4cxx-0.10.0/src/main/include/log4cxx/net/telnetappender.h 
67c67,69 
<   class LOG4CXX_EXPORT TelnetAppender : public AppenderSkeleton 
--- 
>   typedef log4cxx::helpers::SocketPtr Connection; 
>   LOG4CXX_LIST_DEF(ConnectionList, Connection); 
>   class LOG4CXX_EXPORT TelnetAppender : public AppenderSkeleton 
134,135d135 
<       typedef log4cxx::helpers::SocketPtr Connection; 
<       LOG4CXX_LIST_DEF(ConnectionList, Connection); 
diff -r .\archives\apache-log4cxx-0.10.0/src/main/include/log4cxx/patternlayout.h .\build_official_2\apache-log4cxx-0.10.0/src/main/include/log4cxx/patternlayout.h 
326a327,328 
>  LOG4CXX_LIST_DEF(LoggingEventPatternConverterList, log4cxx::pattern::LoggingEventPatternConverterPtr); 
>  LOG4CXX_LIST_DEF(FormattingInfoList, log4cxx::pattern::FormattingInfoPtr); 
337c339 
<     LOG4CXX_LIST_DEF(LoggingEventPatternConverterList, log4cxx::pattern::LoggingEventPatternConverterPtr); 
--- 
>     
343c345 
<     LOG4CXX_LIST_DEF(FormattingInfoList, log4cxx::pattern::FormattingInfoPtr); 
--- 
>     

diff -r .\archives\apache-log4cxx-0.10.0/src/main/include/log4cxx/rolling/rollingpolicybase.h .\build_official_2\apache-log4cxx-0.10.0/src/main/include/log4cxx/rolling/rollingpolicybase.h 
44a45,46 
>  LOG4CXX_LIST_DEF(PatternConverterList, log4cxx::pattern::PatternConverterPtr); 
>  LOG4CXX_LIST_DEF(FormattingInfoList, log4cxx::pattern::FormattingInfoPtr); 
60c62 
<   LOG4CXX_LIST_DEF(PatternConverterList, log4cxx::pattern::PatternConverterPtr); 
--- 
>   
66c68 
<   LOG4CXX_LIST_DEF(FormattingInfoList, log4cxx::pattern::FormattingInfoPtr); 
--- 
>   
diff -r .\archives\apache-log4cxx-0.10.0/src/main/include/log4cxx/spi/loggingevent.h .\build_official_2\apache-log4cxx-0.10.0/src/main/include/log4cxx/spi/loggingevent.h 
54a55 
>    LOG4CXX_LIST_DEF(KeySet, LogString); 
155c156 
<       LOG4CXX_LIST_DEF(KeySet, LogString); 
--- 
>  
1

链接错误的原因是APR(Apache可移植运行时)库。

在文件atomic\win32\apr_atomic.c,存在的各种互锁函数的调用,形式为:

#if (defined(_M_IA64) || defined(_M_AMD64)) && !defined(RC_INVOKED) 
    return InterlockedIncrement(mem) - 1; 
#else 
    return ((apr_atomic_win32_ptr_fn)InterlockedIncrement)(mem) - 1; 
#endif 

其中apr_atomic_win32_ptr_fn由于编译器生成32位可执行被定义为

typedef WINBASEAPI apr_uint32_t (WINAPI * apr_atomic_win32_ptr_fn) 
(apr_uint32_t volatile *); 

,则使用第二个呼叫。这种转换会导致编译器不识别InterlockedIncrement作为内置函数,并生成对__InterlockedIncrement()的调用,而不是预期的内部函数。

作为临时修复,我编辑了使用与64位版本相同的调用的调用。

+0

我有同样的问题,你有没有找到一个永久性的解决方案,而不是临时的? – Shperb 2014-12-28 17:50:48