C++ Linker links to wrong Boost version

I’m not sure whether this is the correct spot for a question like this, but here we go.

Today I updated Tumbleweed to 20200901, which brought me Boost 1.74. Unfortunately, it left some bits and pieces of Boost 1.71 on my system since some applications (e.g. ncmpcpp) depend on it. The problem I now have is that my linker seems to prefer to link against Boost 1.71 - even though the library in question is not present on my system anymore. Here is a curious example:

I have a library, say, liba.so, which links to various Boost components. Here is what ldd shows:

ldd liba.so 
        linux-vdso.so.1 (0x00007ffe861fd000)
        libboost_iostreams.so.1.74.0 => /usr/lib64/libboost_iostreams.so.1.74.0 (0x00007f320f6e3000)
        libboost_log.so.1.74.0 => /usr/lib64/libboost_log.so.1.74.0 (0x00007f320f63f000)
        libboost_filesystem.so.1.74.0 => /usr/lib64/libboost_filesystem.so.1.74.0 (0x00007f320f622000)
        libboost_program_options.so.1.74.0 => /usr/lib64/libboost_program_options.so.1.74.0 (0x00007f320f5e1000)
        libboost_timer.so.1.74.0 => /usr/lib64/libboost_timer.so.1.74.0 (0x00007f320f5d8000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f320f5b6000)
        libboost_atomic.so.1.74.0 => /usr/lib64/libboost_atomic.so.1.74.0 (0x00007f320f5ab000)
        libboost_regex.so.1.74.0 => /usr/lib64/libboost_regex.so.1.74.0 (0x00007f320f4d7000)
        libboost_thread.so.1.74.0 => /usr/lib64/libboost_thread.so.1.74.0 (0x00007f320f4b6000)
        libboost_chrono.so.1.74.0 => /usr/lib64/libboost_chrono.so.1.74.0 (0x00007f320f4ac000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f320f2d0000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f320f18b000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f320f16f000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f320efa8000)
        libz.so.1 => /lib64/libz.so.1 (0x00007f320ef8e000)
        libbz2.so.1 => /usr/lib64/libbz2.so.1 (0x00007f320ef6d000)
        librt.so.1 => /lib64/librt.so.1 (0x00007f320ef62000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f320f8bd000)
        libicui18n.so.67 => /usr/lib64/libicui18n.so.67 (0x00007f320ec53000)
        libicuuc.so.67 => /usr/lib64/libicuuc.so.67 (0x00007f320ea69000)
        libicudata.so.67 => /usr/lib64/libicudata.so.67 (0x00007f320ea66000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f320ea60000)

So far, so innocent - only Boost 1.74 is used, which is exactly as expected. Now I have an executable, which links against liba. Even though the main program is the most simple “Hello World!” program, the linker now gives me:

ldd main
        linux-vdso.so.1 (0x00007fff7f18c000)
        liba.so.3 => /home/kyoki/lib/liba.so.3 (0x00007f3015de0000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f3015bd8000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f3015a93000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f3015a79000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f30158b2000)
        libboost_iostreams.so.1.71.0 => not found
        libboost_log.so.1.71.0 => not found
        libboost_filesystem.so.1.71.0 => /usr/lib64/libboost_filesystem.so.1.71.0 (0x00007f3015896000)
        libboost_program_options.so.1.71.0 => /usr/lib64/libboost_program_options.so.1.71.0 (0x00007f3015846000)
        libboost_timer.so.1.71.0 => not found
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3015824000)
        libboost_atomic.so.1.71.0 => not found
        libboost_date_time.so.1.71.0 => not found
        libboost_regex.so.1.71.0 => /usr/lib64/libboost_regex.so.1.71.0 (0x00007f301574a000)
        libboost_thread.so.1.71.0 => /usr/lib64/libboost_thread.so.1.71.0 (0x00007f3015723000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f3015f96000)
        libboost_chrono.so.1.71.0 => not found
        libicui18n.so.67 => /usr/lib64/libicui18n.so.67 (0x00007f3015416000)
        libicuuc.so.67 => /usr/lib64/libicuuc.so.67 (0x00007f301522a000)
        libicudata.so.67 => /usr/lib64/libicudata.so.67 (0x00007f3015227000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f3015221000)

Consequently, executing main fails while loading the shared libraries. In other cases, ldd shows that the program (or library) is looking for both version 1.74 and 1.71 of the same Boost library. Any idea, why this is happening? The missing libraries are not available as packages anymore and I’d rather not compile and install Boost 1.71 locally, even though this is possible.

If you run ldconfig no errors? Nothing lurking in /etc/ld.so.conf.d/?

In the case of ncmpcpp, it needs to be fixed by the maintainers since it’s failing to build;

in /etc/ld.so.conf.d/ there is a graphviz config file, nothing indicating trouble there. But for ldconfig, I get this:

sudo ldconfig -p | grep boost
        libboost_unit_test_framework.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_unit_test_framework.so.1.74.0
        libboost_unit_test_framework.so (libc6,x86-64) => /usr/lib64/libboost_unit_test_framework.so
        libboost_timer.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_timer.so.1.74.0
        libboost_timer.so (libc6,x86-64) => /usr/lib64/libboost_timer.so
        libboost_thread.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_thread.so.1.74.0
        libboost_thread.so.1.71.0 (libc6,x86-64) => /usr/lib64/libboost_thread.so.1.71.0
        libboost_thread.so (libc6,x86-64) => /usr/lib64/libboost_thread.so
        libboost_test_exec_monitor.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_test_exec_monitor.so.1.74.0
        libboost_test_exec_monitor.so (libc6,x86-64) => /usr/lib64/libboost_test_exec_monitor.so
        libboost_system.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_system.so.1.74.0
        libboost_system.so (libc6,x86-64) => /usr/lib64/libboost_system.so
        libboost_regex.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_regex.so.1.74.0
        libboost_regex.so.1.71.0 (libc6,x86-64) => /usr/lib64/libboost_regex.so.1.71.0
        libboost_regex.so (libc6,x86-64) => /usr/lib64/libboost_regex.so
        libboost_program_options.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_program_options.so.1.74.0
        libboost_program_options.so.1.71.0 (libc6,x86-64) => /usr/lib64/libboost_program_options.so.1.71.0
        libboost_program_options.so (libc6,x86-64) => /usr/lib64/libboost_program_options.so
        libboost_prg_exec_monitor.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_prg_exec_monitor.so.1.74.0
        libboost_prg_exec_monitor.so (libc6,x86-64) => /usr/lib64/libboost_prg_exec_monitor.so
        libboost_log_setup.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_log_setup.so.1.74.0
        libboost_log_setup.so (libc6,x86-64) => /usr/lib64/libboost_log_setup.so
        libboost_log.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_log.so.1.74.0
        libboost_log.so (libc6,x86-64) => /usr/lib64/libboost_log.so
        libboost_locale.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_locale.so.1.74.0
        libboost_locale.so.1.71.0 (libc6,x86-64) => /usr/lib64/libboost_locale.so.1.71.0
        libboost_iostreams.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_iostreams.so.1.74.0
        libboost_iostreams.so (libc6,x86-64) => /usr/lib64/libboost_iostreams.so
        libboost_filesystem.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_filesystem.so.1.74.0
        libboost_filesystem.so.1.71.0 (libc6,x86-64) => /usr/lib64/libboost_filesystem.so.1.71.0
        libboost_filesystem.so (libc6,x86-64) => /usr/lib64/libboost_filesystem.so
        libboost_date_time.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_date_time.so.1.74.0
        libboost_date_time.so (libc6,x86-64) => /usr/lib64/libboost_date_time.so
        libboost_chrono.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_chrono.so.1.74.0
        libboost_chrono.so (libc6,x86-64) => /usr/lib64/libboost_chrono.so
        libboost_atomic.so.1.74.0 (libc6,x86-64) => /usr/lib64/libboost_atomic.so.1.74.0
        libboost_atomic.so (libc6,x86-64) => /usr/lib64/libboost_atomic.so

The double entries (for version 1.74 and 1.71) do exist in the system. For the wrong libraries, e.g., libboost_log.so.1.71.0, there seems to be a default link, but that points to the 1.74 objects as well :question:
Is there a way to (safely) update the linker cache? I’m not an expert in this and don’t want to mess up my system…

Okay, I simply ran ldconfig (without arguments). Problem still persists.

If you run;

zypper se -i libboost*71*

On my system I still see some in use…

I still have some libraries installed:

zypper se -i libboost*71*
Repository-Daten werden geladen...
Installierte Pakete werden gelesen...

S  | Name                           | Zusammenfassung                      | Typ
i+ | libboost_filesystem1_71_0      | Boost.Filesystem Runtime Libraries   | Paket
i+ | libboost_locale1_71_0          | Boost::Locale runtime library        | Paket
i+ | libboost_program_options1_71_0 | Boost.ProgramOptions runtime library | Paket
i+ | libboost_regex1_71_0           | Boost.Regex runtime library          | Paket
i+ | libboost_thread1_71_0          | Boost.Thread runtime libraries       | Paket

For these, the linking works correctly. What puzzles me is that the linker also tries to link to Boost libraries from the 1.71 series for which no package is installed (for instance, libboost_log.so.1.71.0) - for these libraries, the 1.74 version is installed, which is also listed in ldd - but there is then a second entry for the 1.71 version and I have no clue why that suddenly appears. It may be that the Boost libraries themselves are not correctly linked?

EDIT: FWIW, here is the list of installed Boost libraries in version 1.74:

zypper se -i libboost*74*
Repository-Daten werden geladen...
Installierte Pakete werden gelesen...

S | Name                                 | Zusammenfassung                                      | Typ
i | libboost_atomic1_74_0                | Boost.Atomic runtime library                         | Paket
i | libboost_atomic1_74_0-devel          | Development headers for Boost.Atomic                 | Paket
i | libboost_chrono1_74_0                | The Boost::Chrono runtime library                    | Paket
i | libboost_chrono1_74_0-devel          | Development headers for Boost.Chrono library         | Paket
i | libboost_date_time1_74_0             | Boost.DateTime runtime library                       | Paket
i | libboost_date_time1_74_0-devel       | Development headers for Boost.DateTime library       | Paket
i | libboost_filesystem1_74_0            | Boost.Filesystem Runtime Libraries                   | Paket
i | libboost_filesystem1_74_0-devel      | Development headers for Boost.Filesystem library     | Paket
i | libboost_headers1_74_0-devel         | Development headers for Boost                        | Paket
i | libboost_iostreams1_74_0             | Boost.IOStreams Runtime Libraries                    | Paket
i | libboost_iostreams1_74_0-devel       | Development headers for Boost.IOStreans library      | Paket
i | libboost_locale1_74_0                | Boost::Locale runtime library                        | Paket
i | libboost_log1_74_0                   | Boost.Log runtime Run-Time library                   | Paket
i | libboost_log1_74_0-devel             | Development headers for Boost.Log library            | Paket
i | libboost_program_options1_74_0       | Boost.ProgramOptions runtime library                 | Paket
i | libboost_program_options1_74_0-devel | Development headers for Boost.ProgramOptions library | Paket
i | libboost_regex1_74_0                 | Boost.Regex runtime library                          | Paket
i | libboost_regex1_74_0-devel           | Development headers for Boost.Regex library          | Paket
i | libboost_system1_74_0                | Boost.System runtime library                         | Paket
i | libboost_system1_74_0-devel          | Development headers for Boost.System library         | Paket
i | libboost_test1_74_0                  | Boost.Test runtime library                           | Paket
i | libboost_test1_74_0-devel            | Development headers for Boost.Test library           | Paket
i | libboost_thread1_74_0                | Boost.Thread runtime libraries                       | Paket
i | libboost_thread1_74_0-devel          | Development headers for Boost.Thread library         | Paket
i | libboost_timer1_74_0                 | Boost.Timer runtime library                          | Paket
i | libboost_timer1_74_0-devel           | Development headers for Boost.Timer library          | Paket

Okay, I figured it out.

I install some custom libraries I build for a programming project to a local lib directory. when building my code, the linker links to these (older) libraries, which still link to Boost 1.71, since they where not updated after the install (I use a custom LD_LIBRARY_PATH exported in .bashrc). When I delete these libraries (or call the program with LD_LIBRARY_PATH=), the linker chooses the correct library from the build tree and everything works again.

Thanks for the help malcolmlewis, I did learn something new!

Then remove the cache and rebuild… I had a few old programs installed, remove those and all good here…

rm /etc/ld.so.cache