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.
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'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.
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.
Background:
I am trying to provide a library wrapped within an interface, to be used in a third party application (MATLAB).
My problem is that both my library and the third party application rely on Boost libraries.
To make things even worse, not only they rely on two different versions of Boost, but my library is built against a patched version of Boost, and they are statically linked. Third party libraries are instead dynamically linked against Boost.
This is how I link (simplified output of make -n)
g++ -fPIC ${CPPFLAGS} -shared -lc -ldl ... -Wl,-h,mylib.so -o mylib.so \
${MYSTATICLIBS} \
-L${MATLABLIBSPATH} -lmx -lmex \
-L${MYBOOSTVERSIONPATH} -lboost_thread-gcc49-mt-1_52 ...
When I run the library fron within MATLAB then, the wrong boost functions are called from my internal functions (and everything crashes).
My naive intuition was that since i statically linked my Boost, all calls to them from within my library should point to my Boost, while calls from within libmx.so or libmex.so would point to their dynamically loaded dependencies. However this proves my naive intuition was very wrong.
I found different hints here on SO and around the web describing how linking order may break similar situations, however everything describes either all static or all dynamic linking of conflicting symbols.
Suggested solutions are
using -Bsymbolic -Bsymbolic-functions
upgrade my library to the same boost version
changing linking order ( first boost, then -lmx -lmex )
sell all my earthly possessions, buy a bar on the beach somewhere hot and try making a living out of it
other??
Can someone explain if and why these solution can work?
( my other problem is, I am not able to test with MATLAB myself, as I have no access to the machines on which it is installed. this is why I'm also asking "if" the proposed solutions would work)
First of all, welcome to the wonderful world of Linux symbol interposition ;)
I think what happens is your library exports all symbols from Boost library it has been linked with (can be verified with readelf --dyn-syms -W). At runtime, dynamic linker will note that and instead rebind symbols to a different version of Boost (because it happens to be loaded earlier and so overrides symbols used by your library).
What you want to do is to tell gcc that you do not want to export Boost symbols or you do not want them to be interposable at runtime. There are several solutions for this, the best being to compile and link with -fvisibility=hidden (note that Boost will also need to be linked with this flag). This will prevent any functions from being exported from your library unless you explicitly mark them with __attribute__((visibility("hidden"))) (you'll need to annotate library interface functions of course).
Another option is -Bsymbolic - this would not prevent spurious Boost exports from your library but would at least prevent dynamic linker from overriding them with random versions of Boost functions which happen to be loaded by other libraries.
Now to remaining questions.
upgrade my library to the same boost version
You could do that but this may break if 3-rd party upgrades their Boost at some point.
changing linking order ( first boost, then -lmx -lmex )
Does not make much sense... Have you tried?
I'm trying to build a project (namely, Angband's source - http://rephial.org/downloads/3.3/angband-v3.3.2.tar.gz) with Emscripten's emcc in order to port it to Javascript and ultimately build an online version.
I've managed to get the process started with
emconfigure ./configure
make
which begins to successfully start generating LLVM bitcode .o files, but then it hangs up on main-gcu.c with 'main-gcu.c:43:11: fatal error: 'ncurses.h' file not found'
I believe main-gcu.c is the only file that references ncurses, but I just can't figure out how to include the library while compiling. Is there a way to specify including ncurses with 'make', or should I compile the main-gcu.c file individually, with 'emcc main-gcu.c -c -lncurses'? I tried doing that but that led to another error with emcc being unable to find other actually included header files two levels down (it couldn't find headers that were included by a header included by main-gcu.c - anyway to fix that?).
I'm also not certain if I have/need to install the ncurses library on Mac OSX. All I can really find are references to libncurses5-dev for Linux.
Thanks!
I think you misunderstand the compilation via Emscripten. I will try to point out a few problems you are facing.
The general rule is that all tools of Emscripten ONLY can turn LLVM formats (e.g. BITCODE) into JavaScript. emconfigure, emmake, ... modify the build environment so that your sourcecode is compiled to one of the LLVM formats (there are exceptions to the rule but nevermind). So anything you want to link against your final result has to be in a LLVM format, as well (which by default ncurses is not).
Since the output is JavaScript, there is no chance to execute any program code in different threads. While a lot of C/C++ code does use a thread for the UI and others for processing, such a model does NOT work for Emscripten. So in order to get the software compiling/running you will have to rewrite the parts that use threading. See emscripten_set_main_loop for pointers.
Even if you have the libraries compiled you then have to statically link them to Emscripten. At this point it is less of a technical problem but more of a license issue since if your library is licensed under e.g. LGPL due to static linking the GPL terms are effective.
I hope all clarity finally vanished ;)