title: Linker and dependencies
body: <p>For a Linux/g++ project, I have a helper library ("libcommon.a") that I wrote that is used in two different programs ("client" and "server").  One particular source file among several, oshelper.cpp, has a set of unrelated utility functions:</p>
  
  <pre><code>// header file
  #ifndef OSHELPER_H
  #define OSHELPER_H
      size_t GetConsoleWidth();
      uint32_t GetMillisecondCounter();
  #endif
  
  // -----------------------------------------
  // Code file
  #include "commonincludes.h"
  #include "oshelper.h"
  
  size_t GetConsoleWidth()
  {
      struct winsize ws = {};
      ioctl(0, TIOCGWINSZ, &amp;ws);
      return ws.ws_col;
  }
  
  uint32_t GetMillisecondCounter()
  {
      timespec ts={};
      clock_gettime(CLOCK_MONOTONIC, &amp;ts);
      return (uint32_t)(ts.tv_nsec / 1000000 + ts.tv_sec * 1000);
  }
  </code></pre>
  
  <p>Both programs link to the library that contains these functions (libcommon.a or -lcommon).  </p>
  
  <p>"client" program calls both the GetConsoleWidth and GetMillisecondCounter function.  And since GetMillisecondCounter ultimately depends on a call to "clock_gettime", <strong>-lrt</strong> is a required parameter to the linker such that librt is linked in.  This is expected.</p>
  
  <p>"server" just calls GetConsoleWidth.  It never calls GetMillisecondCounter. But without "-lrt" being passed, the linker complains about the unresolved reference to clock_gettime.  Which is obviously fixed by passing -lrt to g++. And then "ldd server" shows that librt.so.1 is still a runtime dependency. So the linkage to clock_gettime clearly did not get optimized away.</p>
  
  <p>But when I separate the implementation of GetConsoleWidth into a <strong>seperate</strong> source file (but still part of libcommon.a), the linker stops complaining about the unresolved reference to clock_gettime and no longer insists that I pass in <strong>-lrt</strong>.</p>
  
  <p>It's as if the g++ linker can only cull out unused object files, but not unused function calls.</p>
  
  <p>What's going on here?</p>
  
  <p>Update: the compiler and linker command lines are as basic as they can get:</p>
  
  <pre><code>g++ -c oshelper.cpp
  g++ -c someotherfile.cpp
  etc...
  ar -rv libcommon.a oshelper.o someotherfile.o ...
  
  g++ server.cpp -lcommon -lpthread -o server
  g++ client.cpp -lcommon -lrt -o client
  </code></pre>