Is $ORIGIN/lib a reasonable RUNPATH for libraries?

Background

I have a third-party library that has this structure:

lib
 ├── liba.so
 └── libb.so // libb.so is NEEDED by liba.so

Both have their RUNPATH set to $ORIGIN/lib and liba.so depend on libb.so.

In my first-party project I have the following structure:

bin
 ├── liba.so
 ├── libb.so
 └── myexecutable

where myexecutable depend directly on both liba.so and libb.so. liba.so still depends directly on libb.so. The RUNPATH of myexecutable is $ORIGIN.

  • ./myexecutable can resolve liba.so since $ORIGIN/liba.so = <path-of-myexecutable>/liba.so = ./liba.so exists
  • ./liba.so can't resolve libb.so since $ORIGIN/lib/libb.so = <path-of-liba.so>/lib/libb.so = ./lib/libb.so does not exist. This is a problem when using CMake's RUNTIME_DEPENDENCY_SET to "automatically" install imported library targets.

Here's what I think.

It makes sense that executables have a RUNPATH $ORIGIN/lib and libraries have a RUNPATH $ORIGIN if the structure resembles this:

Case: lib

.
├── lib
│   ├── liba.so
│   └── libb.so
└── myexecutable

It also makes sense that executables have a RUNPATH $ORIGIN/../lib and libraries have a RUNPATH $ORIGIN if the structure is this:

Case bin+lib

.
├── bin
│   └── myexecutable
└── lib
    ├── liba.so
    └── libb.so

Finally, it makes sense that executables have a RUNPATH $ORIGIN and libraries have a RUNPATH $ORIGIN if the structure is this:

Case: bin (my use-case)

bin
 ├── liba.so
 ├── libb.so
 └── myexecutable

In all cases above, libraries always have their RUNPATH as $ORIGIN and NOT $ORIGIN/lib. For this reason it seems wrong to set $ORIGIN/lib as RUNPATH for shared object files, since I fail to construct any case where it is preferable to have library RUNPATHs set to $ORIGIN/lib.

Question

If .so-files from the same third-party library are expected to live side-by-side in some directory, in presence of NEEDED inter-dependencies, mustn't the .so-files with dependencies on other .so-files always have $ORIGIN in their RUNPATH?


I understand that this is a discussion I could just have with the third-party library author in context of the actual library - and I am, but I also believe that my question is something that others would benefit from in context of other libraries than the one in my use-case.


Solution 1:

If .so-files from the same third-party library are expected to live side-by-side in some directory, in presence of NEEDED inter-dependencies, mustn't the .so-files with dependencies on other .so-files always have $ORIGIN in their RUNPATH?

Yes.

The 3d party vendor who built them with RUNPATH of $ORIGIN/lib didn't know what he/she was doing.