title: g++ the order of static library matters?
body: <p>I have been struggling all day for this problem. I use some libraries in my project and I always got some compilation errors complaining that <code>undefined reference</code>.</p>
  
  <p>The relevant files are as follows:</p>
  
  <pre><code>encode.cc//the main file
  url_codec.h//the header of the libraries, got some function definition in it
  libimageenc.a
  libmbpicenc.a
  liburlaes.a
  liburldecode.a
  </code></pre>
  
  <p>The makefile is like:</p>
  
  <pre><code>cflags = -Wall -O2 -fPIC
  
  libpath=./libs/
  libs+=$(libpath)liburlaes.a
  libs+=$(libpath)liburldecode.a $(libpath)libimageenc.a $(libpath)libmbpicenc.a
  
  cxx  = g++
  bin  = encode
  
  all: $(bin)
  
  srcs = $(shell ls *.cc *.cpp)
  objs = $(srcs:%.cc=%.o)
  
  $(bin):${objs}
      $(cxx) $(cflags) $(inc) -o $@ ${objs} ${libs}
  
  $(objs):%.o:%.cc
      $(cxx) $(cflags) $(inc) -c -o $@ $&lt;
  
  clean:
      rm -f *.o
      rm -f *.bak
      rm -f $(bin)
  </code></pre>
  
  <p>The g++ compiler complains that:</p>
  
  <pre><code>g++ -Wall -O2 -fPIC  -o encode encode.o ./libs/liburlaes.a ./libs/liburldecode.a ./libs/libimageenc.a ./libs/libmbpicenc.a
  ./libs/liburldecode.a(url_codec.o): In function `url_codec::offpic_url_decode_func(std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, unsigned int&amp;, std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;&amp;, int&amp;)':
  url_codec.cc:(.text+0x18da): undefined reference to `uuid_unparse'
  ./libs/liburldecode.a(crypto_aes.o): In function `encode_aes':
  crypto_aes.cc:(.text+0x4e): undefined reference to `AES_cbc_encrypt'
  ./libs/liburldecode.a(crypto_aes.o): In function `decode_aes':
  crypto_aes.cc:(.text+0xae): undefined reference to `AES_cbc_encrypt'
  ./libs/liburldecode.a(crypto_aes.o): In function `init_aes_encrypt_key':
  crypto_aes.cc:(.text+0xf3): undefined reference to `AES_set_encrypt_key'
  ./libs/liburldecode.a(crypto_aes.o): In function `init_aes_decrypt_key':
  crypto_aes.cc:(.text+0x143): undefined reference to `AES_set_decrypt_key'
  collect2: ld returned 1 exit status
  </code></pre>
  
  <p>But all these function are well defined in liburlaes.a as shown by <code>nm -C</code></p>
  
  <pre><code>    nm -C liburlaes.a | grep -i 'aes'
      decode_byaes.o:
           U AES_cbc_encrypt
           U AES_set_decrypt_key
           U AES_set_encrypt_key
  00000060 T decode_byaes
  00000000 T encode_byaes
  00000110 T init_byaes_decrypt_key
  000000c0 T init_byaes_encrypt_key
           U decode_byaes
           U encode_byaes
           U init_byaes_decrypt_key
           U init_byaes_encrypt_key
  </code></pre>
  
  <p>Things won't get better by moving the <code>liburlaes.a</code> to the end of <code>libs</code>, the output is exactly as above. And move <code>libimageenc</code> backward will make it worse, with more symbols claimed undefined:</p>
  
  <pre><code>libs+=$(libpath)liburldecode.a $(libpath)libimageenc.a $(libpath)libmbpicenc.a
  libs+=$(libpath)liburlaes.a
  </code></pre>
  
  <p>So, how can I fix this?</p>
  
  <p><strong>UPDATES</strong></p>
  
  <p>I tried to put the <code>liburlaes.a</code> in both side, but it doesn't work, I wrap the libaray with '**' to emphasize :</p>
  
  <pre><code>g++ -Wall -O2 -fPIC  -o encode encode.o **./libs/liburlaes.a** ./libs/liburldecode.a ./libs/libimageenc.a ./libs/libmbpicenc.a **./libs/liburlaes.a**
  ./libs/liburldecode.a(url_codec.o): In function `url_codec::offpic_url_decode_func(std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, unsigned int&amp;, std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;&amp;, int&amp;)':
  url_codec.cc:(.text+0x18da): undefined reference to `uuid_unparse'
  ./libs/liburldecode.a(crypto_aes.o): In function `encode_aes':
  crypto_aes.cc:(.text+0x4e): undefined reference to `AES_cbc_encrypt'
  ./libs/liburldecode.a(crypto_aes.o): In function `decode_aes':
  crypto_aes.cc:(.text+0xae): undefined reference to `AES_cbc_encrypt'
  ./libs/liburldecode.a(crypto_aes.o): In function `init_aes_encrypt_key':
  crypto_aes.cc:(.text+0xf3): undefined reference to `AES_set_encrypt_key'
  ./libs/liburldecode.a(crypto_aes.o): In function `init_aes_decrypt_key':
  crypto_aes.cc:(.text+0x143): undefined reference to `AES_set_decrypt_key'
  collect2: ld returned 1 exit status
  make: *** [encode] Error 1
  </code></pre>