jeudi 3 septembre 2015

Undefined reference to Logger::getInstance() - but only in some cases

I'm using log4cplus (compiled from current git master), but i get undefined reference errors by the linker. However, these errors occur only at some classes.

In general each class has the following form:

Header (.h)

// ...
#include <log4cplus/loggingmacros.h>
// ...    
// namespace(s)

class Example
{
public:
    // ...
private:
    // ...
    static const log4cplus::Logger logger;
};

Source (.cpp)

// includes

// namespace(s)

// implementations

const log4cplus::Logger Example::logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("Example"));

Usage

The logger is used within the class like this:

LOG4CPLUS_WARN(logger,  "Ha, ha – whatever you try I wont work!");

While compiling works, the linker raises an undefined reference error for

log4cplus::Logger::getInstance(std::string const&)

and

log4cplus::detail::macro_forced_log(log4cplus::Logger const&, int, std::string const&, char const*, int, char const*)

for some classes. I've already copied the logger-parts from working classes: same result.

Replacing the static logger by a class-member doesn't work neither – getInstance() isn't found.

What workarounds this problem is using the root-logger instead; this will compile / link (even though getRoot() is part of the same class!?):

const log4cplus::Logger Example::logger = log4cplus::Logger::getRoot();

But then there's the undefined reference error to

log4cplus::detail::macro_forced_log(...)


To be sure there's no typo, i've used those macros for declaration / definition:

#define LOG_DECL(name)      static const log4cplus::Logger logger
#define LOG_DEF(name)       const log4cplus::Logger name::logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT(#name))

Same result, those which worked before worked too, and those which not … not.


More information:

  1. Log4cplus is linked using -llog4cplusSU (also tested with log4cplusS) and was compiled from it's git master
  2. GCC 4.9 – C++11 is used
  3. Eclipse CDT for building the project
  4. Log4cplus is initialized in the main
  5. All classes are compiled using the same compiler and flags
  6. Fully clean-and-build project
  7. All files are compiled / linked the same way
  8. const / not const has no effect

Result of nm <NAME>.o | grep -i log4cplus:

Working object

                 U _ZN9log4cplus6detail16macro_forced_logERKNS_6LoggerEiRKSbIwSt11char_traitsIwESaIwEEPKciSB_
0000000000000000 W _ZN9log4cplus6detail17macros_get_loggerERKNS_6LoggerE
                 U _ZN9log4cplus6detail18get_macro_body_ossEv
                 U _ZN9log4cplus6Logger11getInstanceERKSbIwSt11char_traitsIwESaIwEE
                 U _ZN9log4cplus6LoggerC1ERKS0_
                 U _ZN9log4cplus6LoggerD1Ev
00000000000002c8 r _ZN9log4cplusL13ALL_LOG_LEVELE
00000000000002ac r _ZN9log4cplusL13OFF_LOG_LEVELE
00000000000002bc r _ZN9log4cplusL14INFO_LOG_LEVELE
00000000000002b8 r _ZN9log4cplusL14WARN_LOG_LEVELE
00000000000002c0 r _ZN9log4cplusL15DEBUG_LOG_LEVELE
00000000000002b4 r _ZN9log4cplusL15ERROR_LOG_LEVELE
00000000000002b0 r _ZN9log4cplusL15FATAL_LOG_LEVELE
00000000000002c4 r _ZN9log4cplusL15TRACE_LOG_LEVELE
00000000000002cc r _ZN9log4cplusL17NOT_SET_LOG_LEVELE
                 U _ZNK9log4cplus6Logger12isEnabledForEi

Whith undefined references:

                 U _ZN9log4cplus6detail16macro_forced_logERKNS_6LoggerEiRKSsPKciS7_
0000000000000000 W _ZN9log4cplus6detail17macros_get_loggerERKNS_6LoggerE
                 U _ZN9log4cplus6detail18get_macro_body_ossEv
                 U _ZN9log4cplus6Logger11getInstanceERKSs
                 U _ZN9log4cplus6LoggerC1ERKS0_
                 U _ZN9log4cplus6LoggerD1Ev
00000000000001ec r _ZN9log4cplusL13ALL_LOG_LEVELE
00000000000001d0 r _ZN9log4cplusL13OFF_LOG_LEVELE
00000000000001e0 r _ZN9log4cplusL14INFO_LOG_LEVELE
00000000000001dc r _ZN9log4cplusL14WARN_LOG_LEVELE
00000000000001e4 r _ZN9log4cplusL15DEBUG_LOG_LEVELE
00000000000001d8 r _ZN9log4cplusL15ERROR_LOG_LEVELE
00000000000001d4 r _ZN9log4cplusL15FATAL_LOG_LEVELE
00000000000001e8 r _ZN9log4cplusL15TRACE_LOG_LEVELE
00000000000001f0 r _ZN9log4cplusL17NOT_SET_LOG_LEVELE
                 U _ZNK9log4cplus6Logger12isEnabledForEi

Aucun commentaire:

Enregistrer un commentaire