title: Removing symbols from `.a`s
body: <p>I'm compiling a C++ static library using <code>g++</code> via Cmake. I want to remove symbols relating to the internal implementation so they don't show up in <code>nm</code>. (See <a href="https://gcc.gnu.org/wiki/Visibility" rel="nofollow noreferrer">here</a> and <a href="https://cmake.org/cmake/help/v3.0/module/GenerateExportHeader.html" rel="nofollow noreferrer">here</a> for the same with shared libraries.) </p>
  
  <p><a href="https://stackoverflow.com/questions/3276474/symbol-hiding-in-static-libraries-built-with-xcode-gcc/18949281#18949281">This answer</a> tells you how to do it on iOS, and I'm trying to understand what happens under the hood so I can replicate on Linux. They invoke <code>ld</code> with:</p>
  
  <ul>
  <li><code>-r</code>/<code>--relocatable</code> to Generate relocatable output---i.e., generate an output file that can in turn serve as input to ld.</li>
  <li><code>-x</code>/<code>--discard-all</code>: Delete all local symbols.</li>
  </ul>
  
  <p>AFAICS the <code>-r</code> glues all the modules into one module, and then the <code>-x</code> removes symbols only used inside that module. Is that right?</p>
  
  <p>It's not clear how the linker 'knows' which symbols will be exported externally? Does it rely on  <code>__attribute__((visibility("hidden/default")))</code> as in the <code>.so</code> case?</p>
  
  <p>Edit: clearly I'm confused... I thought cmake invoked <code>ld</code> to link the <code>.o</code>s into <code>.a</code>. Googled + clarified above. </p>
  
  <p>Question still stands: how do I modify the build process to exclude most symbols?</p>