The solution by Max Ghenis and ManuelAtWork helped me with a related issue with a different shared library. I wanted to document my steps here in case it helps somebody else.
TL;DR
Even if LD_LIBRARY_PATH contains /usr/local/lib, and your shared object library ( the .so file ) is located there, you still might get an error like
error while loading shared libraries: <INSERT LIBRARY NAME>.so.0: cannot open shared object file: No such file or directory
If your linker cache /etc/ld.so.cache has not been rebuilt since the library was installed.
You can fix this by running ldconfig ( or sudo ldconfig, depending on the /etc directory permissions, which are likely only writeable by the root user ).
When successful, ldconfig prints no output. For more detailed output when running ldconfig, use the -v ( or --verbose ) flag.
If you have ever run into this error, and then it magically fixed itself while you were troubleshooting, it's probably because you followed someone's advice and did something like
ldconfig -v | grep <INSERT LIBRARY NAME>
to make sure the .so file was in a directory listed in LD_LIBRARY_PATH, like /usr/local/lib. It's a reasonable troubleshooting step to perform if you already confirmed that directory is included in /etc/ld.so.conf or /etc/ld.so.conf.d/*.conf, but ldconfig -v still runs ldconfig in verbose mode, which rebuilds /etc/ld.so.cache, and probably fixed your issue.
If your error mysteriously fixed itself after some time without you having to run ldconfig, then something else on your system must have run it since then - e.g. a startup script, a scheduled task, or installation scripts for other software.
Details
I recently installed libhttpserver, following the instructions on its GitHub repo, which follow the standard steps with the make command. I was able to compile an external program against the library, but when I ran my program I received the same error related to dynamic linkage.
$ g++ -o server server.c `pkg-config --cflags --libs libhttpserver`
./server
error while loading shared libraries: libhttpserver.so.0: cannot open shared object file: No such file or directory
I confirmed pkg-config knew linker flags and library names, meaning the .pc file(s) for libhttpserver had been installed correctly.
$ pkg-config --cflags --libs libhttpserver
-I/usr/local/include -I/usr/local/include/httpserver -I/usr/include/p11-kit-1 -L/usr/local/lib -lhttpserver -lmicrohttpd
I noted the -L/usr/local/lib flag, and confirmed the shared object files were located there.
$ find /usr/local/lib -name '*httpserver*'
/usr/local/lib/libhttpserver.so.0
/usr/local/lib/libhttpserver.la
/usr/local/lib/libhttpserver.so.0.19.0
/usr/local/lib/pkgconfig/libhttpserver.pc
/usr/local/lib/libhttpserver.a
/usr/local/lib/libhttpserver.so
Following a suggestion from this thread, I searched for the library name in the output of ldconfig -v
$ ldconfig -v |grep libhttpserver
/sbin/ldconfig.real: Path `/usr/lib/x86_64-linux-gnu' given more than once
(from /etc/ld.so.conf.d/x86_64-linux-gnu.conf:4 and /etc/ld.so.conf.d/x86_64-linux-gnu.conf:3)
/sbin/ldconfig.real: Path `/usr/lib32' given more than once
(from /etc/ld.so.conf.d/zz_i386-biarch-compat.conf:3 and /etc/ld.so.conf.d/zz_i386-biarch-compat.conf:2)
/sbin/ldconfig.real: Path `/usr/libx32' given more than once
(from /etc/ld.so.conf.d/zz_x32-biarch-compat.conf:3 and /etc/ld.so.conf.d/zz_x32-biarch-compat.conf:2)
/sbin/ldconfig.real: Path `/lib/x86_64-linux-gnu' given more than once
(from <builtin>:0 and /etc/ld.so.conf.d/x86_64-linux-gnu.conf:3)
/sbin/ldconfig.real: Path `/usr/lib/x86_64-linux-gnu' given more than once
(from <builtin>:0 and /etc/ld.so.conf.d/x86_64-linux-gnu.conf:3)
/sbin/ldconfig.real: Path `/usr/lib' given more than once
(from <builtin>:0 and <builtin>:0)
libhttpserver.so.0 -> libhttpserver.so.0.19.0
/sbin/ldconfig.real: /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 is the dynamic linker, ignoring
/sbin/ldconfig.real: /lib32/ld-linux.so.2 is the dynamic linker, ignoring
/sbin/ldconfig.real: Can't create temporary cache file /etc/ld.so.cache~: Permission denied
I noticed the error message at the end of the output
/sbin/ldconfig.real: Can't create temporary cache file /etc/ld.so.cache~: Permission denied
I decided to read the man page for ldconfig to learn more about what ldconfig -v was doing.
ldconfig creates the necessary links and cache to the most recent shared libraries found in the di‐rectories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories, /lib and /usr/lib
-v, --verbose
Verbose mode. Print current version number, the name of each directory as it is scanned, and
any links that are created. Overrides quiet mode.
Since ldconfig -v flag was doing the same thing as ldconfig, but just with more detailed output, I decided to run ldconfig without it.
$ ldconfig
/sbin/ldconfig.real: Can't create temporary cache file /etc/ld.so.cache~: Permission denied
This time the error message from before was the only output. Before resorting to using sudo, I wanted to learn more about what was happening. Since ldconfig was trying to create a file called /etc/ld.so.cache~, I decided to look for that file or files with similar names.
$ find /etc -name 'ld.so*'
/etc/ld.so.cache
find: ‘/etc/ssl/private’: Permission denied
find: ‘/etc/softhsm’: Permission denied
/etc/ld.so.conf.d
find: ‘/etc/polkit-1/localauthority’: Permission denied
find: ‘/etc/cups/ssl’: Permission denied
/etc/ld.so.conf
I figured /etc/ld.so.cache must be the cache the ldconfig man page was talking about. I decided to look for my library name there.
$ grep libhttpserver /etc/ld.so.cache
But grep returned no matches. Instead I looked for /usr/local/lib.
$ grep /usr/local/lib /etc/ld.so.cache
grep: /etc/ld.so.cache: binary file matches
That found a match. Reading the man pages for ldconfig, I learned the -p flag prints the cache, which is a binary file, in a human readable format, so I searched for /usr/local/lib in the output of ldconfig -p.
ldconfig -p | grep /usr/local/lib
I found matches for other libraries in /usr/local/lib (e.g. libwayland, but not libhttpserver.
libwayland-server.so.0 (libc6,x86-64) => /usr/local/lib/x86_64-linux-gnu/libwayland-server.so.0
libwayland-server.so (libc6,x86-64) => /usr/local/lib/x86_64-linux-gnu/libwayland-server.so
libwayland-egl.so.1 (libc6,x86-64) => /usr/local/lib/x86_64-linux-gnu/libwayland-egl.so.1
libwayland-egl.so (libc6,x86-64) => /usr/local/lib/x86_64-linux-gnu/libwayland-egl.so
libwayland-cursor.so.0 (libc6,x86-64) => /usr/local/lib/x86_64-linux-gnu/libwayland-cursor.so.0
libwayland-cursor.so (libc6,x86-64) => /usr/local/lib/x86_64-linux-gnu/libwayland-cursor.so
libwayland-client.so.0 (libc6,x86-64) => /usr/local/lib/x86_64-linux-gnu/libwayland-client.so.0
libwayland-client.so (libc6,x86-64) => /usr/local/lib/x86_64-linux-gnu/libwayland-client.so
...
Clearly the linker ld.so had at one point been able to find libraries located in /usr/local/lib, because they were in the linker's cache. I confirmed this was still the case by checking /etc/ld.so.conf and /etc/ld.so.conf.d.
$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf
$ grep -x /usr/local/lib /etc/ld.so.conf.d/*.conf
/etc/ld.so.conf.d/libc.conf:/usr/local/lib
I was curious what was normally responsible for running ldconfig on my system, but I couldn't find a systemd service, crontab, or init.d script responsible for running it. I had built libraries from source before that were installed to /usr/local/lib, but I never had this issue.
I finally did find a reference to ldconfig in a build script in the source code for one such library I had installed a while ago. I concluded it was up to the author of the source code whether or not to run ldconfig after installation, and that whether or not the system runs ldconfig automatically on startup, etc., depends on what Linux distribution you're using.
Having convinced myself I wasn't doing any harm by rebuilding the linker cache, I finally resorted to running ldconfig as root.
sudo ldconfig
This time, there was no error message about failing to create a temporary cache file. Before attempting to run my code again, I confirmed the linker cache now contained a reference to libhttpserver.
$ ldconfig -p|grep libhttpserver
libhttpserver.so.0 (libc6,x86-64) => /usr/local/lib/libhttpserver.so.0
libhttpserver.so (libc6,x86-64) => /usr/local/lib/libhttpserver.so
Finally, I tried to run program again and was successful.
$ ./server
Note that I didn't need to recompile my program after running sudo ldconfig, since it already contained references to the correct shared library. The issue was just that the linker cache /etc/ld.so.cache needed to be updated by running sudo ldconfig after installing libhttpserver.
When you build libraries from source, you may run into this issue, depending on whether or not the source maintainers choose to include that step in their installation scripts.