cmake build a shared library that contains all its dependencies - c++

I have built a shared library that depends on a bunch of other libraries. But when loading that shared library, it needs the dependent libraries to be present in order to run properly. I want this shared library to be portable and hence want it to contain all the dependencies in itself. Is there a way in cmake to do this or what is the best solution here?

Actually this is not related with CMake, but with concepts of linking. You should link with static version of all your dependent libraries.

Related

What is the best approach to simplify linking to my library?

I want to build a library which is easy to use and link to. Therefore, I do not want the user of my library to bother with building and linking against the libraries my library uses. What is the best approach of managing and building/linking the dependencies for your own library in order to assure the most simple usage of it?
E.g.: My library uses CURL and OpenSSL. Building and linking on Windows with those dependencies is a pain. I want to avoid this pain to the users of my library.
I use CMake for building.
Related to: Combine libraries and Linking static libraries to other static libraries

Relations between executables, static libraries and shared libraries

I am writing a build system for a project and I am not sure about the links between executables, static libraries and shared libraries.
For me there are three affirmations:
An executable can use both static and shared libraries.
A static library can use both static and shared libraries.
A shared library can only use static libraries.
I have still doubts about the third affirmation...
Can you enlighten me on this?
To use a static library's basically like linking a .o or .obj file: all the implementation's linked into the using application or library at that specific point in time. Changes made to the static library after that time won't be picked up automatically by the code that linked it... the latter would need to be relinked for the changes to be incorporated.
Shared libraries defer the linking until runtime, which means every time the code using a shared library invokes some functionality within it, the version of the shared library which is found at runtime is utilised. As long as the changes don't affect the public API, you can replace a shared library and applications that find it at runtime will pick up the updates/changes without themselves having to be modified/relinked.
So, yes an executable can use both, a static library can use both, and your third "affirmation" is wrong: a shared library can also use both. It just means the shared library itself may use a snapshot of functionality from a static library, or it may find other functionality from another shared library at runtime.

undefined references when linking own static library that itself depends on static libraries

I wrote a static library (compiled with TDM-gcc 4.8.1 in Windows 7 for x64) that has dependencies on other static libraries. Boost libraries (locale and system) to be specific.
Since I'm building a static library I assumed that the libraries I'm dependend on would automatically included in my final .a, especially since I'm using them in my code.
But when I'm trying to build an executable that statically links to my aforementioned library there are still undefined references to some boost parts, that are definitely used in my library.
Is there a way to fix that?
Any help is gladly appreciated. Thank you
Edit:
I haven't been careful enough, because I now know what causes the problem. I'm using codeblocks and all the necessary arguments for building the archive are declared in the project prooperties. But codeblocks doesn't even call the linker when building my library. Instead it calls ar.exe and passes all object files of my project. That way, no external library are ever included. So, I have too look for away to tell codeblocks to build the library in the right way..
Your executable needs to link against all the relevant libraries, including the ones it directly depends on, plus the ones it indirectly depends on. When you link a static library you typically do not embed other static libraries within it.

Problems linking .o library files together into a shared object

I am working on a collection of reusable libraries that need to be made available both as static libraries (.a & .lib) and as dynamic libraries (.so & .dll).
I want dependency management for the dynamic libraries to be as simple as possible (you only take one dynamic library for each bit of functionality that you need), so all of the functional dependencies that each dynamic library has are actually statically linked into it. Thus, the dynamic libraries offer their functionality to downstream clients dynamically, but their upstream dependencies are satisfied statically.
The upshot of all this is that all of my static libraries need to be compiled with -fPIC so that their code is suitable for linkage into a shared library. The same goes for any third-party library that we use. It has to be a static library, compiled with -fPIC.
(I could, I suppose, build both PIC and non-PIC variants of my libraries - but I really do not want to compile the libraries a third time for each target platform -- twice is quite (more than) enough!).
So, here is my problem:
I have been trying to compile boost_system as a static library with -fPIC, but I am not sure if I am succeeding:
/b2 --build-type=complete variant=release link=static threading=multi runtime-link=static --layout=versioned --cxxflags=-fPIC
This build produces .a files as output, as expected. However, when I try to link the boost static library into one of my shared libraries, I start getting an error message that indicates that boost_system is not Position Independent Code:
.../dependencies/external/boost/1_54_0/stage/lib/linux_x86_64/libboost_system-gcc46-s-1_54.a(error_code.o):
relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
However, I have (attempted) to build boost with -fPIC. Is there any test that I can use to determine if libboost_system is actually PIC code? I.e. if the problem is with building boost - or with linking it to my application.
I believe your problem can be solved by removing the command line option "runtime-link=static" which enables static linking of the C++ runtime libraries. Since you are building a dynamic shared library object, you want to avoid this behavior, especially if clients are to link to your library from different Linux OS configurations. However, the option "link=static" is ok and should remain.

Linker dependencies when mixing static and shared libraries

I have a following question about linking on Linux:
Suppose I have a class Foo that uses Qt. To build this class I'd have to use qmake to generate Makefile.
Later on I want to use this class Foo for a Perl module, which is a shared library. However, to build it I have to use Perl's MakeMaker to generate Makefile of it's own.
The way I'm doing it right now is that I build class Foo as a static library, and when building Perl module's shared library I'm linking it against Foo's static library.
The problem is that when building Perl module's shared library I have to link it against all those Qt libraries that Foo's static library is linked against.
So the question is:
Does this approach even make sense?!
Is it possible to build Foo's static library in a way that I wouldn't have to specify all it's dependencies when building the Perl module's shared library? (Because it is somewhat hard to add all those dependencies to module's Makefile)
Would it be any different if Foo's library was shared, not static?
1) You can't link a static library against a shared library.
2) You would not need to explicitly link against Foo's dependencies if Foo itself was a DSO
3) You can easily modify the Makefile.PL LIBS section to add extra linker dependencies.
4) Qt is a downright pain to link statically anyway. You're better off just doing the whole dynamic shebang unless you have specific version dependencies and OS/platform limitations. Hint: Even if you do have a 'static' build of Qt, this 'static' build won't include things which it might decides need to be present as loadable modules. Been there.
5) I believe there's a CPAN module (somewhat recent) which provides Qt4 bindings. I've never used it and don't know its status, but it may be worth checking out.
But your best bet is to make Foo a dynamic library.. everyone's happy then.
1) It depends on what your objective is.
2) If it's about minimizing the hassle building it, you could include Qt's static libraries as static to your Foo lib. All that matters is that the symbols you reference in Foo can be found at runtime. That way you won't need to include Qt libs in your PerlMake.
3) If it's about minimizing executable size you'd have to go for shared libraries. Then you should build everything as a shared-lib.
Building statically has the advantage to be independent of installed shared libraries on the target platform, while having the disadvantage of executable-size bloat and non re-usability of libraries (more memory needed to load two same executables).
Linking against shared has the advantage of smaller code size but at the same time the proper shared libs have to be installed on the target platform.