Linking other libraries into dynamically loaded libraries - c++

I am writing a library that is loaded dynamically by another progam. This library uses some Boost libraries (for example, thread). Is it possible to make it work somehow without recompiling the program in question?
If I use the link flags -lboost_thread, it doesn't work, because the program that uses this library would need to link the same Boost library, too. Using /usr/lib/libboost_thread.a also doesn't work, because the .a file isn't compiled with -fPIC.
I am using GCC under Linux.

Trying again, I found that the problem was not what I described. The library didn't load for some other reason. I found that linking the library with -lboost_thread works, with the following conditions:
gcc gives compiler warnings (possibly because the libraries are from the -L path which is not in $LD_LIBRARY_PATH).
When loading the library, it loads Boost automatically provided it can find them.

Related

How to link against a shared library which linked with different version of boost in linux

I'm building a executable in a big project, one of its dependency, a .so file, is linked against boost 1.6.2, and the executable itself must be static linked to a different version of boost, I don't know the version of that, maybe 1.6.0, when I link to the .so directly, it's able to compile and link, but when I run that binary, the behaviour of that binary becomes strange when calling to the functions of classes of the external .so file, such as it can run into infinite lock, and core dump inside boost. But if I don't link a different version of boost, it works. I guess the version of boost caused this problem. Is that true? How can I fix this?
The safest thing to do is to rename the namespace of your statically linked version of boost to ensure there are no symbol clashes. Unfortunately I don't think boost has any macros for changing its namespace so you'll have to do a manual find and replace in the source code.

Boost Logger Static Linking: Not Working

I have a Qt application that uses the boost logger library. I want to make it a standalone. However, after I managed the libraries for static linking, the application is still dependent on boost libraries.
The libraries that I included are:
..../boost_1_61_0_b1/stage/lib/libboost_regex.a
..../boost_1_61_0_b1/stage/lib/libboost_log_setup.a
..../boost_1_61_0_b1/stage/lib/libboost_thread.a
..../boost_1_61_0_b1/stage/lib/libboost_log.a
..../boost_1_61_0_b1/stage/lib/libboost_system.a
..../boost_1_61_0_b1/stage/lib/libboost_filesystem.a
The application compiles( after countless attempts). However, when I use ldd tool, it shows boost libraries on the dependency list.
Note: I have to define BOOST_ALL_DYN_LINK. Otherwise, it doesn't link.
Is there any way not to use this macro and overcome the dependency problem ? If not, what solutions do you suggest to circumvent this problem?
By default on modern UNIX-like systems gcc links with shared libraries by default. In order to force static linking you can either add -static to your linking command line (see the docs) or make sure gcc doesn't find the shared libraries but only finds the static libraries (e.g. move the shared libraries to a separate directory while you're linking your project). Note that -static will make all libraries linked statically, including libstdc++.
Alternatively, you can specify the static libraries directly, without the -l switch. You will have to use the full path to the libraries though, so instead of
gcc ... -lboost_log ...
you would write
gcc ... ..../boost_1_61_0_b1/stage/lib/libboost_log.a ...
In any case, you should not define BOOST_ALL_DYN_LINK because this macro means exactly the opposite - that you intend to link with Boost shared libraries.

Linking libraries in c++

I have a C++ file a.cpp with the library dependency in the path /home/name/lib and the name of the library abc.so.
I do the compilation as follows:
g++ a.cpp -L/home/name/lib -labc
This compiles the program with no errors.
However while running the program, I get the ERROR:
./a.out: error while loading shared libraries: libabc.so.0: cannot open shared object file: No such file or directory
However if before running the program, I add the library path as
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/name/lib;
and compile and run now, it works fine.
Why am I not able to link the library by giving it from the g++ command?
Because shared object libraries are linked at runtime - you either need to add the location to the library search path (as you've done), place it somewhere within an already existing path (like /usr/lib), or add a symbolic link to an existing library path that links to the location where it exists.
If you want to compile the library in so there is no runtime dependency, you'll need a static library (which would be abc.a) - note that this has numerous downsides, however (if the library is updated, you'll need to recompile your executable to incorporate that update).
Why am I not able to link the library by giving it from the g++ command?
You are able to link, and you did link the library succesfully. Otherwise you would not be able to build executable (in your case a.out). The problem you mixed 2 different things: linking with shared libraries and loading them at runtime. Loading shared libraries is a pretty complex concept and described pretty well here Program-Library-HOWTO read from 3.2.
You are linking dynamically, is the default behavior with GCC. LD_LIBRARY_PATH is used to specify directories where to look for libraries (is a way of enforce using an specific library), read: Program-Library-HOWTO for more info. There is also an ld option -rpath to specify libraries search path for the binary being compiled (this info is written in the binary and only used for that binary, the LD_LIBRARY_PATH affect other apps using the same library, probably expecting a new or old version).
Linking statically is possible (but a little tricky) and no dependency would be required (but sometimes is not recommended, because prevent the update of the dependent libraries, for example for security reason, in static linking your always are using the versions of the libraries you have when compiled the binary).

In linux how can I tell if I'm linking to a static or dynamic library?

I have a static and a dynamic library with the same name: libclsocket.a and libclsocket.so When I specify what library I want to link to i simply enter -lclsocket as the library. My program complies and runs perfectly fine, but what library am I using? the static library or the dynamic library? I want to give my friend my program, and I'm not sure If i need to include the libraries in the release. C++, codelite, pcLinuxOS 2010
You can try running ldd on the executable and seeing if the accompanying .so is being detected as required in the list of dependencies.
ldd man page is here.
If you use the -static flag, all components will be made static. And -l may include shared libraries. So specifying the static library filename (e.g. with /usr/lib/libfoo.a for example, no -l prepended), should get you the desired effect.

linking boost.asio

I have a problem linking boost.asio. It uses boost.system and the linker errors start with:
/boost_1_39_0/boost/system/error_code.hpp:205: undefined reference to `boost::system::get_system_category()'
which means I need to link boost.system. I already built boost and I have now several lib files.
boost_system-mgw32-d-1_39.dll and lib
libboost_system-mgw34-d-1_39.lib
libboost_system-mgw34-mt-d-1_39.lib
libboost_system-mgw34-sd-1_39.lib
and some more. How do I link them? Which one do I use? Do I copy all of them together?
My system is win32+mingw+eclipse cdt+qt 4.5.2+qt integration for eclipse. I already learned that I need to at a LIBS= section to my .pro file.
Can you give my some hints?
Thank you.
The libraries are named based on whether or not multi-threading support is enabled, static and dynamic linkage, debug and release mode, and more. Here's some details:
http://www.boost.org/doc/libs/1_39_0/more/getting_started/unix-variants.html#library-naming
I'm not sure about eclipse as I don't use it, but with gcc (and mingw) you need to specify both a directory to find the libraries in (-L) and the file to link with. For example, if you wanted to link with the single-threaded debug version:
-L/path/to/libraries -lboost_system-mgw34-sd-1_39