1

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:

  1. links bar directly
  2. RPATH: $ORIGIN/lib

bar:

  1. links baz directly
  2. 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:

  1. links baz directly
  2. 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.

lyyyyyyz99
  • 19
  • 2
  • Your question doesn't say where `baz` is located, and would benefit from proper formatting. http://stackoverflow.com/help/mcve would help as well. `RPATH` in `foo` _should_ have worked for locating `baz` IFF `baz` exists in `$ORIGIN/lib`. – Employed Russian Apr 29 '23 at 14:53
  • @EmployedRussian Hi, baz is located in $ORIGIN/lib ($ORIGIN refers to where foo is located), although that path is not a part of bar's path. Yes, if foo has RPATH then baz is able to be located. However, foo has RUNPATH, which is why I suspect that it didn't work. – lyyyyyyz99 Apr 29 '23 at 15:53
  • Your question says `RPATH`. Your comment says `RUNPATH`. These are _different_, and I suspect your question is answered here: https://stackoverflow.com/a/47243544/50617 – Employed Russian Apr 29 '23 at 18:34
  • @EmployedRussian So sorry for the confusion! The question is correct, foo has RPATH, but I meant when bar (which depends on baz) has RUNPATH, baz won't be searched for in foo's RPATH. However, then bar has RPATH, it will be searched for in foo's RPATH. I suspsect that bar's use of RUNPATH vs RPATH is causing this difference and don't know how to resolve it. I can't change bar's use of path b/c it's not a shared library I have control over. – lyyyyyyz99 Apr 30 '23 at 00:41
  • As I said before, it's _very hard_ to understand your question as it currently exists. Please provide MCVE so we can understand what you are asking. – Employed Russian Apr 30 '23 at 00:59
  • @EmployedRussian Hi, I've edited the question, hopefully this clears things up. Thanks. – lyyyyyyz99 Apr 30 '23 at 07:57
  • This _still_ works fine for me. How hard could it be to create an MCVE? – Employed Russian Apr 30 '23 at 16:56
  • @EmployedRussian Sorry I'm new to this, I thought my edit was enough to illustrate the problem. The scenario seems quite simple to me, it's the difference between using RPATH and RUNPATH in the `bar` library, which `foo` has a direct dependency on and depends on `baz`. Never mind then, thanks for trying though. – lyyyyyyz99 May 01 '23 at 02:04

0 Answers0