Very often, you get a static library from some other source, which you need to use for your purposes. What if you finally are working towards creation of a dynamic library, which uses symbols (or functions) from the static library? How do you “link” the symbols in the static library to your dynamic library so that there will be no “undefined” symbols at runtime? This article helps to bust this problem. Ok, first the correction. There is nothing like “linking a static library to dynamic library”. “Linking” is a process of completing the “symbol table” present in every executable or a shared library (see “Linkers and symbol tables”). When you want to “link a static library with dynamic library”, you really want to include the symbols defined in the static library as a part of the dynamic library, so that the run-time linker gets the symbols when it is loading the dynamic library. Cpusched uses this concept to include various commonly used static libraries (like libfifo) to scheduling algorithms which are created as dynamic libraries that will be loaded by Cpusched when selected. Now, for a mini-tutorial that drills this whole concept: We will need three files for our tutorial. Quickly create these files: file1.c #include <stdio.h> void func1(); { printf('func1n'); } int main(void) file2.c #include <stdio.h> void func2() file3.c #include <stdio.h> void func3() gcc -c -fPIC file2.cThis creates both file1.o and file2.o with position independent code. Note that this depends on the platform in which it is used: for example, when gcc is Linux to create an ELF object, on default (i.e., without -fPIC), the code generated is “static” in nature - hence -fPIC forces it to generate PIC code. However, certain platforms (like Cygwin on Windows) always generate PIC code for objects, regardless of whether -fPIC is used or not.Next, archive these objects to get a static library:ar -rv libfiles.a file1.o file2.o ranlib libfiles.aThe ranlib is optional: it just generates an index of symbols in the archive and puts it in the archive - this helps speed up the process of linking. For large libraries, this becomes essential rather an optional.“libfiles.a” now contains the files file1.o and file2.o - both generated as PIC.Now, generate the final dynamic library, which includes another file. First, create the object file of the new file as before:gcc -c -fPIC file3.cFinally, create the dynamic library, which contains the new file (file3.o), along with the other files in libfiles.a.gcc -o libfiledyn.so -Wl,--whole-archive libfiles.a -Wl,--no-whole-archive -shared file3.oThe -Wl options to gcc are directly passed to the linker (gcc invokes the linker “ld” as the last step before creation of an executable or a shared library). The linker gets the option “–whole-archive” - this option instructs the linker to “extract” the option argument (in this case, libfiles.a) so that all the object files in the archive (file1.o and file2.o) are individually added to the link command line (equivalent to actually having them on the command line separately); the –no-whole-archive reverses this behaviour.Both –whole-archive and –no-whole-archive are needed because the linker extracts all the archives that are present in-between these options.That’s it! Now, libfiledyn.so contains also the contents of libfiles.a - and can be then used independently. |
|