I have the following scenario: foo is directly dependent on bar, and bar is dependent on baz. foo has a RPATH of $ORIGIN/lib, where bar.so and baz.so are in. bar has a RUNPATH of /some/unimportant/dir/with/no/baz.
When I ldd foo, I get: bar.so -> $ORIGIN/lib baz.so -> not found
In this case, I expected that when searching for baz, the linker will first search bar's RUNPATH, fail to find it, and then look in foo's RPATH. However, that is not the case, and I genuinely couldn't figure out why. I noticed though that some other direct dependencies with RPATH that are in the same situation (i.e. indirect dependency not in direct dependency's RPATH) works, as in the linker will look in foo's RPATH. Not sure if this is related.
I tried to resolve this by making baz a direct dependency of foo. So now the scenario is: foo -> bar baz bar -> baz
This worked, in the sense that ldd shows: bar.so -> $ORIGIN/lib baz.so -> $ORIGIN/lib
However, I'm not sure if, when the program runs and baz is needed by bar, will it still try to look for it in the RUNPATH of bar? Will it fail to find it and the program execution will be stopped?
This is where I don't fully understand how the linking works in this situation. Is it sequential? In the sense that it will try to link bar, see that bar has dependency on baz, and then try to find baz in bar's RUNPATH. Then it goes to baz (b/c that's the next direct dependency on the list). Or is it some kind of pool of shared libraries? As in, it sorts out all the dependencies and subdependencies at the same time and puts them into the same kind of pool of libraries. So it will first go through all the dependencies, and add them to this "pool". When it looks at the indirect dependencies, it will see that baz is already in the "pool", so it will use the baz there, instead of trying to find it in bar's RUNPATH.
EDIT:
//foo
#include "bar.h"
int main() {
barFunc();
}
//bar
#include "baz.h"
void barFunc() {
bazFunc();
}
//baz
void bazFunc();
foo
:
- links
bar
directly - RPATH:
$ORIGIN/lib
bar
:
- links
baz
directly - RPATH:
/some/unimportant/dir
During runtime, the foo binary is moved to a place where /some/unimportant/dir
isn't available, so I expected that it should try to find baz
in foo
's RPATH, but it doesn't.
However, if the scenario was like this instead:
bar
:
- links
baz
directly - RUNPATH:
/some/unimportant/dir
Then it will search for baz
in foo
's RPATH.
This is where I'm confused, and also don't know how to work around this because bar
is a shared library, which is not something I should try to change.