在 Visual Studio 2013 下构建 log4cxx

3
我正在尝试在Visual Studio 2013下构建log4cxx版本0.10.0。我已经按照在vs 2010 c++中构建log4cxx中指定的所有修复方法进行了操作。
然而,在尝试创建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 中,我已经将其添加到链接器中,但没有任何效果。查看库文件,发现其中包含 _InterlockedIncrement(带有单个下划线)和 _imp_InterlockedIncrement
有人知道我该怎么做才能让它正常工作吗?
另外,在 Windows 7 上使用 VS 2012 构建 log4cxx 提出的解决方法没有任何作用。
3个回答

5

以下步骤是在VS2013下构建Log4CXX的完整过程,适用于32位和64位版本。请注意,32位版本只进行了轻微测试,而64位版本进行了稍微更多的测试(即,这是我们正在使用的版本)。

  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项目,然后选择属性
    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);
---
>       

2
链接错误的原因是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位版本相同的调用。


我也遇到了同样的问题,你找到了一个永久性的解决方法而不是临时的吗? - Shperb

0

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