Let shared lib load other lib from relative path

Hi!

lets say I want to make a game, my game uses a library, which depends on another library.
I want to ship all of this in one block like this:

game
| - Lib A
| - Lib B (depends on LibA)
| - Game.bin

Assuming everything compiled fine, I can’T actually move this anywhere. Because the path that Lib B looks for Lib A is static on my system (you can check this with strace).

How can i compile LibB to look for its neede libraries in other paths ?

As i understand it i can give my libraray B a RPATH of $ORIGIN and it should find it, but it doesn’t.

Search, read, and doit : Setting RPATH and not RUNPATH for executable

Using RPATH instead of RUNPATH is not the solution, it is a workaround that doesn’t solve the underlying problem. If each executable and library involved specifies its dependencies correctly, then RUNPATH should work fine. Indeed, one of the advantages of RUNPATH is that it exposes insufficiently specified dependencies. This will be more important if you are providing a SDK that others may pull your libraries out of and install to their own packages, potentially with a different structure to your SDK (doesn’t seem to be your case here, but mentioning it for context).

Assuming you are in full control of building Lib A, Lib B, and Game.bin, make sure you are setting the INSTALL_RPATH target property of all three targets (technically won’t matter for Lib A though since that one doesn’t depend on anything else). You can make this setting the default applied to all your targets by putting the following early in your project before any targets are defined:

  set(CMAKE_INSTALL_RPATH $ORIGIN)

Note that the above is for the installed binaries. If you’re copying binaries from your build directory instead of doing an install… don’t do that. Use an install and cpack to distribute your project. Then the RPATH handling should all work as designed. If you distribute binaries directly from your build directory, they will contain paths based on your build machine and won’t work on the deployment machine.

Lastly, while the CMake target properties all use RPATH in their name, it will depend on the way the toolchain was built whether they end up setting RPATH or RUNPATH values in the binaries. You can force one or the other with --disable-new-dtags or --enable-new-dtags if you need to, but really your project shouldn’t care. It should work for both.

2 Likes