Linking to SFML libraries without libsfml-dev - c++

I currently have my Other Linker Options as:
Unfortunately, this means that I can only ever run the executable when libsfml-dev is installed, which is undesirable for game development. Whenever I even change the Other Linker Options or Search Directories>Linker will cause an error along the lines of:
error while loading shared libraries: libsfml-graphics.so.2.2.0: cannot open shared object file: No such file or directory. I assume this error happens because the libraries are relative, so it is completely portable.
EDIT:
I am using Code::Blocks (as you can see from the image), and I would like to know how I can link to the libraries relatively. They link fine when it is run from Code::Blocks, but when I run the executable I get the above error. My current Code::Blocks options are:
Linker Options:
(Other linker options is empty)
Search Directories:

Your first linker options would be the correct ones.
The Library libsfml-dev is only required on the compile machine.
There must also be another package which actually supplies the .so files. That one will also be required on the machine running the executable unless you package those .so files with your executable. In that case you probably need a script that sets LD_LIBRARY_PATH to the local directory containing the packaged .so files and then executes your program.

Related

g++ ld shared library error with code::blocks

There are similar topics, but I haven't managed to find my answer in them.
I am building a test console application using the code::blocks IDE. It needs to load a DVB shared library called libhdhomerun.so (from Silicon Dust) for the HD Homerun DVB tuners. The HDHR tuner library has being installed using ./configure, ..., sudo make install, ldconfig etc and it all works with their utilities (built at the same time). So - the library is there and OK.
The library installed itself into /usr/local/lib. There is actually no symlink to it as there is with other shared libraries, but then it doesn't have any version information on the end either.
When I build the code (having explicitly included /usr/local/lib/libhdhomerun.so), the ld stage fails with
"cannot find -lhdhomerun.so"
I have tried every combination of including (/usr/local/lib/) libhdhomerun.so, hdhomerun.so, libhdhomerun, hdhomerun, creating a symlink to it etc. Nothing makes any difference.
The bizarre thing is that I have udev, mysql and libdvbv5 shared libraries included in exactly the same way, and they are fine. The only one that will not link is hdhomerun.
If I run a manual verbose link step from the command line "ld -lhdhomerun.so --verbose", it does fail - because it is trying to find libhdhomerun.so.so.
Any suggestions gratefully received - but I do need to keep using code::blocks.
To link the library properly, you need to have library path defined in your environment, and use proper library name with -l flag. Library path is defined in LD_LIBRARY_PATH environment variable. For -l flag to g++, library extension should not be provided - as you already observed, so in your case it should be like this:
-lhdhomerun

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 !
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.

Compiling with c++ and getting "ready to go" executable

Is it possible to compile a program with g++ so that shared libraries etc are "included" with the executable?
I have a c++ program that I'd like to compile and run at another location where I'm missing some libraries and don't have install access.
The main reason I couldn't find answers for this is probably that I don't know how to call it..
No, it's not possible.
Either link statically (with -static) so it doesn't use any shared libraries, or copy the shared libraries to the other location along with the executable.
Since the shared libraries will not be in the dynamic loader's usual search paths you'll need to ensure they can be found, either by setting the LD_LIBRARY_PATH environment variable when running the program, or by setting an RPATH in the executable when you build it.
(Assuming you're using the GNU linker ...) To set an RPATH in the executable link with '-Wl,-rpath,$ORIGIN' (the quotes are important, to stop $ORIGIN being expanded by the shell). That means the loader will look for shared libraries in the same directory as the executable itself.
See https://gcc.gnu.org/onlinedocs/libstdc++/faq.html#faq.how_to_set_paths and https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_dynamic_or_shared.html#manual.intro.using.linkage.dynamic for more information.

Linker can't find lib in Eclipse/JNI/ANT

I am trying to build a large Java/c++ project involving JNI and ANT in Eclipse, under Linux. One of the source c++ files calls the log10() function for mathematical calculations. The project compiles fine, but fails at linking, where it complains that it cannot find the libm.so library necessary to link log10().
My problem is that I am unable to properly tell Eclipse to link that file, even after the following steps:
Added the correct library path in the linker options,
Added a reference to libm in the linker include list,
Added -lm to the full compile options list,
Set LD_LIBRARY_PATH to point to the library's location,
Copied the library to the current directory.
What am I doing wrong/has anyone had such experiences with correctly linking libs in Eclipse? Any suggestions?
This is a bit confusing.
If you fail to find your library at runtime inside your java environment :
Try loading your .so library inside the java environment before making any calls to log10.
System.LoadLibrary("m");
Notice how I left "lib" and ".so" out.
However, you are complaining of a Linker problem from C++, you cannot link to a dynamic file. You can only link to a static library, or a static export library (so you need a libm.a file to which to link at compile time, and then your program will require libm.so at runtime).
Could you post the exact message you are receiving and when you are receiving it ?

C++ shared libraries

I am trying to get my head around the way shared libraries work in the c++ unix environment. I understand we only need header files and no shared libraries specification when compiling code. But if I want to create an executable or shared library from my compiled files, do I need to specify shared library dependencies (those are dynamic)? And do the paths of shared libraries need to match the path at runtime loading?
I am using Linux 2.6.18-164.11.1.el5 #1 SMP x86_64 GNU/Linux
I am having a problem where my code is not able to pick up a library at runtime. I have tried setting LD_LIBRARY_PATH and PATH. But at runtime when I run the executable, I get the following error:
Error: librc.so: cannot open shared object file: No such file or directory
Sam
The headers are only for the compile phase. At link time, you usually have to specify which shared libs you are going to link to. You might see -L options to set locations to where shared libraries reside, and/or -l to specify which libraries to link. There is usually also a switch on the command line to alert the linker as to whether you are using thread-safe versions of the libs or the 'regular' ones, and another switch to specify dynamic linking.
At run time, whether you are starting the program that uses the libs, or running ldd to find out what it needs, the OS has a system for locating .so files, and this can vary from one unix version to another. The LD_LIBRARY_PATH variable specifies where to look for .so files, but may not be the full story, depending on the exact unix version in question. Also, you probably don't want to fiddle around with modifying LD_LIBRARY_PATH except from a throw-away shell, since it has system wide effects. A better option is to check it the 'missing' .so files are or are not on the existing path set by LD_LIBRARY_PATH, and if not, try putting copies of them somewhere on that path.
At run time, dynamic libraries are searched:
in a path recorded in the executable (under linux with -rpath at link time, under Solaris with -R, using $ORIGIN in a directory name allows to specify a directory relative to the directory containing the executable)
in the LD_LIBRARY_PATH (or equivalent, there are sometimes 64/32 bits variant). If a path has been recorded in the executable, LD_LIBRARY_PATH may not searched (under Linux it is searched after the recorded path if the executable has been linked with the option --enable-new-dtags; I don't remember Solaris behavior for now)
in a set of system dependant directories (Linux allows to specify them in /etc/ld.so.conf and has a cache, see ldconfig)