title: Passing `-l<libname>` vs passing `lib<libname>.a` directly to linker?
body: <p>Suppose I have two files</p>
  
  <pre><code>// a.c
  int a() {return 1;}
  
  // b.c
  int a();
  int b() {return a();}
  </code></pre>
  
  <p>and I compile them to <code>a.o</code> and <code>b.o</code>, respectively.</p>
  
  <p>In an attempt to make an executable or shared library, one can call <code>gcc a.o b.o -o libab.so -shared</code>. But I also noticed that one can also call <code>gcc b.o -L. -l:a.o -o libab.so -shared</code> to generate (apparently) the same output. To my surprise, even running <code>gcc a.o -L. -l:b.o -shared</code> results in a library that has both <code>a()</code> and <code>b()</code>. (Shouldn't linker discard the unused library <code>b.o</code> since <code>a.o</code> does not depend on it?)</p>
  
  <p>The latter two presumably pass <code>a</code> in as if <code>a.o</code> was a library. Now if I run <code>ar rcs liba.a a.o</code>, <code>gcc b.o -L. -l:liba.a -shared</code> and <code>gcc b.o liba.a -shared</code> both run without any problem and give the same output.</p>
  
  <p>However, I have also seen case where this trick doesn't work and results undefined references. My question is therefore as the titles says: what are the differences between passing an object as a library and as a normal object file, and are there any differences when it comes to C++?</p>
  
  <p><em>The problem arose in a much larger project. Sorry for lacking mcve because I can't seem to isolate the problem.</em></p>