34

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?

Fixee
  • 1,891
  • 3
  • 17
  • 24

2 Answers2

25

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

David Schwartz
  • 5,294
  • 22
  • 27
  • 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 08 '15 at 11:46
25

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.

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • 3
    +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 '20 at 04:52
  • 2
    @RoelVandePaar I think `chrpath` can only edit an existing rpath, not add one if there isn't. [This thread](https://stackoverflow.com/questions/13769141/can-i-change-rpath-in-an-already-compiled-binary/20333550#20333550) suggests that `patchelf` can add an rpath. I haven't tried. – Gilles 'SO- stop being evil' Jul 29 '20 at 07:44