3

I have a libA.so that depends on libB.so and having trouble finding it even though it's in the same directory.

ldd libA.so linux-vdso.so.1 (0x00007fff50bdb000) libB.so => not found libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f4aeb902000) /lib64/ld-linux-x86-64.so.2 (0x00007f4aebadb000) 

I'm wondering if there is a way to make libA.so always look for libB.so in the same directory as this will be the case for my application? I know updating LD_LIBRARY_PATH is an option as well but wanted to reduce the amount of work required.

1
  • Have you tried to put the directory in LD_LIBRARY_PATH ? Commented Mar 11, 2022 at 11:33

3 Answers 3

3

The .dynamic section of an ELF file (.so libraries on Linux use ELF format) contains information to help the library find its dependencies. .dynamic entries with type DT_NEEDED contain the names of other .so files for the dynamic linker to find, but they do not contain any information on where to find those files. For that, as you mentioned, you can use LD_LIBRARY_PATH, but the ELF format also provides a way to specify it in the file itself.

A .dynamic entry with type DT_RUNPATH gives the dynamic linker a path to a directory where the dynamic linker should look for DT_NEEDED files. DT_RUNPATH allows a special variable, $ORIGIN, which refers to the file's current directory. This allows you to use relative paths, without requiring the user to invoke an executable from a specific working directory.

You use the -rpath linker flag to specify a DT_RUNPATH entry. In order to pass the literal string $ORIGIN, however, you must wrap it in single quotes to prevent your shell from interpreting it as an environment variable.

Assuming you are using gcc, you should use add this argument to the link step:

-Wl,-rpath,'$ORIGIN' 
Sign up to request clarification or add additional context in comments.

1 Comment

This did the trick. Thanks! Thanks for explanation as well.
1

From 'man 8 ld.so':

 If a shared object dependency does not contain a slash, then it is searched for in the following order: o Using the directories specified in the DT_RPATH dynamic section attribute of the binary if present and DT_RUNPATH attribute does not exist. Use of DT_RPATH is deprecated. o Using the environment variable LD_LIBRARY_PATH, unless the executable is being run in secure-execution mode (see below), in which case this variable is ignored. o Using the directories specified in the DT_RUNPATH dynamic section attribute of the binary if present. Such directories are searched only to find those objects required by DT_NEEDED (direct dependencies) entries and do not apply to those objects' children, which must themselves have their own DT_RUNPATH entries. This is unlike DT_RPATH, which is applied to searches for all children in the dependency tree. o From the cache file /etc/ld.so.cache, which contains a compiled list of candidate shared objects previously found in the augmented library path. If, however, the binary was linked with the -z nodeflib linker option, shared objects in the default paths are skipped. Shared objects installed in hardware capability directories (see below) are preferred to other shared objects. o In the default path /lib, and then /usr/lib. (On some 64-bit architectures, the default paths for 64-bit shared objects are /lib64, and then /usr/lib64.) If the binary was linked with the -z nodeflib linker option, this step is skipped. 

The key here is to use the DT_RUNPATH, which can be embedded into the binary you are creating. You can link it so that it points to the same directory, as you wanted.

See this post about how to do this: https://stackoverflow.com/a/67131878

Comments

1

On the top of the answers provided, it is also possible to change DT_RUNPATH using patchelf:

patchelf --set-rpath . <your-binary> 

Obviously be careful to understand security implications of allowing to load libraries from local directory.

patchelf allows to change DT_RUNPATH without recompiling or re-linking so may be convenient if you want to do this and do not have source or do not want to deal with re-compiling (which may be actually painful process on distros like Alpine).

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.