I'm reading a Mastering Embedded Linux Programming book. Came across the following paragraph:
libjpeg.a: This is the library archive used for static linking
libjpeg.so -> libjpeg.so.8.0.2: This is a symbolic link, used for dynamic linking
libjpeg.so.8 -> libjpeg.so.8.0.2: This is a symbolic link, used when loading the library at runtime
libjpeg.so.8.0.2: This is the actual shared library, used at both compile time and runtime
What is the difference between dynamic linking and loading the library at runtime?
Came across the following paragraph
The book author is likely confused.
There is no fundamental reason to have anything other than libjpeg.so, which is a shared library that is usable both for linking and runtime loading.
The reason for all the .so.8.0.2 naming and symlinking is external library versioning, described e.g. here.
External versioning is not necessary at all on GNU systems that support symbol versioning.
Related
Similar to this question: Is it safe to strip a shared library after linking?
I am curious if it is possible to strip a shared library such that one can no longer compile against it, but where binaries that have been compiled against it can still be linked at run-time?
I have an OpenWrt-based system. The OpenWrt devs ship several (open source) libraries that appear to have had symbols necessary for compile-time linking against removed. I don't have a deep knowledge of ELF shared libraries, but had not thought this was even possible. However gcc reports undefined references to all the libraries functions. Rather than recompile every library so butchered, is there any way to rebuild those symbols in the shipped libs? The symbols are still in the shared library in some way, as they can be seen with "strings".
I am trying to compile a binary which links to libcrypto.so.1.1 and my binary also links against another library (Let us call this library libblah.so)
This libblah.so links against libcrypto.so.1.0. During the compilation, I get a warning saying that there is a conflicting linking of library for libcrypto.
Though, I am not directly linking libcrypto 1.0 and 1.1 in my 1st level of linking, I am seeing this error. I am interested in understanding what issues might this cause during the runtime.
I have some XML parsing utility functions written inside C headers and source files based on expat library.
For this I have compiled my source files to a static library with expat statically linked to it.
I am able to use and the functions from the resulting xml utilities library with my applications only if I statically link both the utility library and expat with my application. I was of the view that I should be able to get my application built with only statically linking my utility library without requiring to statically link expat again with the application executable. Only linking my application with the utility library gives undefined symbol error for expat.
Can someone please guide me what am I missing ? I am using gcc compiler.
Thanks....
"I have compiled my source files to a static library with expat statically linked to it."
I'm fraid you haven't. A static library is not produced by the linker; no linkage is involved, so nothing can be linked to it.
A static library is nothing but a bag of object files in ar archive format.
When you are linking something that is produced by the linker - namely a program or a shared library -
you may offer such a bag to the linker. It will look in the bag and take out just the object files it needs to
carry on the linkage and link them into the target. The bag spares you the difficulty of
needing to know exactly which of the object files in it the linker will need, but the bag itself contributes nothing at all to the linkage.
Later
How can I get expat static library included in my utilities library, so that I only need to link my executable with a single static library. I don't want to extract the two archives and merge the object files together.
There is no other way of combining two ar archives.
Your resistance to linking libexpat is puzzling, without further context. It is available
through the package manager on any distro. You've made a library that depends on libexpat. Clients that link your
library will need also need to link libexpat. This is an utterly routine sort of dependency
that you should simply document and - if you are packaging your library - include
in the package dependencies. Almost invariably when we write new libraries we are augmenting the
libraries already available to our target users. If every library statically
incorporated all of its own dependencies then they would all be the size of an
operating system and of no practical use.
I built boost libraries with msvc. And I want to link to my program using mingw. As the title asked, how can I achieve that?
When I try to link the boost libraries. The compiler suggests that it can't find symbols of the boost libraries.
Quoting the mingw wiki here:
Object files and static libraries created with different compilers [...] often cannot be linked together. This issue is not specific to MinGW: many other compilers are mutually incompatible. Build everything from source with the same version of the same compiler if you can.
It is stated in the same page that if you want, you may use dynamic (shared) libraries from different compilers if you provide a C interface for the library you want to use. Then your program would use this interface (C wrapper library) to communicate with Boost, by including the header for this interface library with extern "C". Example of doing this can be found here.
In your case, however, this would not be preferable as you would have to expose everything you want to use from Boost one by one in the C interface that you would write yourself. You might find it much easier just compiling your libraries with the same compiler you are compiling your program with.
When I need to build some third party library to be used in several of my projects under different version of MSVC, I usually build it for every MSVC version and for both Debug and Release configurations. That's what boost does, and that's what we have been done for our whole life in my team.
However, I still don't get, why couldn't I just build this library with like... whatever. All I need is function prototype and object code, right? Since I'm linking CRT statically, I have no external dependencies. But when I'm trying to link library built in Release under MSVC8 with my project in Debug under MSVC10 I have this annoying "already defined" linker errors which we all hate so much.
But why? Can I just "encapsulate" all this functions inside lib and do not export them so that my project will take only what it needs from the lib? Why can I have precompiled version of libpng and zlib which I can link in every project? Yes, they are not build using MSVC, I guess, but the still uses the same functions of CRT. So can anyone please explain in depth or share a link to some enlightened explanation of this issue?
Since I'm linking CRT statically, I have no external dependencies
Well, that's not true, you do have a dependency. On the static version of the CRT. Debug or Release, depending on your build settings. And it is an external dependency, the linker glues the CRT later, when the library gets linked. The code that uses the library also has a dependency on the CRT. And if the compile settings don't match then the linker barfs.
You isolate that dependency by building a DLL instead of a static link library. You must further ensure that the exported functions don't cause a CRT dependency. You can't return a C++ object from the standard C++ library and can't return a pointer to an object that needs to be released by the client code. Even passing structures is tricky since their packing is an implementation detail, but you usually get away with it. A good practical example is COM automation, it forces you into using a subset of types that are universal. Windows is rife with them and all these servers work with any version of the compiler or CRT. Even any language. This however comes at a cost, writing such a library isn't as simple or convenient as just throwing a bunch of code in a static lib.