linuxlinkericu

GCC links to library that does not exist


Will two libraries together produce a third library that does not even exist?

Try it here

Make sure there are icu and g++ on your machine

Output

ldd out1:
    linux-vdso.so.1 (0x00007ffd5cdaf000)
    liblcf.so.0 => /home/aleck099/.local/lib/liblcf.so.0 (0x00007ff200600000)
    libicuuc.so.72 => /usr/lib/libicuuc.so.72 (0x00007ff200200000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007ff1ffe00000)
    libm.so.6 => /usr/lib/libm.so.6 (0x00007ff200518000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007ff2008a1000)
    libc.so.6 => /usr/lib/libc.so.6 (0x00007ff1ffc19000)
    libicui18n.so.71 => not found
    libicuuc.so.71 => not found
    libicudata.so.71 => not found
    libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007ff200874000)
    libicudata.so.72 => /usr/lib/libicudata.so.72 (0x00007ff1fde00000)
    /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007ff2008ea000)
ldd out2:
    linux-vdso.so.1 (0x00007ffdfed78000)
    libicui18n.so.72 => /usr/lib/libicui18n.so.72 (0x00007fa088000000)
    libicuuc.so.72 => /usr/lib/libicuuc.so.72 (0x00007fa087c00000)
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007fa087800000)
    libm.so.6 => /usr/lib/libm.so.6 (0x00007fa08834d000)
    libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007fa087fe0000)
    libc.so.6 => /usr/lib/libc.so.6 (0x00007fa087619000)
    libicudata.so.72 => /usr/lib/libicudata.so.72 (0x00007fa085800000)
    /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fa08845e000)

You can see that three "not found"s in the ldd output of out1

They are even duplicates of existing icu libraries

How could this happen?

Other information


Solution

  • It looks like the link command used to create out1 picked up symbols from two different versions of the ICU library: libicuuc.so.71 and libicuuc.so.72. The 71 vs 72 is the version number. Those appear to be two different versions of the shared library that were both in the linker's library path. It's "not found" at ldd time because one copy is not in the runtime shared library search path, and even if it was mixing both is probably a bad idea.

    The solution is likely to inspect your link command and ensure the -L options only include one version/copy of the ICU library.

    EDIT: Linking with verbosity enabled (g++ -v option) will provide additional information about the libraries and paths being used.

    Note that it's possible that some of the shared libraries pulled in by out1 are transitively pulling in the (non-existent) libicuuc.so.71. Comparing your two ldd executable outputs, I would be suspicious of /home/aleck099/.local/lib/liblcf.so.0 (and possibly /usr/lib/libexpat.so.1) that only appear in out1. The following command may help:

    $ ldd /home/aleck099/.local/lib/liblcf.so.0 /usr/lib/libexpat.so.1