12

On CentOS 7.2, I've built an app with g++ 4.8.5 that can't run because it can't find a library that does exist in its runpath. I'm pretty sure it worked two weeks ago. What could cause this?

$ ./app
./app: error while loading shared libraries: libhdf5.so.9: cannot open shared object file: No such file or directory

$ ldd ./app | grep libhdf5
    libhdf5.so.9 => not found

$ readelf app -d | grep path
 0x000000000000001d (RUNPATH)            Library runpath: [/opt/ProductName/lib:/opt/ProductName/lib/private]

$ ll /opt/ProductName/lib/libhdf5.so*
lrwxrwxrwx. 1 fotechd fotechd      16 Oct 26 14:38 /opt/ProductName/lib/libhdf5.so -> libhdf5.so.9.0.0
lrwxrwxrwx. 1 fotechd fotechd      16 Oct 26 14:38 /opt/ProductName/lib/libhdf5.so.9 -> libhdf5.so.9.0.0
-rwxr-xr-x. 1 fotechd fotechd 3316074 Oct 26 14:35 /opt/ProductName/lib/libhdf5.so.9.0.0

Setting LD_LIBRARY_PATH fixes it temporarily:

$ LD_LIBRARY_PATH=/opt/ProductName/lib ./app
...
OK
1
  • I have exactly the same problem on a fedora 29 system. Have you been able to solve it ? Commented Feb 13, 2019 at 12:09

2 Answers 2

13

I have been able to solve this issue on my side. For me it was because the not found library was an indirect one and runpath actually does not resolve indirect dependencies. I fixed it with using rpath instead of runpath by passing the additional -Wl,--disable-new-dtags linker option to the compiler.

There is a good and detailed explanation here: How to set RPATH and RUNPATH with GCC/LD?

Sign up to request clarification or add additional context in comments.

3 Comments

So you're saying that if your app loads an .so, which loads another .so, the second .so is unaffected by the runpath (but is affected by rpath)?
In my case I couldn't tell which dependencies are indirect since ldd only shows a flat list (and I'm new to the codebase). To get a proper tree structure you need to call lddtree instead, which is part of pax-utils (on CentOS I got it with sudo yum install pax-utils --enablerepo=epel).
Yes, that's exactly what an indirect dependency is: "a .so loaded by a .so". In my case, the not found .so was not in the list of (NEEDED) libraries you get with readelf -d
0

In order to find the shared objects, dlopen() searches the following, in this order:

  • the runtime library search path that was set using the -rpath option to ld (see the Utilities Reference) when the binary was linked
  • directories specified by the LD_LIBRARY_PATH environment variable
  • directories specified by the _CS_LIBPATH configuration string

It seems dlopen() does not check on RUNPATH.

http://www.qnx.com/developers/docs/6.5.0SP1.update/com.qnx.doc.neutrino_lib_ref/d/dlopen.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.