Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linux executable can't find shared library in same folder

I am relatively new to Linux development, having been using Windows for a while now. Anyway, I am compiling a C++ game using g++ on both Windows and Linux (using mingw32 when needed), and am linking against SDL2 and SDL2_mixer. On Windows, one would only need to put the DLL files in the same folder as the executable and everything would run fine. On Linux however, although the code compiled just fine with not even a single warning, I get this at runtime :

./nKaruga: error while loading shared libraries: libSDL2_mixer-2.0.so.0: cannot open shared object file: No such file or directory

although said shared lib is in the same folder. I looked up several similar cases on Stack Overflow, all of them involving the use of LD_LIBRARY_PATH, and tried it but to no avail.

% LD_LIBRARY_PATH=pwd
% export LD_LIBRARY_PATH
% ./nKaruga
./nKaruga: error while loading shared libraries: libSDL2_mixer-2.0.so.0: cannot open shared object file: No such file or directory

I want to distribute this program on systems that do not necessarily have admin rights to install dependencies, hence why I am putting the SO in the same folder as the executable.

Thanks by advance !

like image 302
Matrefeytontias Avatar asked Oct 11 '16 13:10

Matrefeytontias


1 Answers

LD_LIBRARY_PATH is a quick ad-hoc hack to specify alternate library loading search paths. A more permanent and cleaner solution is to specify the specific sets of paths in which libraries shall be searched specific for your particular binary. This is called the rpath (Wikipedia article on it: https://en.wikipedia.org/wiki/Rpath). There are a number of "variables" that can be specified in the binary rpath that get substituted. In your case the rpath variable ${ORIGIN} would be the most interesting for you. ${ORIGIN} tells the dynamic linker to look for libraries within the very same directory in which also the binary resides.

The rpath can be set at link time with the -rpath linker option, i.e. when invoked through GCC the option would be -Wl,-rpath='${ORIGIN}', i.e.

gcc -o program_binary -Wl,-rpath='${ORIGIN}' -lSDL2_mixer a.o b.o …

For an existing binary the rpath can be set post-hoc using the chrpath or patchelf tools; it's better to set it at link time proper, though.

like image 75
datenwolf Avatar answered Oct 16 '22 13:10

datenwolf