title: Undefined reference when compiling against libraries generated by Automake
body: <p>I am having a pretty strange linking error in a project that uses automake. What I do seems pretty simple from the manual, so I really wonder what I can doing wrong ... </p>
  
  <p>My project has three folders : </p>
  
  <ul>
  <li>src/common, in which I compile a number of C++ files into a libube-common.a static lib</li>
  <li>src/engine, in which I compile a number of files into a libube-engine.a static lib</li>
  <li>src/client, in which ... you guessed it, libue-client.a , and also one file ube.cpp that is my main</li>
  </ul>
  
  <p>Each of the libraries is compiled with a Makefile.am like this : </p>
  
  <pre><code>noinst_LIBRARIES=libube-common.a
  libube_common_a_SOURCES=gettext.h lua_helper.hpp \
   silent_ostream.hpp \
   logging.hpp logging.cpp \
   logger_interface.hpp \
       ... etc ...
  AM_CPPFLAGS=-DSRCDIR=\"${srcdir}\" \
   -DLUADIR=\"${luadir}\" \
   -Wall -Werror \
   -I$(srcdir)/../../include \
   $(LUA_INCLUDE) \
   $(BOOST_CPPFLAGS)
  </code></pre>
  
  <p>This results in the various objects being built with a line like : </p>
  
  <pre><code>g++ -DHAVE_CONFIG_H -I. -I../../../../../src/common -I../..  -DSRCDIR=\"../../../../../src/common\" -DLUADIR=\"\" -Wall -Werror -I../../../../../src/common/../../include -I/usr/include/lua5.1 -I/usr/include   -g -O2 -MT logging.o -MD -MP -MF .deps/logging.Tpo -c -o logging.o ../../../../../src/common/logging.cpp
  </code></pre>
  
  <p>And all of them are put in the library with : </p>
  
  <pre><code>ar cru libube-common.a logging.o prefix_resource_resolver.o stat_file_checker.o 
  ranlib libube-common.a
  </code></pre>
  
  <p>All of this seems good and well, I can even linked some little tests programs against the library (inside the same makefile)</p>
  
  <p>Then, in the Makefile.am of my main program, I asked to link against the local libraries : </p>
  
  <pre><code>ube_LDADD=../common/libube-common.a \
        ../engine/libube-engine.a \
        libube-client.a \
            ... other libs ...
  </code></pre>
  
  <p>And that's where I get errors like this : </p>
  
  <pre><code>g++  -g -O2   -o ube ube.o ../common/libube-common.a ../engine/libube-engine.a libube-   client.a -L/usr/include/lua5.1/lib -llua5.1  -lm -ldl  -L/usr/lib -lSDL -lSDL_image -lpng -ltiff -ljpeg -lz -lSDL_ttf -lfreetype -lSDL_mixer -lSDL_mixer -lSDL_ttf -lSDL_image
  
  libube-client.a(game_loop.o): In function `Logging::debug_ostream(std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;)':
  (...) logging.hpp:54: undefined reference to `Logging::get_ostream(LogLevel::Level, std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;)'
  (...)logging.hpp:54: undefined reference to `Logging::get_ostream(LogLevel::Level, std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;)'
  </code></pre>
  
  <p>At first I though it was because of some static symbols, but I also get the issue with non-static ones.</p>
  
  <p>I checked the generated libs, and it seem to contain the symbol properly : </p>
  
  <pre><code>~/prj/ube/builds/linux/current/src/common$ nm -C libube-common.a  | grep logging.o -C 20
  
  logging.o:
  00000010 t global constructors keyed to _ZN7Logging15disable_loggingEv
  00000000 V guard variable for Logging::get_instance()::s_local_instance
  000000b0 T Logging::get_ostream(LogLevel::Level, std::string)
  00000000 T Logging::disable_logging()
  00000040 T Logging::is_category_enabled(LogLevel::Level, std::string&amp;)
       U std::ios_base::Init::Init()
       U std::ios_base::Init::~Init()
  00000000 b std::__ioinit
       U __cxa_atexit
       U __dso_handle
       U __gxx_personality_v0
  </code></pre>
  
  <p>The only fix is to explicitely link against my .o files (by adding them to the ube_LDADD line ... but that kinda defies the idea of using a library !!)</p>
  
  <p>I seem to have been following the manual : <a href="http://www.gnu.org/software/hello/manual/automake/Linking.html#Linking" rel="nofollow noreferrer">http://www.gnu.org/software/hello/manual/automake/Linking.html#Linking</a> </p>
  
  <p>But ovbiously I messed up somewhere, so any idea is welcome !!</p>
  
  <p>Thanks</p>
  
  <p>PH</p>
  
  <hr>
  
  <p>EDIT : The library in itself seems to work, it seems to be a linking issue. I can link my test cases programs agaist them. Here is what I do : </p>
  
  <p>In folder src/common/tests, there is a main called common-tests.cpp that runs unit tests ; 
  the common-tests bin is linked against the library libube-common.a (it only needs objects that are inside the lib, since those are unit tests)</p>
  
  <pre><code># There is one program that aggreatates all tests cases
  check_PROGRAMS = common-tests
  common_tests_SOURCES= tests/common_tests.cpp \
  tests/prefix_resource_resolver_test.cpp \
  tests/mock_file_checker.hpp \
  tests/stat_file_checker_test.cpp
  
  # The program needs to be compiled against the local lib 
  common_tests_LDADD=libube-common.a -L$(top_srcdir)/lib -lgtest -lgmock -llua -ldl
  
  # This means common-tests is run when using 'make check'.
  TESTS = common-tests
  </code></pre>
  
  <p>When running make check, the test program is compiled this way : </p>
  
  <pre><code>g++  -g -O2   -o common-tests common_tests.o prefix_resource_resolver_test.o stat_file_checker_test.o libube-common.a -L../../../../../lib -lgtest -lgmock -llua -ldl -lSDL_mixer -lSDL_ttf -lSDL_image 
  </code></pre>
  
  <p>And things work perfectly. The only difference I can see is that in this case the library is right next to the executable to link ... could this really make any difference ? </p>
  
  <p>Also, I tried using options like -Wl,--whole-archive but it did not help (plus I don't know how to add them to the Automake-generated line ...)</p>