title: Explanation sought: libtool, automake, shared libraries (and Fortran)
body: <p>The problem I had is solved. I'm posting this to solicit an explanation as to why the solution actually works. I've gotten great feedback here before. </p>
  
  <p>I have a legacy code base that used a very simplistic build system, and my project is to migrate that to Autotools for customization and, particularly, building shared libraries. The main library is written in C, but must also be linkable from Fortran (for legacy purposes), and is distributed with some test codes in F77. The authors organized the source code into modules...</p>
  
  <pre><code>src_module1/
  src_module2/
  ...
  testc/
  testf77/
  </code></pre>
  
  <p>Their built the library <code>lib/libmain.a</code> by compiling code in the src_*/ directories and archiving the objects with ranlib.</p>
  
  <p>My first approach was to build a shared library from each src_*/ separately and "link" all of these into one shared library. Using Autotools, the <code>src_module1/Makefile.am</code> would contain </p>
  
  <pre><code>noinst_LTLIBRARIES = libmodule1.la
  libmodule1_la_SOURCES = ...
  </code></pre>
  
  <p>and so on for the other modules, and finally the <code>lib/Makefile.am</code> would need only:</p>
  
  <pre><code>lib_LTLIBRARIES = libmain.la
  libmain_la_SOURCES =
  libmain_la_LIBADD = $(top_srcdir)/src_module1/libmodule1.la ...
  </code></pre>
  
  <p>This seemed to work perfectly. However, when the code in testc/ was compiled and linked against libmain.la, a "symbols not found" error was issued. </p>
  
  <p>Thinking that this was an issue with libtool or shared libraries, I tried building static only, basically changing all <code>.la</code> to <code>.a</code> and all <code>_LTLIBRARIES</code> to <code>_LIBRARIES</code>. Same problem. This time, however, noticing the error "ranlib: warning for library: libmain.a the table of contents is empty (no object file members in the library define global symbols)" when trying to link libmain.a itself.</p>
  
  <p>The solution that I found seems like a hack. I did not build Makefiles for any of the src_*/ directories, but instead used only for the lib/ directory and its Makefile.am had the lines:</p>
  
  <pre><code>lib_LTLIBRARIES = libmain.la
  libmain_la_SOURCES = [all sources from all ../src_modules/ ]
  </code></pre>
  
  <p>This worked. The compiled programs in testc/ linked against libmain.la without issue. One of the "modules" is a set of Fortran bindings that wrap other C functions in the library. Even the Fortran codes in testf77/ linked against libmain.la properly.</p>
  
  <p>Could someone carefully explain what happens when libtool builds a shared library? Or even when building a static library? Why is it that several static libraries can't be linked together to make one static library? Why are symbols only available when libtool/ranlib builds the library "from sources"? And what about installing a shared/static library, i.e. moving it to the /usr/local/lib --- what happens there? The Wikipedia article on static and shared libraries isn't really detailed enough for me.</p>
  
  <p>I do appreciate all efforts to make sense of my longwinded question.</p>