32

I have an executable linked like this:

  $ ldd a.out
        libboost_system-mt.so.1.47.0 => /usr/lib64/libboost_system-mt.so.1.47.0 (0x00007f4881f56000)
        libssl.so.10 => /usr/lib64/libssl.so.10 (0x00007f4881cfb000)
        libcrypto.so.10 => /usr/lib64/libcrypto.so.10 (0x00007f4881965000)
        librt.so.1 => /lib64/librt.so.1 (0x00007f488175d000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f4881540000)
        libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007f4881239000)
.
.

Where the libcrypto and libssl libraries are openssl 1.0.0-fips libs. I want to experiment with the 1.0.1 libraries instead, and so I've built them in my home directory. Is there a way to get a.out to relink against my new openssl libraries without a lot of pain? I would like to avoid

  • Having to relink a.out (because the build tools are massively complicated)
  • Altering any global settings (because other devs work on this machine)

Is it possible to do what I'm hoping here?

23

You can temporarily substitute a different library for this particular execution. In Linux, the environment variable LD_LIBRARY_PATH is a colon-separated set of directories where libraries should be searched for first, before the standard set of directories; this is useful when debugging a new library or using a nonstandard library for special purposes. The environment variable LD_PRELOAD lists shared libraries with functions that override the standard set, just as /etc/ld.so.preload does. - Shared Libraries

You can also invoke the loader directly:

/lib/ld-linux.so.2 --library-path path executable

| improve this answer | |
  • 1
    LD_LIBRARY_PATH does not override the default search path. I set it but ldd still shows me the system default path, not the overridden one. Though I can force the loading of my own library by setting LD_PRELOAD. – Calmarius Dec 8 '15 at 11:46
22

Write a wrapper script that sets the LD_LIBRARY_PATH environment variable. This is the pendant of PATH for shared libraries. The system search path is always searched after the directories listed in $LD_LIBRARY_PATH. See the dynamic linker manual for reference.

#!/bin/sh
export LD_LIBRARY_PATH=~/opt/openssl-1.0.1/lib
exec /path/to/a.out "$@"

Or, for a one-off, directly on the command line:

LD_LIBRARY_PATH=~/opt/openssl-1.0.1/lib ./a.out

Alternatively, if you want to modify the binary, try chrpath, which lets you edit the library search path baked in the executable.

| improve this answer | |
  • 2
    +1 for chrpath. Exactly what I needed. – Raghav RV May 24 '16 at 19:49
  • $ chrpath ./mybinary -l results in ./mybinary: no rpath or runpath tag found., thus it seems the only solution in this case is to use LD_LIBRARY_PATH=${PWD} ./mybinary which works (provided the libraries it needs - as can be seen by ldd mybinary | grep 'not found' - are in the current directory). Any way to still change the binary in this case? – Roel Van de Paar Jul 29 at 4:52
  • 1
    @RoelVandePaar I think chrpath can only edit an existing rpath, not add one if there isn't. This thread suggests that patchelf can add an rpath. I haven't tried. – Gilles 'SO- stop being evil' Jul 29 at 7:44

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.