2

I am looking for a way to allow an executable to find its shared library, but in order to avoid conflict with any package that could use a different version of the same shared library I prefer to keep these libraries in a 'private path' (not /usr/lib).

The possible ways seems :

  • embbeded rpath in the executable
  • set LD_LIBRARY_PATH when executable is started
  • add libraries path in ldconfig configuration in a ld.so.conf.d file

rpath links target structure to the build, ld.so.conf.d configure path for the system, LD_LIBRARY_PATH need the caller process to be aware of it.

So I was wondering if it is possible to use ld.so.conf.d (or similar loader configuration) applied only for an executable ?

2

Not easily. ld.so.conf files have a very simple format: they're just a list of paths.

You could do something by building your executable with a different interpreter; the normal one would be something like /lib64/ld-linux-x86-64.so.21 and is what's actually responsible for performing the dynamic linking. So your custom dynamic linker could look in a different ld.so.conf, or do whatever. But this sounds far worse than rpath!

A much simpler solution is a wrapper. Install the binary as program.real, or, even better, in /usr/local/lib/ somewhere (that is, not in $PATH). Then put a simple shell script as /usr/local/bin/program:

#!/bin/sh
export LD_LIBRARY_PATH=/path/to/libs
exec /usr/local/lib/program/program.real

Now your library location is independent of the build, but the calling program requires no knowledge of it.




1: Quick way to find what it normally is on your system: readelf /bin/bash -p .interp. Try a few different executables; you'll find at least 32- and 64-bit programs use a different one.

0

It is possible to use a relative rpath using $ORIGIN.

Linking executables with -Wl,-rpath,'$ORIGIN/../lib' allow executables to find their librairies installing :

  • executables in <base>/bin/
  • shared libraries in <base>/lib/

Proceeding like this allow to configure this link only for these executables and the <base> directory could be anywhere.

-1

The filename argument to dlopen can be an absolute path (starts with '/').

So, store the 'private path' in a configuration-file, build the full name of the library from that. Or, if you know the private library will be in the same directory as the executable, do simple string operations on the path to the executable to find it...

#include <dlfcn.h>
#include <unistd.h>
#include <string.h>

static int (*foo)();

/* ... */
char buf[BUFSIZ];
char *lastslash;
void *handle;

realpath(argv[0],buf);
lastslash = strrchr(buf,'/');
strcpy(lastslash,"foo." VERSION_BUILD ".so");
dlopen(buf,RTLD_LOCAL | RTLD_LAZY);
*(void **)(&foo) = dlsym(handle, "foo");

/* ... */
printf("%d\n",foo());
  • I though to that but this is really different, it is more adapt to configurables dynamic dependencies like plugins. Such a way needs to wrap all the methods of the shared libraries. – mpromonet Sep 4 '14 at 17:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.