在visual studio 2013下构建log4cxx

时间:2014-10-28 15:34:50

标签: visual-studio-2013 log4cxx

我正在尝试在Visual Studio 2013下构建log4cxx版本0.10.0。我已经完成了building log4cxx in vs 2010 c++中指定的所有修复。

但是,在尝试创建log4cxx.lib时,它现在在链接阶段失败,并出现以下错误:

unresolved external symbol __InterlockedIncrement referenced in function _apr_atomic_inc32@4
unresolved external symbol __InterlockedExchangeAdd referenced in function _apr_atomic_add32@8
unresolved external symbol __InterlockedExchange referenced in function _apr_atomic_set32@8
unresolved external symbol __InterlockedDecrement referenced in function _apr_atomic_dec32@4
unresolved external symbol __InterlockedCompareExchange referenced in function _apr_atomic_cas32@12

根据MSDN,这些函数应该在kernel32.lib中,我已经将它添加到链接器中,没有任何效果。查看ht elib,这似乎包含_InterlockedIncrement(单个下划线)和_imp_InterlockedIncrement

有谁知道我能做些什么才能让它发挥作用?

此外,Building log4cxx with VS 2012 on Windows 7中建议的修复不会产生任何不同的

3 个答案:

答案 0 :(得分:3)

以下过程是在VS2013下为32位和64位构建构建Log4CXX的完整过程。请注意,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. 构建项目。
  14. 以下是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 :(得分:1)

链接错误的原因是APR(Apache Portable Runtime)库。

在文件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定义为

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

由于编译器正在构建32位可执行文件,因此使用第二个调用。此转换使编译器不会将InterlockedIncrement识别为内置,并生成对__InterlockedIncrement()的调用,而不是预期的内在调用。

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

答案 2 :(得分:0)

关于log4cxx,以下是有用的:

VS2013 APR link issue