G++ cannot find library unless it is full path - c++

After installing boost from EPEL 5 on 64-bit CentOS 5.8 I run insto strange problem. I cannot link in other way then providing full path. I.e this works:
g++ ... /usr/lib64/libboost_python.so.5
But this cannot find -lboost_python
g++ ... -L/usr/lib64/ -lboost_python
What could be wrong?
PS. LD_LIBRARY_PATH does not help. It do finds some libraries but even symlinking into /usr/lib does not help. I am building 64-version of program (checked by file *.o).

Try to add a symlink : ln -s /usr/lib64/liboost_python.so /usr/lib64/libboost_python.so.5, then try again.

Related

Can't use static lib of mongo-cxx-driver on Linux

So I follow the official tutorial for the installation : https://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/installation/
Neverless, I can't use the produced libraries as static.
So I managed to compile the C version of the driver as described, I've enabled the flag --enable-static=yes with the ./configure before doing make && sudo make install and I got the libmongoc-1.0.a and the libbson-1.0.a which are static. So this far, everything it's alright.
Then I have done the cxx version of the driver, except that there is no configuration file as in the C version. So I've juste done a
cmake -DCMAKE_BUILD_TYPE=Release -DBSONCXX_POLY_USE_BOOST=1 -DCMAKE_INSTALL_PREFIX=/usr/local
from the build folder, followed by a make && sudo make install
So I got the libmongocxx.a and the libbsoncxx.a, but when I try to compile with them, I can't run the binary because I got the following error :
error while loading shared libraries: libmongocxx.so._noabi: cannot open shared object file: No such file or directory
So I understand that is because there is some symbols missing and then I need to use the shared library to run the binary but I don't want this to happend, I want the symbols within the binary that I can run it without any LD_PRELOAD.
Any suggestions ?
I had the same issue in an Ubuntu 16.04 and I run a apt-get update & apt-get upgrade and the problem was solved.
It seems that there were some update to the compiler and some libraries that prevent some test from reaching the shared libraries.
I have a similar question, and solved, now I compiled and run my binary with static libs successfully.
I write my build script using newlisp, but the static link options are very helpful, I paste it here.
c++ /to/your/path/site/code/back_end/builder/object/files1.cc.o ... /to/your/path/site/code/back_end/builder/object/files10.cc.o -o bin/site -static-libgcc -static-libstdc++ -L/usr/lib -lpthread -l:libmongocxx.a -l:libbsoncxx.a -l:libmongoc-1.0.a -l:libbson-1.0.a -lrt -lssl -lcrypto -lsasl2 -l:libboost_log.a -l:libboost_log_setup.a -l:libboost_system.a -l:libboost_thread.a -l:libboost_filesystem.a -lcppcms -lbooster -lcurl -ljsoncpp

Boost librairies not found but compilation is ok

I am trying to use filesystem from boost in c++
It seems the compilation is ok when using
"c++ -c Analyse.c -o Analyse.o -g -W -Wall -L/usr/local/lib -lboost_filesystem -lboost_system"
However I have the following error when trying to execute my code :
"error while loading shared libraries: libboost_filesystem.so.1.54.0: cannot open shared object file: No such file or directory", a find / -iname "libboost_system.so.1.54.0
I had some issues to install boost (I first installed the 1.49 and after that 1.54) so I was wondering if there could be any conflict between the 2 version ?
P.S : btw a "find / -iname "libboost_system.so.1.54.0" gave me the following
/usr/include/boost/boost_1_54_0/bin.v2/libs/system/build/gcc-4.7/release/threading-multi/libboost_system.so.1.54.0
/usr/local/lib/libboost_system.so.1.54.0
Try to add the directory before execution. For example:
LD_LIBRARY_PATH="/usr/local/lib/" ./Analyse.o
I encountered this issue very recently, after a fresh installation of boost. In my case, the solution was to simply run
sudo ldconfig
The explanation is that the system keeps a cache of the installed shared libraries (located in /usr/lib, /lib, /usr/local/lib). When the libraries are changed, or new ones are added, the cache is not updated until ldconfig is run. More details can be found in the ldconfig manual.

libboost-system linker errors when cross-compiling to x86

I'm trying to build a 32-bit application on Ubuntu 11.04 x64. I'm having some issues with the build because of linker errors with libboost. The build statement has -lboost_system in it, but when I try to build I get a bunch of these:
CommunicationModule.cpp:(.text+0x68c1): undefined reference to boost::system::generic_category()
CommunicationModule.cpp:(.text+0x68d7): undefined reference to boost::system::system_category()
Everything I've found on google says I need to link to the boost_system library. One place I found says to try linking to it directly, but when i do locate boost_system the result is empty. When I try doing a sudo apt-get install libboost-system-dev it tells me that it's already installed. I'm kind of at a loss here. The library is installed, but it's not being found by locate?
Can anyone tell me what I need to do to properly link to boost::system? I'm fairly new to linux and the complexities of compilers so any help here would be appreciated.
Update:
Here is the output of dpkg -L libboost-system1.42-dev:
/.
/usr
/usr/share
/usr/share/doc
/usr/share/doc/libboost-system1.42-dev
/usr/share/doc/libboost-system1.42-dev/copyright
/usr/share/doc/libboost-system1.42-dev/NEWS.Debian.gz
/usr/share/doc/libboost-system1.42-dev/README.Debian.gz
/usr/lib
/usr/lib/libboost_system.a
/usr/lib/libboost_system-mt.so
/usr/lib/libboost_system-mt.a
/usr/lib/libboost_system.so
Is there a flag I can use to link to one of these directly? I tried using -L /usr/lib/libboost_system.so and -L /usr/lib/libboost_system-mt.so and neither of those fixed the issue. Same with just adding /usr/lib/libboost_system.a and /usr/lib/libboost_system-mt.a to the build statement.
Here is the compilation line:
g++ -m32 -Wl,-O1 -o UTNaoTool [.o files] -L/usr/lib32 -lqglviewer-qt4 -lqwt-qt4 -lboost_system -lboost_thread -lQtXml -lQtOpenGL -lQtGui -lQtNetwork -lQtCore -lGLU -lpthread
Update 2:
I downloaded boost 1.49 and built everything for 32-bit and that seemed to help. A lot of the errors went away, but now I still have these:
CommunicationModule.cpp:(.text+0x68c1): undefined reference to
boost::system::get_generic_category()
Note that the function is different. So all of my errors are regarding undefined references to get_system_category() and get_generic_category() now. I tried adding a -lboost_filesystem to the build command but that didn't fix this, and I made sure it was referencing the 32-bit library that I built when I built libboost_system.
Looking at my own installation, it seems libboost-system-dev does not install the libraries. Using dpkg to tell me what was installed bz libboost-system-dev I get:
$ dpkg -L libboost-system-dev
/.
/usr
/usr/share
/usr/share/doc
/usr/share/doc/libboost-system-dev
/usr/share/doc/libboost-system-dev/copyright
/usr/share/doc/libboost-system-dev/changelog.gz
Poking around, I think you need to install libboost-system1.48.1 (or some other version).
sudo apt-get install libboost-system1.XX.Y
You can also search fo rthe libraries using the find command, for example, search under /usr for all files starting with libboost_system:
find /usr -name "libboost_system*"
Edit: Since you are cross-compiling from a 64 bit OS to a 32 bit one, you need 32 bit versions of the boost libraries. I would be tempted to set up a small 32 bit virtual machine to do this, rather than cross-compiling all the dependencies.
I had the same problem with boost_serialization here is what i found out after couple of googling..
first this library need to be compiled separately :
so after downloading the boost library ,extract it and execute sudo ./bootstrap.sh' then
sudo ./b2 --with-system
after this step you should be find a result when executing locate boost_system
then to link it manually I did:
both should work
g++ boostexample.cpp -o run /PATH/libboost_serialization.a
g++ boostexample.cpp -o run -L/PATH/ -lboost_serialization
well this is a little work around and I'm still looking for how to link the library properly
I hope this helped :)

Ubuntu 11.10 linking perftools library

I can't get gcc in Ubuntu 11.10 to properly link in the google perftools -lprofiler.
The problem seems to be that the linker discards libraries which are not directly used in a program.
An example will help.
Let's call this main.cpp:
#include <math.h>
int main()
{
double value;
for (int i=0; i < 1000000; i++)
{
for (int j=0; j < 1000; j++)
value = sqrt(100.9);
}
return 0;
}
Compile using:
g++ -c main.cpp -o main.o
g++ main.o -o main -lm -lprofiler
Check the executable using ldd ./main:
linux-vdso.so.1 => (0x00007fff5a9ff000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f32bc1c9000)
/lib64/ld-linux-x86-64.so.2 (0x00007f32bc593000)
Normally, I would run:
CPUPROFILE=/tmp/profile ./main
to produce profile output. But since the profile library is not linked in no profile output is generated.
I've made sure the profiler library is in my search path, and have tried directly linking against the shared library and static library.
The above test works fine on Ubuntu 10.04, Ubuntu 10.10, Ubuntu 11.04, SUSE 12.1, and Fedora 16.
Also, once I include function calls that use the profiler (such as ProfilerStart() and ProfilerStop()), then the profiler library gets linked into the executable.
Any ideas on how to get gcc to link in the profiler library?
Thanks.
g++ main.o -o main -lm -lprofiler
As another.anon.coward commented, you are likely falling victim of your g++ using --as-needed linker flag. Try this instead:
g++ main.o -Wl,--no-as-needed -lprofiler -Wl,--as-needed
Notes:
g++ already adds -lm, no need to add it again
It is important to turn --as-needed back on. Not doing so will likely cause you to link to additional libraries that you don't really need.
In my case, the problem was that there was only a libprofiler.so.0, and no libprofiler.so in /usr/lib/:
user#compy:/usr/include$ dpkg -L libgoogle-perftools4
/.
/usr
/usr/share
/usr/share/doc
/usr/share/doc/libgoogle-perftools4
/usr/share/doc/libgoogle-perftools4/README.Debian
/usr/share/doc/libgoogle-perftools4/copyright
/usr/lib
/usr/lib/libprofiler.so.0.4.5
/usr/lib/libtcmalloc.so.4.2.6
/usr/lib/libtcmalloc_debug.so.4.2.6
/usr/lib/libtcmalloc_and_profiler.so.4.2.6
/usr/share/doc/libgoogle-perftools4/AUTHORS
/usr/share/doc/libgoogle-perftools4/TODO
/usr/share/doc/libgoogle-perftools4/README.gz
/usr/share/doc/libgoogle-perftools4/NEWS.gz
/usr/share/doc/libgoogle-perftools4/changelog.Debian.gz
/usr/lib/libtcmalloc.so.4
/usr/lib/libtcmalloc_and_profiler.so.4
/usr/lib/libprofiler.so.0
/usr/lib/libtcmalloc_debug.so.4
I don't know what the official fix to this is, but I simply created a symlink in /usr/lib:
user#compy:/usr/lib$ sudo ln -s libprofiler.so.0 libprofiler.so
This will make -lprofiler work.
If you don't mind changing your Makefile you can alternatively specify -l:libprofiler.so.0 instead of -lprofiler (note the extra colon) (source).
EDIT: The official way to get the .so is apparently to install the libgoogle-perftools-dev package as explained here:
user#compy:/usr/lib$ dpkg -S libprofiler.so
libgoogle-perftools-dev: /usr/lib/libprofiler.so
libgoogle-perftools4: /usr/lib/libprofiler.so.0.4.5
libgoogle-perftools4: /usr/lib/libprofiler.so.0
I understand that if you want to link to a certain lib, you should install the libx-dev package, which will contain the /usr/lib/libx.so. This file will only be a symlink to a specific version, such as /usr/lib/libx.so.1.2. When you link against /usr/lib/libx.so by specifying -lx to your linker, you will actually create a link in your program against the specific version linked at the time by recording a SONAME of libx.so.1 (the last version number is stripped as oulined here). So when you run your program at a later point in time the dynamic linker will look only for /usr/lib/libx.so.1, which is symlinked to /usr/lib/libx.so.1.2, and no /usr/lib/libx.so hence no dev package needs to exist.
So the libx-dev packages is for compiling and linking against libx, and the libx package is for running a precompiled program against libx.

Boost and Python 3.x

How does boost.python deal with Python 3? Is it Python 2 only?
Newer versions of Boost should work fine with Python V3.x. This support has been added quite some time ago, I believe after a successful Google Summer of Code project back in 2009.
The way to use Python V3 with Boost is to properly configure the build system by adding for instance:
using python : 3.1 : /your_python31_root ;
to your user-config.jam file.
libboostpython needs to be built with python3 in order to do this. This doesn't work with boost 1.58 (which comes with Ubuntu 16.04), so make sure you download the latest boost distribution. I just did this with boost_1_64_0.
As mentioned above, find the file "user-config.jam" in you boost code distribution, and copy it to $HOME.
cp /path/to/boost_1_64_0/tools/build/example/user-config.jam $HOME
Then edit the python line (the last line) so that is says:
using python : 3.5 : /usr/bin/python3 : /usr/include/python3.5m : /usr/lib ;
This is correct for Ubuntu 16.04. You can use pkg-config to find the correct include directory.
user#computer > pkg-config --cflags python3
-I/usr/include/python3.5m -I/usr/include/x86_64-linux-gnu/python3.5m
And you only need the first include directory.
Then build boost from scratch. (Sorry.) I install it to /usr/local
cd /path/to/boost_1_64_0
./bootstrap.sh --prefix=/usr/local
./b2
sudo ./b2 install
Now jump into the python example directory, and build the tutorial
cd /path/to/boost_1_64_0/libs/python/example/tutorial
bjam
This will not build correctly if you have a system install of boost, because, under the hood, bjam is linking to libboostpython using the g++ parameter "-lboost". But, on Ubuntu 16.04, this will just go and find "/usr/lib/x86_64-linux-gnu/libboost_python-py27.so.1.58.0", and then the python bindings will fail to load. In fact, you'll get his error:
ImportError: /usr/lib/x86_64-linux-gnu/libboost_python-py27.so.1.58.0: undefined symbol: PyClass_Type
If you want to see the g++ commands that bjam is using, do this:
user#computer > bjam -d2 -a | grep g++
g++ -ftemplate-depth-128 -O0 -fno-inline -Wall -g -fPIC -I/usr/include/python3.5m -c -o "hello.o" "hello.cpp"
g++ -o hello_ext.so -Wl,-h -Wl,hello_ext.so -shared -Wl,--start-group hello.o -Wl,-Bstatic -Wl,-Bdynamic -lboost_python -ldl -lpthread -lutil -Wl,--end-group
Here we see the problem, you need "-L/usr/includ/lib" just before "-lboost_python". So execute this to link the shared library correctly:
g++ -o hello_ext.so -Wl,-h -Wl,hello_ext.so -shared -Wl,--start-group hello.o -Wl,-Bstatic -Wl,-Bdynamic -L/usr/local/lib -lboost_python -ldl -lpthread -lutil -Wl,--end-group
You may need to rerun ldconfig (or reboot)
sudo ldconfig
And you are finally ready to go:
user#computer > python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello_ext
>>> hello_ext.greet()
'hello, world'
>>> exit()
Yes this question is super old, but I had to do something that wasn't specified in any of the answers here (though it was built off some of the suggestions), so I'll quickly jot down my entire process:
Download boost_X_Y_Z.tar.bz2 (I used boost 1.68.0)
tar --bzip2 -xf boost_1_68_0.tar.bz2 (where you want folder to be temporarily)
cd boost_1_68_0
./bootstrap.sh --with-python-version=3.6 --prefix=/usr/local
./b2
sudo ./bjam install
cp tools/build/example/user-config.jam $HOME, then modify the contents of this file to say using python : 3.6 : /usr/bin/python3 : /usr/include/python3.6m : /usr/lib ; (or whatever folders are appropriate for your environment)
Given this C++ source file BoostPythonHelloWorld.cpp:
#include <boost/python.hpp>
char const* say_hi()
{
return "Hi!";
}
BOOST_PYTHON_MODULE(BoostPythonHelloWorld)
{
boost::python::def("say_hi", say_hi);
}
And this Python script BoostPythonHelloWorld.py:
import BoostPythonHelloWorld
print(BoostPythonHelloWorld.say_hi())
It can be compiled and ran as such:
gcc -c -fPIC -I/path/to/boost_1_68_0 -I/usr/include/python3.6 /other_path/to/BoostPythonHelloWorld.cpp
gcc -shared -Wall -Werror -Wl,--export-dynamic BoostPythonHelloWorld.o -L/path/to/boost_1_68_0/stage/lib -lboost_python36 -o BoostPythonHelloWorld.so
python3 BoostPythonHelloWorld.py
The part that was different for me was -Wl,--export-dynamic BoostPythonHelloWorld.o, I had not seen that anywhere else, and I was getting a Python error concerning an undefined symbol until I added that.
Hope this helps someone down the line!
If you get "error: No best alternative for /python_for_extension" be sure to have
using python : 3.4 : C:\\Python34 : C:\\Python34\\include : C:\\Python34\\libs ;
only in user-config.jam in your home path and nowhere else.
Use double backslashes when compiling under windows with mingw (toolset=gcc) or MSVC (toolset=msvc).
Compile with cmd, not msys, and if you also have python 2.7 installed remove that from PATH in that shell.
First do
bootstrap.bat gcc/msvc
assuming you have the gcc/msvc tools available via PATH (/ for the alternatives, but use only one, or leave away)
Afterward you can also do
booststrap.sh --with-bjam=b2
in msys to generate a project-config.jam, but need to edit it to remove the "using python" and "/usr",..
Then the following
b2 variant=debug/shared link=static/shared toolset=gcc/msvc > b2.log
With static the python quickstart examples did not work for me, although I would prefer to do without the boost_python dll.
I did not try on linux, but it should be more straightforward there.
You can even specify the python distribution via
./bootstrap.sh --with-python=<path to your python binary>
e.g.
./bootstrap.sh --with-python=python3
for your system's python3 or
./bootstrap.sh --with-python=$VIRTUAL_ENV/bin/python
for the python version of your currently active virtual env python.
Refer this to know how to build boost with python. It shows the way to build with python2 with Visual Studio 10.0 (2010). But I go through the same procedure for a project that I am currently working on and it works fine with python 3.5 and Visual Studio 14.1 (2017).
If you get this error when building your python boost project, just add BOOST_ALL_NO_LIB value to Preprocessor Definitions (inside C\C++ > preprocessor tab) in your project properties.
And also, do not forget to add boost .dll files location to your system path.
When the path to Python contains spaces, you will be in for quite a ride. After a whole lot of trial and error, I finally managed to get something that works. Behold my user-config.jam (which has to be in my home directory for bjam to find it):
import toolset : using ;
using python : 3.6
: \"C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\\Shared\\Python36_64\\python.exe\"
: C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\\Shared\\Python36_64\\include
: C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\\Shared\\Python36_64\\libs
;
The inconsistent quoting is intended and seems to be required. With this I can build boost-python and use it as Boost::python36 in my CMakeLists.txt. Still, one issue remains: I have to link to python manually viz
target_link_libraries(MyTarget
Boost::boost Boost::python36
"C:/Program Files (x86)/Microsoft Visual Studio/Shared/Python36_64/libs/python36.lib")
target_include_directories(MyTarget PRIVATE
"C:/Program Files (x86)/Microsoft Visual Studio/Shared/Python36_64/include")
In my case adding "Using Python : 3 etc." into user-config.jam in my home directory didn't work. I had to add the line into project-config.jam instead, which resides in the root directory of unpacked boost.
Specifically the line was:
using python : 3.9 : /usr/bin/python3 : /usr/include/python3.9 : /usr/lib ;
and the version of boost was 1_78_0