title: Libicu, undefined reference while compiling
body: <p>I'm trying to use the lib icu in my shared library.
  So i generate my .so who use libicu functions, this parts works well.</p>
  
  <p>Then i try to compile my main program, using the shared library that i created before. But i get the following error:</p>
  
  <pre><code>release//libstring.so: undefined reference to `u_errorName_53'
  release//libstring.so: undefined reference to `ucnv_toUnicode_53'
  release//libstring.so: undefined reference to `ucnv_close_53'
  release//libstring.so: undefined reference to `ucnv_fromUChars_53'
  release//libstring.so: undefined reference to `udat_open_53'
  release//libstring.so: undefined reference to `udat_parse_53'
  release//libstring.so: undefined reference to `udat_format_53'
  release//libstring.so: undefined reference to `ucnv_toUChars_53'
  release//libstring.so: undefined reference to `ucnv_open_53'
  release//libstring.so: undefined reference to `udat_close_53'
  </code></pre>
  
  <p>I have installed the libicu with <a href="http://www.linuxfromscratch.org/blfs/view/svn/general/icu.html" rel="nofollow">this</a> help.</p>
  
  <p>I compile my shared library with -licuuc, as well as my main program compile only with -l:libstring.so and -licuuc.</p>
  
  <p>When i do ldd libstring.so, i don't have the .so of the libicu on the list of dependencies.</p>
  
  <p>The problem probably come from this.</p>
  
  <p>Thx</p>
  
  <p>EDIT: I have create a little test:</p>
  
  <p>icu.h:</p>
  
  <pre><code>#pragma once
  
  #include &lt;iostream&gt;
  #include &lt;string&gt;
  
  #include &lt;unicode/ucnv.h&gt;
  
  class                     c_icu
  {
  private:
  
          void *             p_priv;
  
  public:
  
          c_icu();
  
          void               open(const wchar_t *name);
  
          void               to_local(std::wstring &amp;, std::wstring &amp;);
          void               from_local(std::wstring &amp;, std::wstring &amp;);
  
          void               close(void);
  
          ~c_icu();
  };
  </code></pre>
  
  <p>icu.cpp:</p>
  
  <pre><code>#include "icu.h"
  
  c_icu::c_icu()
  {
    p_priv = NULL;
  }
  
  c_icu::~c_icu()
  {
    if (p_priv)
      close();
  }
  
  void              c_icu::open(const wchar_t *name)
  {
    UErrorCode      status = U_ZERO_ERROR;
    char            conv_name[256];
  
    if (wcstombs(conv_name, name, 256) == (size_t)-1)
      {
        std::cout &lt;&lt; "ERROR: wcstombs failed" &lt;&lt; std::endl;
        exit(0);
      }
    if ((p_priv = (UConverter *)ucnv_open(conv_name, &amp;status)) == NULL)
      {
        std::cout &lt;&lt; "ERROR: ucnv_open failed" &lt;&lt; std::endl;
        exit(0);
      }
  }
  
  void              c_icu::to_local(std::wstring &amp;src, std::wstring &amp;dst)
  {
    UErrorCode      status = U_ZERO_ERROR;
    int32_t         len;
  
    len = ucnv_toUChars((UConverter *)p_priv, (UChar *)NULL, 0, (const char *)src.c_str(), src.size(), &amp;status);
    if (status == U_BUFFER_OVERFLOW_ERROR)
      {
        status = U_ZERO_ERROR;
        dst.resize(len);
        len = ucnv_toUChars((UConverter *)p_priv, (UChar *)dst.c_str(), dst.size(), (const char *)src.c_str(), src.size(), &amp;status);
        if (U_FAILURE(status))
          {
            std::cout &lt;&lt; "ERROR: to_local failed" &lt;&lt; std::endl;
            exit(0);
          }
      }
  }
  
  void              c_icu::from_local(std::wstring &amp;src, std::wstring &amp;dst)
  {
    UErrorCode      status = U_ZERO_ERROR;
    int32_t         len;
  
    len = ucnv_fromUChars((UConverter *)p_priv, (char *)NULL, 0, (const UChar *)src.c_str(), src.size(), &amp;status);
    if (status == U_BUFFER_OVERFLOW_ERROR)
      {
        status = U_ZERO_ERROR;
        dst.reserve(len);
        len = ucnv_fromUChars((UConverter *)p_priv, (char *)dst.c_str(), dst.size(), (const UChar *)src.c_str(), -1, &amp;status);
      }
  }
  
  void              c_icu::close(void)
  {
    ucnv_close((UConverter *)p_priv);
    p_priv = NULL;
  }
  </code></pre>
  
  <p>test.cpp:</p>
  
  <pre><code>#include "icu.h"
  
  int           main(void)
  {
    c_icu converter;
    std::wstring src = L"";
    std::wstring dst;
    const wchar_t add[11] = L"Just a test";
    const wchar_t *unicode = L"koi8-r";
  
    for (unsigned int i = 0; i &lt; 1000; i++)
      src.append(add, 11);
  
    converter.open(unicode);
    converter.from_local(src, dst);
    converter.close();
  }
  </code></pre>
  
  <p>Makefile:</p>
  
  <pre><code>NAME=           test
  LIB_NAME=       libicutest.so
  FLAGS=          -W -Wall -Wextra
  
  all:    lib $(NAME)
  
  $(NAME):
          @echo "Main programm compiling ..."
          g++ -c test.cpp -o test.o $(FLAGS)
          g++ -o $(NAME) test.o -Wl,-rpath,'$$ORIGIN/' -licui18n -L. -licutest
          @echo "Main programm compiled"
  
  lib:
          @echo "Lib Compiling ..."
          g++ -std=gnu++11 -c -fPIC icu.cpp -o icu.o $(FLAGS)
          g++ -shared -Wl,-soname,$(LIB_NAME) -o $(LIB_NAME) icu.o -licui18n
          @echo "Lib Compiled"
  </code></pre>
  
  <p>Note: even with -licuuc instead of -licui18n i got the same error.</p>
  
  <p>Output:</p>
  
  <pre><code>$&gt; make
  Lib Compiling ...
  g++ -std=gnu++11 -c -fPIC icu.cpp -o icu.o -W -Wall -Wextra
  g++ -shared -Wl,-soname,libicutest.so -o libicutest.so icu.o -licui18n
  Lib Compiled
  Main programm compiling ...
  g++ -c test.cpp -o test.o -W -Wall -Wextra
  g++ -o test test.o -Wl,-rpath,'$ORIGIN/' -licui18n -L. -licutest
  ./libicutest.so: undefined reference to `ucnv_close_53'
  ./libicutest.so: undefined reference to `ucnv_fromUChars_53'
  ./libicutest.so: undefined reference to `ucnv_toUChars_53'
  ./libicutest.so: undefined reference to `ucnv_open_53'
  collect2: error: ld returned 1 exit status
  make: *** [test] Error 1
  </code></pre>
  
  <p>If i do ldd on my shared library:</p>
  
  <pre><code>$&gt; ldd libicutest.so
   linux-vdso.so.1 =&gt;  (0x00007ffd5eb7f000)
   libstdc++.so.6 =&gt; /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f092b5e6000)
   libc.so.6 =&gt; /lib/x86_64-linux-gnu/libc.so.6 (0x00007f092b221000)
   libm.so.6 =&gt; /lib/x86_64-linux-gnu/libm.so.6 (0x00007f092af1a000)
   /lib64/ld-linux-x86-64.so.2 (0x00007f092bb00000)
   libgcc_s.so.1 =&gt; /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f092ad04000)
  </code></pre>
  
  <p>EDIT2:</p>
  
  <p>Ok, seems that the problem is easier to solve than expected. My program need function in icu_53, but i got icu_48 installed on my computer dunno why.</p>
  
  <pre><code>$&gt; locate libicu
  /usr/lib/x86_64-linux-gnu/libicudata.so.48
  /usr/lib/x86_64-linux-gnu/libicudata.so.48.1.1
  /usr/lib/x86_64-linux-gnu/libicui18n.so.48
  /usr/lib/x86_64-linux-gnu/libicui18n.so.48.1.1
  /usr/lib/x86_64-linux-gnu/libicuio.so.48
  /usr/lib/x86_64-linux-gnu/libicuio.so.48.1.1
  /usr/lib/x86_64-linux-gnu/libicule.so.48
  /usr/lib/x86_64-linux-gnu/libicule.so.48.1.1
  /usr/lib/x86_64-linux-gnu/libiculx.so.48
  /usr/lib/x86_64-linux-gnu/libiculx.so.48.1.1
  /usr/lib/x86_64-linux-gnu/libicutest.so.48
  /usr/lib/x86_64-linux-gnu/libicutest.so.48.1.1
  /usr/lib/x86_64-linux-gnu/libicutu.so.48
  /usr/lib/x86_64-linux-gnu/libicutu.so.48.1.1
  /usr/lib/x86_64-linux-gnu/libicuuc.so.48
  /usr/lib/x86_64-linux-gnu/libicuuc.so.48.1.1
  </code></pre>
  
  <p>Does anyone know how to upgrade the version from icu_48 to icu_53 at least ?</p>