title: Undefined reference to Logger::getInstance() - but only in some cases
body: <p>I'm using log4cplus (compiled from current git master), but i get undefined reference errors by the linker. However, these errors occur <em>only at some classes</em>.</p>
  
  <p>In general each class has the following form:</p>
  
  <h3>Header (.h)</h3>
  
  <pre><code>// ...
  #include &lt;log4cplus/loggingmacros.h&gt;
  // ...    
  // namespace(s)
  
  class Example
  {
  public:
      // ...
  private:
      // ...
      static const log4cplus::Logger logger;
  };
  </code></pre>
  
  <h3>Source (.cpp)</h3>
  
  <pre><code>// includes
  
  // namespace(s)
  
  // implementations
  
  const log4cplus::Logger Example::logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("Example"));
  </code></pre>
  
  <h3>Usage</h3>
  
  <p>The logger is used within the class like this:</p>
  
  <pre><code>LOG4CPLUS_WARN(logger,  "Ha, ha – whatever you try I wont work!");
  </code></pre>
  
  <p>While compiling works, the linker raises an undefined reference error for</p>
  
  <pre><code>log4cplus::Logger::getInstance(std::string const&amp;)
  </code></pre>
  
  <p>and</p>
  
  <pre><code>log4cplus::detail::macro_forced_log(log4cplus::Logger const&amp;, int, std::string const&amp;, char const*, int, char const*)
  </code></pre>
  
  <p>for some classes. I've already copied the logger-parts from working classes: same result.</p>
  
  <p>Replacing the static logger by a class-member doesn't work neither – <code>getInstance()</code> isn't found.</p>
  
  <p>What workarounds this problem is using the root-logger instead; this will compile / link (even though <code>getRoot()</code> is part of the same class!?):</p>
  
  <pre><code>const log4cplus::Logger Example::logger = log4cplus::Logger::getRoot();
  </code></pre>
  
  <p>But then there's the undefined reference error to</p>
  
  <pre><code>log4cplus::detail::macro_forced_log(...)
  </code></pre>
  
  <hr>
  
  <p>To be sure there's no typo, i've used those macros for declaration / definition:</p>
  
  <pre><code>#define LOG_DECL(name)      static const log4cplus::Logger logger
  #define LOG_DEF(name)       const log4cplus::Logger name::logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT(#name))
  </code></pre>
  
  <p>Same result, those which worked before worked too, and those which not … not.</p>
  
  <hr>
  
  <h3>More information:</h3>
  
  <ol>
  <li>Log4cplus is linked using -llog4cplusSU (also tested with log4cplusS) and was compiled from it's git master</li>
  <li>GCC 4.9 – C++11 is used</li>
  <li>Eclipse CDT for building the project</li>
  <li>Log4cplus is initialized in the main</li>
  <li>All classes are compiled using the same compiler and flags</li>
  <li>Fully clean-and-build project</li>
  <li>All files are compiled / linked the same way</li>
  <li>const / not const has no effect</li>
  </ol>
  
  <p>Result of <code>nm &lt;NAME&gt;.o | grep -i log4cplus</code>:</p>
  
  <p><strong>Working object</strong></p>
  
  <pre><code>                 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
  </code></pre>
  
  <p><strong>Whith undefined references:</strong></p>
  
  <pre><code>                 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
  </code></pre>
  
  <hr>
  
  <h3>Minimal class that fails</h3>
  
  <pre><code>//////////////////////// Header ////////////////////////
  namespace so {
  namespace example {
  
  class FailingExample
  {
  public:
      FailingExample(other_ns::Config* config, other_ns::Command* cmd);
      bool updateData(uint8_t* dataPtr, uint32_t dataSize);
      virtual ~FailingExample();
  
  private:
      static const log4cplus::Logger logger;
  };
  }}
  
  
  //////////////////////// Source ////////////////////////
  namespace so {
  namespace example {
  
  FailingExample::FailingExample(other_ns::Config* config, other_ns::Command* cmd)
  {
  }
  
  bool FailingExample::updateData(uint8_t* dataPtr, uint32_t dataSize)
  {
      return true;
  }
  
  FailingExample::~FailingExample()
  {
  }
  
  // Undefined reference to getInstance() here
  const log4cplus::Logger FailingExample::logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("FailingExample"));
  
  }}
  </code></pre>