Avoiding symbols collisions in a shared library using the C++ standard library - c++

I'm developing a .so shared library in C++ that uses standard library facilities (e.g. std::map or std::vector).
I had problems in the past though since any application pulling my shared library caused standard libraries symbols collisions and debugging quickly became a nightmare.
I'm a novice on linux, how can I avoid this problem and/or mitigate it if I have no control on the application which loads my .so?

In short, link your shared library statically against the C++ standard library. Find more details in libstdc++ static linking in dynamic library.

Related

C++: Linking an external library to a dll library

I'm currently developing a shared library on Windows (dll) with c++.
The library depends on another external library.
What is the best way to link them together?
Link the external library as a static library into my shared lib?
Link it as a shared library and provide the dll to the application who is using my shared lib?
For the second case what happens if i create an application which uses my own created shared library and also the external library as a shared library?
If for example my shared library is build with the external library version 1.1 and the application uses the newer Version for example 1.3 ? Now the dlls should be different but how could i provide them to the main application?
Are there some best practices or recommendations on how to handle such a situation?
This really depends on what you want to do and how you are deploying your library.
shared/dynamic libraries (dll's on windows) have several advantages over static libraries
They can be distributed externally from the application, allowing your application binary to be smaller
They can be updated externally to the application
They are slightly more efficient as code is only executed if its needed rather than being bundled with the executable
Of course they have several weaknesses too
They can be distributed externally from your application and updated externally - allowing dll injection attacks
Trying to release dynamic libraries with the executable is one of the most painful and horrible things to do (especially on windows where there is no RPATH)
You may have to use a dll, dependent on your external libraries licensing, Qt for example requires shared library linking in many cases (not all).
Standard convention is usually to offer shared and static versions of your library with the shared version being completely linked to other shared libraries and the static version being an ar static library (includes all dependencies). The shared library variant then offers instructions on linking (i.e a .pc (pkgconfig) file) which specifies the versions of the other libraries to link to (i.e v1.1 of x.dll) in order to successfully compile/link.

Do shared libraries (.so) files need to present (or specified) at link time?

Do shared libraries (.so) files need to present (or specified) at link time?
I've read here (Difference between shared objects (.so), static libraries (.a), and DLL's (.so)?) that .so files must be present at compile time, but in my experience this is not true?
Doesn't shared libraries just get linked at runtime using dlopen and dlsym, so that the library may not be present on the system, when the application is linked?
Most shared libraries need to be present both at build time and at run time. Notice that shared libraries are not DLLs (which is a Windows thing).
I assume you code for Linux. Details are different on other OSes (and they matter).
For example, if you are compiling a Qt application, you need the Qt shared libraries (such as /usr/lib/x86_64-linux-gnu/libQt5Gui.so and many others) both when building your application and when running it. Read about the dynamic linker ld-linux.so(8) & about ELF.
But you are asking about dynamic loading (using dlopen(3) with dlsym(3) ...) of plugins.
Then read Levine's Linkers & Loaders, Program Library HowTo, C++ dlopen mini HowTo, and Drepper's How To Write Shared Libraries
See also this answer.
Some libraries and frameworks try to abstract the loading of plugins in an OS-neutral manner. Read e.g. about Qt plugins support, or about POCO shared libraries (poorly named, it is about plugins).
You can have it both way, it all works.
While with library present at compile time,instead of get library by dlopen/LoadLibrary explictly, you can use all the functions directly

Linking a shared object into other shared object C++ project

I am working in a very big C++ project to create a big shared object where we are using an external SDK which have several header files and several shared libraries which belong to each other. This means that the declaration of SDK classes are in the header files but their definitions are in the shared objects.
I understand that because of the declarations in header files I can compile this code.
But what I do not understand exactly is when do I have to specify the used shared objects for the linker explicitly?
Namely if I specify it (e.g. in cmake with target_link_libraries command) then the linker can check that a symbol will be in the shared library or not. But what happens if I do not specify it (i.e. there is not any -l[shared_object_name] flags in linkage)? My experience is (which surprised me) that is work properly (i.e. the whole building process finished). How can it possible?
In POSIX shared libraries, you can have undefined symbols in a shared library, and all will link just fine. As long as the executable is fully linked, there will be no linker errors.
That's done this way because dynamic libraries mimic the behaviour of static libraries, and static libraries can have undefined symbols (static libraries are not linked, to begin with).
If you come from a Windows background, then it will surprise you, because Windows DLLs cannot have undefined symbols.
If you are worried about this, you can check the linker options --no-undefined and --no-allow-shlib-undefined.
My experience is (which surprised me) that is work properly (i.e. the whole building process finished).
That seems unlikely.
In fact…
How can it possible?
It's not.
The only explanation is that you weren't using symbols defined inside those library files. They were either in header-only parts of the third-party code, or they weren't part of the third-party code at all.
Or you were building a shared library of your own. The ultimate executable would still need the third-party libraries linked in, though.

Mixing boost library versions

We have a application with various dynamic libs, which all use Boost 1.48 (static). Due to a third-party dependency on Boost Filesystem v2, we can't switch to a more recent Boost version for the application.
For a new functionality we develop a new dynamic lib for the application, which should also be used in some other projects.
Can we use a recent (static?) Boost lib for this new lib, without interfering the Boost lib already used in the application?
Any traps I should avoid?
Boost libraries generally do not support mixing different versions of libraries. Whether doing so would cause problems or not depends on many factors, among which are the libraries in question, your application design and the target platform. One source of problems can be symbol relocation which is part of the linking process on Linux and other UNIX-like systems. Even if you link with static libs of Boost, the linked symbols can still be exported from your binaries and may clash when you load your application. This can cause all sorts of undefined behavior and is often very difficult to debug.
In general, I would highly discourage from mixing different releases of Boost in the same application (i.e. a runtime process).
If you are using a static boost library to build your dynamic library, the static boost library will not create side effect with another boost static or dynamic library.

Meaning of library dl in gcc

I'm checking a makefile, and see that the libraries used are:
LIBS = -lcppunit -ldl
lcppunit is the unit testing library. What is ldl then?
This is the interface to the dynamic loader, which provides a client program with ability to do things such as explicitly load other libraries, lookup symbols within, etc.
Most programs do not need to do such things explicitly, since the linker does what is needed to enable ordinary usage of shared libraries while loading the program and libraries themselves. However programs that are clever or try to explore and manipulate the dynamic linking system and its data need explicit access. Some of the capabilities are distantly similar to reflection in Java, though with major limitations (such as applying only to dynamic symbols)
libdl is the dynamic linking library.
libdl is the dynamic link library used in plugin architectures with well defined interfaces. At least that's how I've seen it used.