Let shared lib load other lib from relative path

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