I need to create a .so by linking it to other opensource libraries (some available as .so and some as .a)
Is it possible to create a .so by linking it with combination of .so and .a
E.g. Say I'm trying to create libfinal.so by linking it with liba.so, libb.a
gcc -shared -Wl,-soname,libfinal.so -Wl,--no-undefined -la -lb
The above command is trying to find libb.so which is not available. Any solution?
UPDATE: The problem seems to be libb.a is compiled with out -fPIC option.
Error --> relocation R_MIPS_26 against `libipt_DNAT_init' can not be used when making a shared object; recompile with -fPIC
Below is command syntax to link object files , archives and libraries.
gcc -o <output file> -l<library> objectfiles|archives
E.g. Linking libc.so.6, Ex.o and binary1.a to generate MyEx.so
gcc -o MyEx.so -lc Ex.o binary1.a
Note : An archive (.a) is nothing but a single file holding a collection of other files
Related
Say I have a.so and b.so.
Can I produce c.so as a single shared library with all the functions exported by a and b, of course resolving all intra-dependencies (i.e. all functions of b.so called by a.so and the other way around)?
I tried
gcc -shared -Wl,soname,c.so -o c.so a.so b.so
but it doesn't work.
Same goes if I archive a.o and b.o in a.a and b.a (which shouldn't modify a.o and b.o), and do
gcc -shared -Wl,soname,c.so -o c.so a.a b.a
Thanks
Merging multiple shared libraries into one is indeed practically impossible on all UNIXen, except AIX: the linker considers the .so a "final" product.
But merging archives into .so should not be a problem:
gcc -shared -o c.so -Wl,--whole-archive a.a b.a -Wl,--no-whole-archive
In practice it is not possible.
From linker point of view, a SO library is a final product that does not contain relocation information required for linking.
If you have access to either source or object files for both libraries, it is straightforward to compile/link a combined SO from them.
I am trying to understand static libraries and shared objects in C. I am trying to understand whether one type of library can depend on other type.
Consider a scenario:
libA.so has a function foo_A_dyn():
libA.so ---> foo_A_dyn()
foo_A_dyn() uses a function foo_B_static() which is defined in libB.a which is a static library.
libB.a ---> foo_B_static()
I have built my libraries in the following way:
gcc -c foo_B.c -o foo_B.o
ar -cvq libB.a foo_B.o
gcc -fPIC -c foo_A.c -o foo_A.o
gcc -shared libA.so foo_A.o -I.
gcc main.c -lA -lB -L. -I. -o EXE
Note: main.c makes call to foo_A_dyn() and does NOT call foo_B_static() directly.
And now when I am trying to build my executable EXE, I am getting the error "undefined reference to foo_B_static".
I think the error seems genuine but I am not able to decode the rationale behind this and put it to words.
Can someone please help?
From gcc link options:
-llibrary
-l library
...
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, ‘foo.o -lz bar.o’ searches library ‘z’ after file foo.o but before bar.o. If bar.o refers to functions in ‘z’, those functions may not be loaded.
Try:
gcc main.c -lB -lA -L. -I. -o EXE
Here's what the linker is doing. When we link our executable ('EXE' above) it has some symbols (functions and other things) that are unresolved. It will look down the list of libraries that follow in sequential order, trying to resolve unresolved symbols. Along the way, it finds that some of the symbols are provided by libB.so, so it notes that they are now resolved by this library. While going through libB.so it finds some symbols which are unresolved and it tries to resolve them by looking up the library that follows.
When we are ordering the libraries like:
gcc main.c -lA -lB -L. -I. -o EXE
Linker is not able to lookup for the definition of symbols used in libB into libA. Reason could be that backward reference is not available.
I have also figured out that:
shared object can depend on a static archive,
a static archive can depend on a shared object, and
one static archive can depend on another static archive
Please let me know if I have erred somewhere.
When compiling our project, we create several archives (static libraries), say liby.a and libz.a that each contains an object file defining a function y_function() and z_function(). Then, these archives are joined in a shared object, say libyz.so, that is one of our main distributable target.
g++ -fPIC -c -o y.o y.cpp
ar cr liby.a y.o
g++ -fPIC -c -o z.o z.cpp
ar cr libz.a z.o
g++ -shared -L. -ly -lz -o libyz.so
When using this shared object into the example program, say x.c, the link fails because of an undefined references to functions y_function() and z_function().
g++ x.o -L. -lyz -o xyz
It works however when I link the final executable directly with the archives (static libraries).
g++ x.o -L. -ly -lz -o xyz
My guess is that the object files contained in the archives are not linked into the shared library because they are not used in it. How to force inclusion?
Edit:
Inclusion can be forced using --whole-archive ld option. But if results in compilation errors:
g++ -shared '-Wl,--whole-archive' -L. -ly -lz -o libyz.so
/usr/lib/libc_nonshared.a(elf-init.oS): In function `__libc_csu_init':
(.text+0x1d): undefined reference to `__init_array_end'
/usr/bin/ld: /usr/lib/libc_nonshared.a(elf-init.oS): relocation R_X86_64_PC32 against undefined hidden symbol `__init_array_end' can not be used when making a shared object
/usr/bin/ld: final link failed: Bad value
Any idea where this comes from?
You could try (ld(2)):
--whole-archive
For each archive mentioned on the command line after the --whole-archive option, include every object file in the
archive in the link, rather than searching the archive for the required object files. This is normally used to turn
an archive file into a shared library, forcing every object to be included in the resulting shared library. This
option may be used more than once.
(gcc -Wl,--whole-archive)
Plus, you should put -Wl,--no-whole-archive at the end of the library list. (as said by Dmitry Yudakov in the comment below)
I've got two shared libraries libA and libB, and I want to create a new library libC, that links to both libraries, so I can link my application with -lC instead of -lA and -lB.
I can't use -lA and -lB one, because I'd have to fix many packages otherwise.
libB is a precompiled binary.
I tried to run this:
gcc -fPIC -shared -o libA.so A.c
gcc -shared -Wl,--no-as-needed -L. -lA -lB -o libC.so
But when I link my application, that needs libB with -lC I
App.o: undefined reference to symbol 'SymbolInB'
note: 'SymbolInB' is defined in DSO libB.so so try adding it to the linker command line
libB.so: could not read symbols: Invalid operation
If I run readelf -a libB.so I see the SymbolInB in .dynsym, it is missing in libC.so. So I assume I miss a linking option to resolve the symbols correctly?
It doesn't work that way. The functions in libC can use the functions in libA and libB fine, because libC was linked with the other libraries. However, those symbols from libA and libB are not exported from libC, so if you have an application which directly uses functions from libB then you need to link with libB.
I have a third-party library which consists mainly of a large number of static (.a) library files. I can compile this into a single .a library file, but I really need it to be a single .so shared library file.
Is there any way to convert a static .a file into a shared .so file? Or more generally is there a good way to combine a huge number of static .a files with a few .o object files into a single .so file?
Does this (with appropriate -L's of course)
gcc -shared -o megalib.so foo.o bar.o -la_static_lib -lb_static_lib
Not do it?
You can't do this if objects within static library was compiled without -fPIC or like.
g++ -shared -o megalib.so foo.o bar.o -Wl,--whole-archive -la_static_lib -lb_static_lib -Wl,--no-whole-archive -lc_static_lib -lother_shared_object
I'm not sure about gcc, but for g++ I had to add the --whole-archive linker option to include the objects from the static libraries in the shared object.
The --no-whole-archive option is necessary if you want to link to libc_static_lib.a and libother_shared_object.so, but not include them as a whole in megalib.so.
ar -x can be also useful if you want to focus on specific objects from your .as and you don't want to add anything on your own.
Examples:
ar -x lib***.a
gcc -shared *.o -o lib***.so
ar -x lib***.a
gcc -shared *.o -o lib***.so