Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux Program can't find Shared Library at run-time

I'm trying to compile a linux program, id3v2, and it says it is can't find the appropriate library:

id3v2: error while loading shared libraries: libid3-3.8.so.3: cannot open shared object file: No such file or directory

I'm guessing that this is the part that pulls in the lidid3 library?

The file DOES exist, however, what they are looking for is actually a symbolic link to:

"ibid3-3.8.so.3.0.0"

I'm wondering if it is an issue with it not being able to follow symbolic links? Perhaps I could manually change it to look for 0.0 if I knew where I was looking to change it.

I'm happy to clarify any details.

It looks like the includes are done in the following manner:

id3v2:  convert.o list.o id3v2.o genre.o
        ${CXX} ${LDFLAGS} -pedantic -Wall -g -o $@ $^ -lz -lid3

I was able to use Simon's advice to figure out that there were multiple spots where one might expect a library. I create a symbolic link where the program was linking to the ACTUAL file.

Thank you Simon!

like image 721
Scott Avatar asked Jan 21 '11 01:01

Scott


People also ask

How do I find shared libraries in Linux?

In this standard, folders /lib, /usr/lib and /usr/local/lib are the default folders to store shared libraries. The /lib folder has libraries used during the boot time of the system but also used by programs in the /bin folder. Similarly, the/usr/lib folder has libraries used by programs in the /usr/bin folder.

Where does Linux install shared libraries?

According to the FHS, most libraries should be installed in /usr/lib, but libraries required for startup should be in /lib and libraries that are not part of the system should be in /usr/local/lib.

How do you check if a shared library is loaded in Linux?

To find the list of processes and their loaded libraries, use "genld -ld" command. The -l option reports the lists of loaded objects for each process running on the system.

Do shared libraries need executable?

9.2. As shared libraries cannot be directly executed, they need to be linked into a system executable or callable shared object. Hence, shared libraries are searched for by the system linker during the link process. This means that a shared library name must always start with the prefix lib and have the extension .


1 Answers

Symlinks on libraries work fine, as long as the final target they trace to exists and is accessible.

You have built a dynamically-linked executable, that wishes to be linked against libid3-3.8.so.3 at execution time. This was likely linked during the build phase with something like -L/path/to/libid3/directory -lid3.

You have a few options to make libid3 available, in generally decreasing order of preference (since you didn't mention where the file was, I can only be general):

  • Create a symlink to libid3* in a directory listed in /etc/ld.so.conf (or /lib or /usr/lib)
  • Copy libid3* to a directory listed in /etc/ld.so.conf (or /lib or /usr/lib) (defaults)
  • Add the directory containing libid3* to /etc/ld.so.conf
  • Set LD_LIBRARY_PATH=/directory/path/to/libid3* before running your id3v2 executable.
  • Recompile id3v2 statically. (It will work, but don't bother.)

After any of the first 3, rerun ldconfig so the linker cache is updated. (You can then run ldconfig -v to verify it's resolvable.)

Note those aren't steps, they're options. You only need to do 1 of them.

Glad you updated the title. #include directives have nothing to do with linking.

like image 142
Sdaz MacSkibbons Avatar answered Sep 27 '22 20:09

Sdaz MacSkibbons