2

I am trying to link a locally installed shared library (./vendor/lib/libfoo.so) with my binary, ./bar. Unfortunately, none of my attempts generates a link with an absolute path to libfoo.so. As a consequence I need to use

LD_LIBRARY_PATH=vendor/lib ./bar

to run it, which I want to avoid. ldd bar shows me this:

    linux-vdso.so.1 =>  (0x00007ffed5fd8000)
    libbar.so.2 => not found
    libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fb9ea787000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb9ea47d000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fb9ea267000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb9e9e9d000)
    /lib64/ld-linux-x86-64.so.2 (0x000055f326761000)

A word about libbar.so.2: the file exists (in vendor/lib) alongside libbar.so. Both are actually symlinks to libhts.so.1.6. That file also exists, and is the actual shared library.

Here’s the different ways I’ve tried:

FULL_PATH="$(pwd -P)/vendor/lib"

g++ -o bar bar.o -Lvendor/lib -lfoo        # 1
g++ -o bar bar.o -L$FULL_PATH -lfoo        # 2
g++ -o bar bar.o $FULL_PATH/libfoo.so      # 3
g++ -o bar bar.o $FULL_PATH/libfoo.so.1.6  # 4

All of these variants produce identical ldd output, even the last line (does ld insist on using the highest version of a library?).

The only way I’ve found to make this work is to use

LD_RUN_PATH=$FULL_PATH g++ -o bar bar.o -Lvendor/lib -lfoo

(I can’t use -rpath because my version of g++ doesn’t understand this argument, and I’m using g++ instead of ld to get the libstdc++ dependencies right — I could use -Wl,-rpath of course.)

But I can’t help but feel that there should be a way of making this work without the use of environment variables/-rpath. I’ve found an answer specifically referencing symlinks to libraries but unfortunately it doesn’t help me (see attempt 4 above).

This is on Ubuntu 16.04, g++ 5.4.0, GNU ld 2.26.1, in case it matters.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214

1 Answers1

2

It sounds likely that you didn't update the ldconfig cache after installing your shared library in the non-standard location /what/ever/vendor/lib:-

sudo ldconfig /what/ever/vendor/lib

Until you do that the runtime linker will be unaware that libfoo.so is in /what/ever/vendor/lib, even if it is, unless you prompt it at runtime through the LD_LIBRARY_PATH environment variable.

Incidentally, it isn't a shortcoming of your version of g++ that it doesn't recognize -rpath. This has only ever been a linker (ld) option, never a GCC frontend option. So -Wl,-rpath=/what/ever/vendor/lib is the conventional way of tacking the non-standard runtime library path to your program so as to avoid relying on either the ldconfig cache or LD_LIBRARY_PATH

For out-of-the ordinary linkages it may be considered better to use -rpath rather than extend the ldconfig cache, which has less discriminate effects.

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
  • 1
    ”Until you do that the runtime linker will be unaware that `libfoo.so` is in `/what/ever/vendor/lib`” — right, that’s why I wanted to compile the binary with an absolute path to the library, so that `ld.so` doesn’t need to search for it (I don’t have superuser rights). But I’m starting to see that `-rpath` is the conventional solution here; I’m just puzzled why `ld` would ignore my explicit use of absolute paths. – Konrad Rudolph Oct 28 '17 at 13:13