title: C symbol visibility in static archives
body: <p>I have files foo.c bar.c and baz.c, plus wrapper code myfn.c  defining a function myfn() that uses code and data from those other files.</p>
  
  <p>I would like to create something like an object file or archive, myfn.o or libmyfn.a, so that myfn() can be made available to other projects without also exporting a load of symbols from {foo,bar,baz}.o as well.</p>
  
  <p>What's the right way to do that in Linux/gcc?  Thanks.</p>
  
  <hr>
  
  <p>Update: I've found one way of doing it.  I should've emphasised originally that this was about static archives, not DSOs.  Anyway, the recipe:</p>
  
  <ol>
  <li><p><code>#define PUBLIC __attribute__ ((visibility("default")))</code> then mark <code>myfn()</code> as <code>PUBLIC</code> in <code>myfn.c</code>.  Don't mark anything else <code>PUBLIC</code>.</p></li>
  <li><p>Compile objects with <code>gcc -c foo.c bar.c baz.c myfn.c -fvisibility=hidden</code>, which marks everything as hidden except for <code>myfn()</code>.</p></li>
  <li><p>Create a convenience archive using <code>ld</code>'s partial-linking switch: <code>ld -r foo.o bar.o baz.o myfn.o -o libmyfn.a</code></p></li>
  <li><p>Localise everything that wasn't <code>PUBLIC</code> like so: <code>objcopy --localize-hidden libmyfn.a</code></p></li>
  <li><p>Now <code>nm</code> says <code>myfn</code> is the only global symbol in <code>libmyfn.a</code> and subsequent linking into other programs works just fine: <code>gcc -o main main.c -L. -lmyfn</code> (here, the program calls <code>myfn()</code>; if it tried to call <code>foo()</code> then compilation would fail).</p></li>
  </ol>
  
  <p>If I use <code>ar</code> instead of <code>ld -r</code> in step 3 then compilation fails in step 5: I guess <code>ar</code> hasn't linked <code>foo</code> etc to <code>myfn</code>, and no longer can once those functions are localised, whereas <code>ld -r</code> resolves the link before it gets localised-away.</p>
  
  <p><strong>I'd welcome any response that confirms this is the "right" way, or describes a slicker way of achieving the same.</strong></p>