Boost library missing at runtime (Can compile. Can't run) - c++

This is a pretty entry level question but I just can't seem to find any relevant answers.
I can compile this no problem using the following command:
g++ client.cpp -o client -lboost_system -lpthread
When I try to run the program I get the following error:
./client
./client: error while loading shared libraries: libboost_system.so.1.58.0: cannot open shared object file: No such file or directory
this file exists: /usr/local/lib/libboost_system.so
What am I doing wrong here?

You have to set the path where to find the shared object, the command LD_LIBRARY_PATH=path where shared object is will do it. I guess file is somewhere otherwise link would fail.

It should be some linking error,
Try to compile it and create the .o file first.
g++ -C .cpp // here you need to mention the includes from library. -I
And then create the executable,
g++ -O // here you need to mention the path of the library. -l
Incase your prog is correct, it will create the exe else it will show you the error. Incase of linking error, try to include the .h and lib path correctly in the program.

I didn't get a chance to test your answers. Upgraded to ubuntu 15.04 while troubleshooting another unrelated problem which happened to fix this problem aswell.
Thanks anyway.

Related

C++ Executable cannot find library at runtime, even though it's in /usr/lib (On Linux)

I'm creating a game in c++ with the Panda3D framework on Ubuntu. All of the Panda3D shared libraries are in /usr/lib/panda3d and all of the headers are in /usr/include/panda3d. I'm compiling with SCons, but I've tried it with gcc and it's the same, so here are the commands:
g++ -o src/main.o -c -fPIC -O2 -std=gnu++11 -I/usr/include/python2.7 -I/usr/include/panda3d -Iinclude src/main.cpp
g++ -o Test src/main.o -L/usr/lib/panda3d -lp3framework -lpanda -lpandafx -lpandaexpress -lpandabullet -lp3dtoolconfig -lp3dtool -lp3direct -lpthread
And here is the error I get when I run the executable:
./Test: error while loading shared libraries: libp3framework.so.1.11: cannot open shared object file: No such file or directory
There isn't much in the code, just initializing a Panda3D window, so I doubt that's the culprit.
As I said before, the libraries are in /usr/lib/panda3d, I've checked about a million times now and it's driving me crazy. I can't think of a single reason why I would get this error. Any help is appreciated :)
Edit:
I was looking through my files and there's a panda3d.conf file in /etc/ld.so.conf.d with one line: /usr/local/lib/x86_64-linux-gnu/panda3d. Does this have anything to do with it?
Edit #2:
I used the path in the above edit as the library path and got the same results, unfortunately.
I can't think of a single reason why I would get this error.
The reason is very simple: the dynamic loader hasn't been told to look in /usr/lib/panda3d for shared libraries, and so doesn't.
You can run your program with:
LD_DEBUG=files,libs ./Test
and observe which directories the loader is searching.
panda3d.conf ... with one line: /usr/local/lib/x86_64-linux-gnu/panda3d
That is the wrong directory (or at least not the one where your libraries are).
One way to fix this is to correct the above path to /usr/lib/panda3d and run sudo ldconfig.
Another way is to add -Wl,-rpath=/usr/lib/panda3d to your link line.

Can't link libboost solution on running time

I installed boost_1_55_0 under /usr/local/boost_1_55_0, and in my makefile I set the linking flag as:
CC = g++
CFLAGS = -I ./ -I/usr/local/boost_1_55_0 -w -std=c++11
LFLAGS = -L./ -lm -lpthread -L/usr/local/boost_1_55_0/lib -lboost_regex
I encountered nothing during compile time, but I got:
./$(exec): error while loading shared libraries:
libboost_regex.so.1.55.0: cannot open shared object file: No such file
or directory
I'm pretty sure I cleaned all old files and compiled again, I also granted access to read the files in usr/local/boost_1_55_0 by sudo chmod -R +x /usr/local/boost_1_55_0 just in case I banned access to read. However, I still got this error. I also tried to move boost_1_55_0 in /usr/lib/ but it does not work either.
I've also read this question: Compiling issue with boost and tried both solutions under this question, but neither of them works for me. Can someone figure out a different solution?
As the error implies, your executable is unable to find the shared library. Add the .so file (or all of them, if you want to be safe) that was generated by the boost build process to the same directory where your program's executable is getting generated, and try running the program again.
I manually cleaned the executable files and compiled it again, and it somehow solved my problem. I am guessing there must be some config in my system messed up so that the executable would invisibly linked to some outdated directory and cause this problem.

Compiling an external library on Linux

Good Day Everyone,
N.B - This problem has been solved - I have provided my own solution in the answer section however the solution provided by Jonathan is much shorter. Nevertheless, this was the following question I originally posted:
I am basically trying to compile a serial library (for UART communication) on Linux however I am not really sure how to correctly compile (I have mentioned what I have done so far below), any suggestions would be highly valuable. I am using the serialib library - which is composed of 2 main files (serialib.h and serialib.cpp) , you may directly view the source code of these files here (scroll all the way to the bottom and view the files in new tabs): http://serialib.free.fr/html/classserialib.html
I transferred these files (serialib.h and serialib.cpp) to my BeagleBone Black micro-controller which is running Debian (Wheezy) , g++/gcc (Debian 4.6.3-14) 4.6.3. I wrote my own program (uart.cpp is my file name) to access the functions provided by this library, this is what I wrote:
#include <iostream>
#include "serialib.h"
#ifdef __linux__
#define DEVICE_PORT "/dev/ttyO1"
#endif
int main()
{
serialib LS;
return 0;
}
So as you can see I am trying to access the 'seriallib' class. serialib.h, serialib.cpp and uart.cpp are all in the home directory. I also manually added the iostream library in serialib.cpp as I did not see it being declared in the original source code.
Now I am really unsure of how to compile such external libraries but so far I tried the following steps:
g++ -c -Wall -Werror -fPIC serialib.c to convert to PIC which gives the following error:
distcc[3142] (dcc_parse_hosts) Warning: /home/debian/.distcc/zeroconf/hosts contained no hosts; can't distribute work
distcc[3142] (dcc_zeroconf_add_hosts) CRITICAL! failed to parse host file.
distcc[3142] (dcc_build_somewhere) Warning: failed to distribute, running locally instead
g++ serialib.cpp -L /home/debian/serialib.h which gives the following error:
/usr/lib/gcc/arm-linux-gnueabihf/4.6/../../../arm-linux-gnueabihf/crt1.o: In function _start':
(.text+0x30): undefined reference tomain'
collect2: ld returned 1 exit status
distcc[3210] ERROR: compile serialib.cpp on localhost failed
As of now I am still finding out how to compile this and if I manage to work this out then I'll post my solution here too. Once again any suggestion will be highly valuable. Thank you all :) .
g++ -c -Wall -Werror -fPIC serialib.c to convert to PIC which gives the following error:
The "error" is not an error, it's a warning, telling you that your distcc setup is broken, but that it compiled locally.
That command doesn't "convert to PIC", it compiles the file serialib.c and produces a compiled object file, serialib.o
g++ serialib.cpp -L /home/debian/serialib.h
This is just nonsense. It tries to build a program from serialib.cpp and use the directory /home/debian/serialib.h (which isn't a directory!) to find libraries.
You don't need to "compile a library" you can just compile both the source files and link them together into a program. Either:
g++ -c serialib.cpp
g++ -c uart.cpp
g++ serialib.o uart.o -o uart
Or all in one command:
g++ serialib.cpp uart.cpp -o uart
You should read An Introduction to GCC to understand the commands, not just enter bogus commands without understanding them.
I have found a solution to this problem, hope this helps for all the future readers with similar problems. I have my own source code uart.cpp (Given in the question) which I want to compile, the external library is serialib that contains two main files (serialib.h and serialib.cpp), you will want to replace the following commands with respect to the files you have
Step 1: Compiling with position independent code
g++ -c -Wall -Werror -fpic serialib.cpp
Step 2: Creating a shared library
g++ -shared -o libserialib.so serialib.o , here the library is libserialib.so.
Step 3: Linking your source code with library
g++ -L /home/debian -lserialib uart.cpp -o uart
g++ -L /home/debian -Wall -o test uart.cpp -lserialib
You may save the library at a different path and you may have a different name of course. Suppose you have a library called libabc.so at the directory /home/user/myDir then the commands will be like:
g++ -L /home/user/myDir -labc your_code.cpp -o your_code
g++ -L /home/user/myDir -Wall -o test your_code.cpp -labc
test is out own program, lserialib is actually looking for libserialib.so and not serialib.o as gcc/g++ assumes all libraries start with lib and end with .so or .a and you can see the same goes for labc as it will look for libabc.so thus it is important to make sure your library name begins with lib and ends with .so or .a
Step 4: Making library available at run time
Here we provide the path where the library is actually stored, I saved it in the directory /home/debian which is why my command looks like:
export LD_LIBRARY_PATH=/home/debian:$LD_LIBRARY_PATH
if your library is saved at /path/to/file then the command will look like:
export LD_LIBRARY_PATH=/path/to/file:$LD_LIBRARY_PATH
This is to help the loader find the shared library and to view this path: echo $LD_LIBRARY_PATH and to unset this: unset LD_LIBRARY_PATH
To execute the program type either ./test or ./uart and in case of any modification to the main source code (uart.cpp in this case) , simply repeat step 3. I found the following link very useful: http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html . Thank you to all of you who took time to read this question and especially those who gave me suggestions. If anyone has more or better solutions, feel free to post them here to assist future readers :).

Is there a way to find which library file is to be used when compiling?

When compile with g++ -lboost_system code.cpp -o a.out, the linker will try to find the library file (libboost_system.so). What if there are more than one such file existing in different directory, how can I know which one is been chosen?
PS: I try to compile a project, it needs a high version of libboost than the one been installed. I compile libbost_1_55_0 and install it to /usr/local/, however, when I try to compile the project, it still report errors about libboost, it seems that the old version is been used rather than the new version. I want to make out which version of boost is been used.
From the gcc man page:
-Ldir
Add directory dir to the list of directories to be searched for -l.

c/c++ boost - problem compiling

I've been pulling my hair out trying to figure out how to compile my app with boost regex.
I've installed boost from source on centos 5.
g++ -lboost_regex -o my_app my_app.c $(mysql_config --libs --cflags)
It compiles without any errors, however when I execute it:
error while loading shared libraries: libboost_regex.so.1.46.1: cannot open shared object file: No such file or directory
The location of that file is:
/usr/local/lib/libboost_regex.so.1.46.1
Anyone experience the same issues?
Did you try LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH your_program to make sure it knows where to find the shared object? You can set the path when you link by using -Wl,-R/usr/local/lib.
EDIT: To be more clear, when you link your code the linker will embed an RPATH and RUNPATH into the binary. These values tell the runtime loader where to find required shared objects.
If you add -Wl,-R/usr/local/lib to your link command that should cause it to embed that directory and always check it when loading your program.
Try this.
$ LD_LIBRARY_PATH=/usr/local/lib:LD_LIBRARY_PATH
$ export LD_LIBRARY PATH
Now try and tell us what happens.