Boost installation and library paths - c++

I have been using Boost (the header only library part) for sometime now. I recently started on a project that required the compiled libraries (filesystem etc).
I followed the instructions given in the documentation, and was under the impression that the libraries to installed (directly) in the usr/local folder. After a lot of trial and error, I found that the correct (*.a) files to use were in:
/usr/local/boost_1_45_0/stage/lib/
Is this the correct folder to use for linking the boost built shlibs (shared libraries)?

An example for linking regex static(*.a) lib:
g++ -I /usr/local/boost_1_45_0 -c your_regex_prog
g++ -static -o static_regex your_regex_prog.o -lboost_regex

Related

Link libraries to linux biinary file in c++

I'm compiling a c++ program using g++ and i am using two libraries called libsdl2-dev and libsdl2-image-dev
I installed both these libraries in my ubuntu machine with the commands
apt install libsdl2-dev libsdl2-image-dev and when I compile the program everything works fine. Then I copied these libraries from /usr/lib/x86_64-linux-gnu/ to my working dir with the binary file to be able to give this folder to someone else.
The problem comes when the user that hasn't installed these libraries tries to open my program by writing ./main (the binary file). Since he hasn't installed these libraries he would get an error like "can't open shared object: no such file or directory".
This happens because the binary file looks for these libraries in /usr/lib etc...
What i need
I need that my binary file looks for these libraries in the same folder,and not in /usr/lib/x86 etc.., from what I read I have to do something like rpath
The IDE used is Sublime Text and the syntax used to compile all my files is this:
g++ -c src/*.cpp -std=c++14 -m64 -g -Wall -I include && g++ *.o -o bin/debug/main -lSDL2main -lSDL2 -lSDL2_image && ./bin/debug/main`
Structure of folders
I got the project dir with and inside that i got 4 more directories, each one called: bin (with the debug subdirectory, where we got the final compile), include (with hpp files), res (with all textures), and src with all cpp files to compile, the other files are project files and .o files
I'm using Ubuntu 20.04-2 LTS and the same is for the other user's PC
Thanks in advance for any help!
That's because the dynamic linker loading runtime dependencies looks for them in some specified locations, which are "by default" your system library directories (where those libraries got installed by apt).
The other user should ideally install those libraries too (which could be done "automatically" if you build a .deb package with proper dependencies)
Otherwise you would have to change the runpath of your program by adding -Wl,-rpath='$ORIGIN', which makes the dynamic linker look for dependencies just where the binary is located.
$ORIGIN here is a special variable meaning "this executable" which is what you wanted to achieve.
see rpath
and A description of RPATH $ORIGIN
I found a way to resolve!
I used the program patchelf to add an rpath to my directory (linked to the binary file) now everything works
use ldd ./bin/debug/main to check the library
export LD_LIBRARY_PATH =$LD_LIBRARY_PATH:"your library path"
run the program,if this is not work. use patchelf to change the rpath to you r library

Simple Boost code doesn't build

When I am including the asio header:
#include <boost/asio.hpp>
I got the error:
undefined reference to boost::system::generic_category()
So I read that I had to link to boost_system which I did. But now it gives the error::
cannot find -lboost_system
Why can it not find boost_system. I'm using Codeblocks on Windows.
boost is a separate library that needs to be installed on you building machine.
Please follow these instructions to install:
http://www.boost.org/doc/libs/1_55_0/doc/html/bbv2/installation.html
http://www.boost.org/
After installation your application needs to be able to find it if it is not installed in a standard location.
you will need to supply the header and lib directories to the build process.
g++ source source.cpp -I/path to boost headers -L path to boost libs -lboost_system
Look inside you libs directory to be sure that you have boost_system. It is possible depending on the build that you may only have boost_system-mt

C++ make link step : Undefined symbols for architecture x86_64

I am trying to link a compiled research experiment project, built in C/C++.
The project is dependant on HyperNEAT and robot simulation software WeBots.
I have cloned and built the HyperNEAT project successfully (in that project there are other dependancies such as Boost, TinyXML, JGTL (custom library) and other unrelated subprojects).
I have made a makefile including all neccesary header search paths and library paths, and compiling the two main .cpp files:
/ModHyperNEAT/mod_ctrler7.cpp
/ModSupervisor/mod_supervisor.cpp
works, giving me 2 .o files.
However, in the make link step, when I want to create (separate) executables of both files, I am getting the 'undefined symbols for architecture x86_64' error (see pastebin here: http://pastebin.com/kiwwCcUf). It seems that C++ standard datatypes and functions such as
std::string::end() const cannot be found.
I have googled and searched SO for answers regarding this, and it seems that either libraries are missing or binary incompatible if i understand correctly, but the libraries are there and both projects have been compiled with the -lstdc++ flag.
This is the make link step (and the used macro's from the makefile) :
CC = gcc
CFLAGS = -v -g -lstdc++ -Wall -Wno-error -ferror-limit=100 -fmessage-length=0
DEFINES = -DHCUBE_NOGUI -DTIXML_USE_STL
FLAGS = $(CFLAGS) $(DEFINES)
LIB_TINYXML = -L/Users/michahell/Documents/projects_c++/HyperNEAT/tinyxmldll/out
LIB_HYPERNEAT = -L/Users/michahell/Documents/projects_c++/HyperNEAT/NE/HyperNEAT/out
LIB_BOOST = -L/usr/local/Cellar/boost/1.57.0/lib
LIB_WEBOTS = -I/Applications/Webots/lib
LIBS = $(LIB_TINYXML) $(LIB_HYPERNEAT) $(LIB_BOOST) $(LIB_WEBOTS)
LIBFLAGS = -ltinyxmlpluslib -lboost_filesystem-mt -lboost_random-mt -lboost_system-mt -lNEATLib_d -lHypercube_NEAT_Base_d
WEBOTS_DYLIB = -dylib_file /Applications/Webots/lib/libController.dylib:/Applications/Webots/lib/libController.dylib
$(CC) $(FLAGS) $(LIBS) ./mod_ctrler7.o $(WEBOTS_DYLIB) $(LIBFLAGS)
I found out that to link to .dylib's I had to use a specific flag and specify the full path, hence the $(WEBOTS_DYLIB) macro.
I am using the -lstdc++ flag because in the HyperNEAT project that flag was also used for building that library. If i exclude this flag, i get a lot of errors during compilation (libc++ and libstdc++ incompatibility as I now understand). All of the library paths check out, and .a and/or .dylib files are present.
My knowledge of C/C++ and GCC tooling is very limited, as I have never had to use it before.
I think it might have to do with the fact that the HyperNEAT project contains a Boost 1.57.0 distribution which is used for their build, and that i have a separate (using homebrew) Boost version installed on my system, which is the same version:
$ brew info boost
boost: stable 1.57.0 (bottled), HEAD
http://www.boost.org
/usr/local/Cellar/boost/1.57.0 (10572 files, 439M) *
What could be the cause of this error failing my link step? Anyone should be able to reproduce my linker errors if both HyperNEAT and my project are cloned and put their root dirs in the same location. WeBots should be downloaded but only for the header includes and libraries. And of course my makefile paths should be modified.
If anyone can give me tips on how to solve this problem, i would GREATLY appreciate it!
It turns out that, for some reason, I had to include the lstdc++ flag to the library link flags and not as a compiler flag, AND the stdlib=libstdc++ as compiler flag.

Linux mingw32 sfml cross compile for windows - missing dll files

I am compiling my C++ project in the following way:
/usr/bin/i686-w64-mingw32-g++ -g -std=c++0x -Wall -I /home/bluszcz/dev/win64/SFML-2.1/include -L /home/bluszcz/dev/win64/SFML-2.1/lib -static-libgcc -static-libstdc++ -static -O4 -c src/game.cpp -o src/game.a -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio
However, when I try to run my exe file I am getting an error about missing DLL files:
bluszcz#zendo ~/dev/win32/builds/magicwizard $ wine mw.exe
err:module:import_dll Library libgcc_s_dw2-1.dll (which is needed by L"Z:\\home\\bluszcz\\dev\\win32\\builds\\magicwizard\\sfml-system-2.dll") not found
err:module:import_dll Library libgcc_s_sjlj-1.dll (which is needed by L"Z:\\home\\bluszcz\\dev\\win32\\builds\\magicwizard\\libstdc++-6.dll") not found
err:module:import_dll Library libwinpthread-1.dll (which is needed by L"Z:\\home\\bluszcz\\dev\\win32\\builds\\magicwizard\\libstdc++-6.dll") not found
err:module:import_dll Library libstdc++-6.dll (which is needed by L"Z:\\home\\bluszcz\\dev\\win32\\builds\\magicwizard\\sfml-system-2.dll") not found
err:module:import_dll Library sfml-system-2.dll (which is needed by L"Z:\\home\\bluszcz\\dev\\win32\\builds\\magicwizard\\sfml-audio-2.dll") not found
err:module:import_dll Library libgcc_s_dw2-1.dll (which is needed by L"Z:\\home\\bluszcz\\dev\\win32\\builds\\magicwizard\\sfml-audio-2.dll") not found
err:module:import_dll Library libgcc_s_sjlj-1.dll (which is needed by L"Z:\\home\\bluszcz\\dev\\win32\\builds\\magicwizard\\libstdc++-6.dll") not found
err:module:import_dll Library libwinpthread-1.dll (which is needed by L"Z:\\home\\bluszcz\\dev\\win32\\builds\\magicwizard\\libstdc++-6.dll") not found
err:module:import_dll Library libstdc++-6.dll (which is needed by L"Z:\\home\\bluszcz\\dev\\win32\\builds\\magicwizard\\sfml-audio-2.dll") not found
I have compiled using static options - so why it asks for libgcc_s_dw2-1.dll for example?
Also, I copied some files there, but the application still doesn't see them.
bluszcz#zendo ~/dev/win32/builds/magicwizard $ ls *dll
libsndfile-1.dll sfml-audio-2.dll sfml-graphics-d-2.dll sfml-system-2.dll sfml-window-d-2.dll
libstdc++-6.dll sfml-audio-d-2.dll sfml-network-2.dll sfml-system-d-2.dll
openal32.dll sfml-graphics-2.dll sfml-network-d-2.dll sfml-window-2.dll
bluszcz#zendo ~/dev/win32/builds/magicwizard $
And some files, like libgcc_s_dw2-1.dll, don't exist on my file system at all...
To summarize:
Why does my application not see the missing files?
How to compile in static way with mingw32?
How to get the missing files?
I use this version of sfml library to compile it: http://www.sfml-dev.org/download/sfml/2.1/SFML-2.1-windows-gcc-4.7-mingw-32bits.zip
The missing dll's can simply be added to your WINEPATH before running your program with wine, i.e.
export WINEPATH="/usr/x86_64-w64-mingw32/lib;/usr/lib/gcc/x86_64-w64-mingw32/7.3-posix"
!Note, your paths might be slightly different depending on the mingw version you are using.
Answering only the last of the three question:
About the standards libraries, it worked for me to copy them from the mingw folder:
cp /usr/lib/gcc/i686-w64-mingw32/5.3-win32/libstdc++-6.dll ./
However, when I copied from the wrong directory according to my build (e.g. /usr/lib/gcc/x86_64-w64-mingw32/5.3-posix/libstdc++-6.dll) I still had the same error while the file with the exact same name was here.
On my Fedora 26 after installing mingw64-gcc and mingw64-gcc-g++:
[leo#pc]$ locate libgcc_s_seh-1.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libgcc_s_seh-1.dll
[leo#pc]$ locate libstdc++-6.dll
/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libstdc++-6.dll
[leo#pc]$
If I copy dll's and run wine with generated a.out.exe it works.
Probably your application isn't seeing the files because it's configured like that, and you don't need to add tags like -static to the command.
For compiling static libraries, you must add -s, like -lsfml-window-s -lsfml-system-s
libgcc_s_dw2-1.dll is just inside bin folder, on latest MinGW releases.
If there are missing dlls, there's probably a version incompatibility.

Creating dummy shared object (.so) to depend on other shared objects

I'm trying to create a shared object (.so) that will make it so, by including one shared object with -lboost, I implicitly include all the boost libraries. Here's what I tried:
#!/bin/sh
BOOST_LIBS="-lboost_date_time-gcc43-mt -lboost_filesystem-gcc43-mt"
#truncated for brevity
g++ $BOOST_LIBS -shared -Wl,-soname,libboost.so.1 -o libboost.so.1.0
ln -si libboost.so.1.0 libboost.so.1
ln -si libboost.so.1 libboost.so
After placing all 3 created files (libboost.so libboost.so.1 libboost.so.1.0) in the same directory as all the boost libraries, I tried compiling a test program with it (which depends on -lboost_date_time-gcc43-mt):
g++ -lboost test.cpp
Doing this, I got the same undefined reference message as not having -lboost. Having -lboost_date_time-gcc43-mt works, but that's too wordy :) How do I get -lboost to automatically bring in the other shared libraries?
You don't. Not really, anyway.
The linker is stripping out all of the symbol dependencies because the .so doesn't use them.
You can get around this, perhaps, by writing a linker script that declares all of the symbols you need as EXTERN() dependencies. But this implies that you'll need to list all of the mangled names for the symbols you need. Not at all worth the effort, IMO.
I don't have a solution for creating a dummy '.so', but I do have something that will simplify your life... I highly suggest that you try using cross-platform make (CMake). In CMake, linking against those libraries is easy:
FIND_PACKAGE(Boost 1.37 COMPONENTS date_time filesystem REQUIRED)
ADD_EXECUTABLE(myexecutable ${myexecutable_SRCS})
TARGET_LINK_LIBRARIES(myexecutable ${Boost_LIBRARIES})
The commands above, if placed in a "CMakeLists.txt" file, is all you need to:
Verify that Boost 1.37 or later is installed, with the "date_time" and "filesystem" libraries installed.
Create an executable named "myexecutable" from the sources listed in the corresponding variable.
Link the executable "myexecutable" against the boost "date_time" and "filesystem" libraries.
See also: Why the KDE project switched to CMake.
Actually, making one .so depend on all boost .so files is quite possible (but might not actually help you). I've just tried this:
$ export BOOST_ROOT=/home/ghost/Work/Boost/boost-svn
$ g++ -shared -Wl,-soname,libboost.so -o libboost.so $BOOST_ROOT/stage/lib/libboost_program_options.so
$ g++ -L . -I $BOOST_ROOT first.cpp -lboost -Wl,-R$BOOST_ROOT/stage/lib
$ LD_LIBRARY_PATH=.:$BOOST_ROOT/stage/lib ./a.out
And it did work. However, note that dancing with -R and LD_LIBRARY_PATH. I don't know an way how you can include the path to Boost .so inside your libboost.so so that they are used both for linking and actually running the application. I can include rpath inside libboost.so just fine, but it's ignored when resolving symbols for the application.