title: Why does GNU ld resolve symbols differently when linking executables vs shared objects?
body: <p>I have a trivial piece of C++ code that looks something like this:</p>
  
  <pre><code>#include &lt;boost/timer/timer.hpp&gt;
  
  int main(void) {
      boost::timer::auto_cpu_timer t;
      return 0;
  }
  </code></pre>
  
  <p>I tried to compile and link it (with gcc 4.8.1 and GNU ld 2.23.52.20130828) as follows:</p>
  
  <pre><code>$ g++ -o test test.cc -lboost_timer
  /usr/bin/ld: /tmp/cc2jP1jv.o: undefined reference to symbol '_ZN5boost6system15system_categoryEv'
  /usr/lib/libboost_system.so.1.54.0: error adding symbols: DSO missing from command line
  collect2: error: ld returned 1 exit status
  </code></pre>
  
  <p>One solution is to explicitly mention <code>-lboost_system</code> on the command line, and that works. However, I can also do:</p>
  
  <pre><code>$ g++ -Wl,--copy-dt-needed-entries -o test test.cc -lboost_timer
  </code></pre>
  
  <p>According to the ld documentation "with --copy-dt-needed-entries dynamic libraries mentioned on the command line will be recursively searched, following their DT_NEEDED tags to other libraries, in order to resolve symbols required by the output binary", so this all makes sense: ld is figuring out from boost_timer that it also needs to link against boost_system in order to resolve all the symbols.</p>
  
  <p>However, I realised that this also works:</p>
  
  <pre><code>$ g++ -fPIC -shared -o test test.cc -lboost_timer
  </code></pre>
  
  <p>Obviously, I've now generated a shared object rather than an executable. Apparently, though, ld was able to figure out that it needed to link the shared object against boost_system:</p>
  
  <pre><code>$ ldd test | grep boost_system
          libboost_system.so.1.54.0 =&gt; /usr/lib/libboost_system.so.1.54.0 (0x00007f385246e000)
  </code></pre>
  
  <p>So my question is this: why is symbol resolution different when building a shared object versus an executable? How is ld able to figure out that my shared object should be linked against boost_system without my specifying <code>--copy-dt-needed-entries</code>? </p>