Half-Blood Programmer

How To Build Log4cxx In Visual Studio 2010

Daniel mentioned how he managed to build log4cxx in Visual Studio. However, he did not provide more details. So this blog post serves as a detailed explanation.

http://old.nabble.com/Unable-to-build-with-VS2010-td28519743.html

We are going to follow the steps here, http://logging.apache.org/log4cxx/building/vstudio.html. However, we must make changes to adapt to Visual Studio 2010.
Preparation
  1. Download the log4cxx ZIP package from here, http://logging.apache.org/log4cxx/download.html, and extract its content.
  2. Download apr and apr-util ZIP packages from here, http://apr.apache.org/download.cgi.
  3. Now let’s translate the original commands into manual steps,
  unzip apr-1.2.11-win32-src.zip      -> manually extract this zip
  rename apr-1.2.11 apr               -> rename the extracted folder 
  unzip apr-util-1.2.10-win32-src.zip -> manually extract this zip 
  rename apr-util-1.2.10 apr-util     -> rename this folder too 
  cd apache-log4cxx-0.10.0 
  configure                           -> execute configure.bat 
  configure-aprutil                   -> see below*
* as the sed tool is not available on Windows, you must do the following,
  1. Open apr-util\include\apu.hw.
  2. Find the line starting with “#define APU_HAVE_APR_ICONV”.
  3. Change this constant to 0 and save.
  4. Open apr-util\include\apr_ldap.hw.
  5. Find the line starting with “#define APR_HAS_LDAP”
  6. Change this constant to 0.
The changes mean that we won’t use APR ICONV and LDAP support.
Building log4cxx.dll
Now we have to convert *.dsw to *.cxproj. In order to make it smooth, you may launch Visual Studio 2010 and open log4cxx.dsw.
VS will ask if you like to convert everything. Simply click Yes.

xml, apr, and apr-util projects may build without any problem. If apr fails, and you find out _WIN32_WINNT is less than _WIN32_WINNT_WINXP, you may go to its Properties->Configuration Properties->C/C++->Preprocessor. Then you edit Preprocessor Definitions and add  _WIN32_WINNT=_WIN32_WINNT_WINXP.
log4cxx.dll must fail with hundreds of errors. But don’t mind it. The root cause is that VC++ has a bug (http://connect.microsoft.com/VisualStudio/feedback/details/473882/error-message-c-c-optimizing-compiler-stopped-working) and VC++ team decided to generate this error. Well, that forces all of us to take the workaround.
LOG4CXX_LIST_DEF macro is used to define classes. As error C2252 is there, we have to move such macro usages out of any classes. That’s what Daniel meant in point 1.
Point 2 is necessary because we moved the nested classes out of their parent classes. Now we can use KeySet instead of LoggingEvent::KeySet. 
Point 3 and 4 are also necessary. Note that for point 4 you may find all generated lib/dll from Output panel in Visual Studio after building xml, apr, and apr-util. Then you can modify Linker settings for log4cxx to include such folders and lib files.
Once you fixed all things, you should have log4cxx compiled successfully on your machine.
(Update: Thanks for who has commented this post. You might check out the comments, as many of them are very valuable by providing more details on one of the steps or alternative approaches.)

17 thoughts on “How To Build Log4cxx In Visual Studio 2010

  1. Anonymous

    Thanks for the post. Was looking for this just the other day and was able to follow your steps to compile. You reference Daniel Andrade’s thread reply at the top of your blog post, but I wish further down (“Point 3 and 4…”) I wouldn’t have had to reference the other blog for instructions. Your post should be standalone in case the old nabble thread ever goes away.

    It’s also interesting that you go into detail about extracting and renaming apr and aprutil… but then hand-wave modifying the linker settings. Updating those settings is trivial but it seems inconsistent that you don’t walks us the whole way home. :)

    I wish the updated version was posted somewhere so I wouldn’t have had to do the conversion myself.

    Again, thanks for the help. Cheers!

  2. Anonymous

    thanks man. I’ve been struggling with this VC++ build for several hours till i encountered your setp by step post that really understands what it posts… This was bottom line helpful!

  3. Anonymous

    There is another way to fix the LOG4CXX_LIST_DEF macro. Comment out the “#if defined(_MSC_VER) && !defined(LOG4CXX_STATIC) && defined(LOG4CXX)” and “#elif defined(_MSC_VER) && !defined(LOG4CXX_STATIC)” blocks in log4cxx.h and use the contents of the “#else” block to define the LOG4CXX_PTR_DEF and LOG4CXX_LIST_DEF macros as typedefs.

    Unfortunately, this will get you C4251 warnings in your code, but it might be an easier way to resolve the issue.

  4. X12334

    works great when I combine this with Daniel post and convert the apr.dsw and apr-util.dsw files before opening log4cxx.dsw.
    I also needed to use log4cxx.h and log4cxx_private.h from trunk in SVN.

  5. john k

    I used Anon @ Nov 11, 2011 idea to change the log4cxx.h #if #elif #else block. Instead of commenting portions out, I just used the _MSC_VER to change behavior for VS2010+. The block is now:
    ——
    #if defined(_MSC_VER) && _MSC_VER < 1600 && !defined(LOG4CXX_STATIC) && defined(LOG4CXX)
    #define LOG4CXX_PTR_DEF(T) \
    template class LOG4CXX_EXPORT log4cxx::helpers::ObjectPtrT; \
    typedef log4cxx::helpers::ObjectPtrT T##Ptr
    #define LOG4CXX_LIST_DEF(N, T) \
    template class LOG4CXX_EXPORT std::allocator; \
    template class LOG4CXX_EXPORT std::vector; \
    typedef std::vector N
    //
    // pointer and list definition macros when linking with DLL using VC
    //
    #elif defined(_MSC_VER) && _MSC_VER < 1600 && !defined(LOG4CXX_STATIC)
    #define LOG4CXX_PTR_DEF(T) \
    extern template class LOG4CXX_EXPORT log4cxx::helpers::ObjectPtrT; \
    typedef log4cxx::helpers::ObjectPtrT T##Ptr
    #define LOG4CXX_LIST_DEF(N, T) \
    extern template class LOG4CXX_EXPORT std::allocator; \
    extern template class LOG4CXX_EXPORT std::vector; \
    typedef std::vector N
    //
    // pointer and list definition macros for all other cases
    //
    #else
    #define LOG4CXX_PTR_DEF(T) typedef log4cxx::helpers::ObjectPtrT T##Ptr
    #define LOG4CXX_LIST_DEF(N, T) typedef std::vector N
    #endif

    ——

  6. john k

    In case the referenced nabble link goes away, here’s the relevant post from Daniel L. Andrade:
    —————-
    Hi Cory,

    This is how I did it:

    1. Move all those LOG4CXX_LIST_DEF macros before the class definition.

    in telnetappender.h you will also need to move the typedef that precedes this
    macro.

    2. If the compiler complains about KeySet not being member of LoggingEvent,
    just remove the scope (since we moved the type to outside the class in the
    previous step, these types no longer are inside the class)
    ex:
    change: LoggingEvent::KeySet set;
    to: KeySet set;

    3. If the compiler complains about insert_iterator not being in the namespace
    std, add
    #include
    to the include section of the source file

    4. For some reason the VS2010 converter ‘forgot’ to reference the lib files
    from apr,apr-util and xml, so i had to add them manually.

    Hope it helps,

    Daniel
    ——————

  7. Anonymous

    Hi,

    the line starting from “unzip apr-1.2.11-win32-src.zip -> manually extract this zip” does not wrap properly in Firefox (I’m using 11.0 on Windows right now) – it is displayed as a long line, while giving a horizontal scroll bar, while wrapping in Google Chrome. Please fix it on Firefox.

    Regards,

    – Shlomi Fish ( http://www.shlomifish.org/ )

  8. Seve

    I fixed all errors and succeeded in compiling it with VS2010 … I could upload my vs solution if anyone is interested. Just send me a mail to [email protected] :)