Friday, March 6, 2015

How to Create a Static Library in Linux

Basically libraries are of two types
  • Static
  • Dynamic
     Click here to understand compilation stages in Linux
$ gcc first.c -o first
This gives an executable which is of dynamic type. This can be known by using the tool file.

$ file first
First: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
$ gcc first.c -o first
$ ls -l
-rwxr-xr-x 1 gvamshi gvamshi 7139 2011-01-23 14:26 first
-rw-r--r-- 1 gvamshi gvamshi 63 2011-01-23 14:26 first.c
-l is the option used with ls for long listing.

We run the executable we obtained above by compilation as follows.
$ ./first
This is Linux 2.6.32

To generate an executable of static type, we use a flag static as shown below.
$ gcc -static first.c -o firststatic
$ ls -l
-rwxr-xr-x 1 gvamshi gvamshi 7139 2011-01-23 14:26 first
-rw-r--r-- 1 gvamshi gvamshi 63 2011-01-23 14:26 first.c
-rwxr-xr-x 1 gvamshi gvamshi 578015 2011-01-23 14:35 firststatic
$ ./firststatic
This is Linux 2.6.32

Here the thing to observe is the size of both executables that is first and firststatic, here the size of firststatic is approximately ten times that of first, this is because the libraries are also loaded into it. As the libraries are loaded with our code then this firststatic can be executed on any machine which is of same architecture and of same linux kernel version even if the machine doesnt have libc libraries, where as the executable first need the libc on the machine to run as the libraries are dynamically linked and are loaded at run time by the tool link-loader. As the libraries are linked dynamically the size of executable first is small. Static executable (firststatic) in now independent of libc library.
Note: In gnu linker by default follow dynamic linking strategy.

Steps In Creating Static Library

Step1: implement the library source. Let us assume there are two files namely one.c and two.c each implementing one function as follows
$ vim one.c
#include<stdio.h>
void fun1(){
printf("This is function 1
");
}
~
$ vim two.c
#include<stdio.h>
void fun2(){
printf("This is function 2
");
}
~


Step2: compile the sources (one.c, two.c) to generate relocatables
$ gcc -c one.c
$ gcc -c two.c
ls -l
total 16
-rw-r--r-- 1 gvamshi gvamshi 66 2011-01-23 14:59 one.c
-rw-r--r-- 1 gvamshi gvamshi 844 2011-01-23 15:01 one.o
-rw-r--r-- 1 gvamshi gvamshi 66 2011-01-23 14:58 two.c
-rw-r--r-- 1 gvamshi gvamshi 844 2011-01-23 15:01 two.o
$

Note: “.a “ is the extension for the static libraries.

Using the archive tool ar we create a static library.

$ ar rcs libmyown.a one.o two.o

- libmyown.a is the own static library to be created. According to the general naming conventions a library should start with “lib” .
- rcs are the options (replace, create, symbol) for more details refer to man pages as follows.
- one.o and two.o are the list of sources to be packed into archive.

The above created static library is position dependent.

$ man ar (this gives description about the usage of ar)
$ info ar (this gives information like an ebook)

To list what all files have gone into archive type use option‘t’ of ar.
$ ar -t libmyown.a
one.o
two.o

you can even view the list of file that are packed into libc.a standard library as follows. To see where libc.a located in your machine use whereis as follows, which gives the path for libc.a
$ whereis libc.a
libc: /usr/lib/libc.so /usr/lib/libc.a /usr/share/man/man7/libc.7.gz

$ ar -t /usr/lib/libc.a init-first.o |more
libc-start.o
sysdep.o
version.o
check_fds.o
libc-tls.o
elf-init.o
dso_handle.o
errno.o
--More--
Now we can ship our library to costumer, along with this we even need to ship the header file to give the function prototypes. Create a header file mylib.h as follows.

$ vim mylib.h
void fun1();
void fun2();

to make use of the library above created write a test application as follows.
$ vim test.c
#include<stdio.h>
#include<mylib.h>
main(){
printf("This is test to create own library
");
fun1();/*call to function */
fun2();/*call to function */
}

Now compile the source file as follows.

$ gcc test.c -o test (gives an error)
test.c:2:18: error: mylib.h: No such file or directory

to figure out where the error occurred use the following option
$ gcc -v test.c -o test
v option with gcc, stands for verbose.
the error is because the header files included are searched at the following locations.
/usr/local/include
         /usr/lib/gcc/i486-linux-gnu/4.4.3/include
           /usr/lib/gcc/i486-linux-gnu/4.4.3/include-fixed
           /usr/include
where in our header file exists in the current working directory, and is not in above of the paths, so we have to explicitly say this by using the option I.
$ gcc -I ./ test.c -o test (gives error)
/tmp/ccFPPIsN.o: In function `main:
test.c:(.text+0x16): undefined reference to `fun1
test.c:(.text+0x1b): undefined reference to `fun2
collect2: ld returned 1 exit status

Still we end up with the above errors as we missed library, so follow the below step.

$ gcc -I ./ test.c -o teststatic ./libmyown.a
$ ./test
This is test to create own library
This is function 1
This is function 2

Here important thing to note is what ever the executable (teststatic) we generated is not complete static, it is dynamically linked, this can be know by the tool file.

$ file teststatic
teststatic: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped

Therefore to obtain a complete static executable use the -static flag with the above command and check out the type of file as above.

$ gcc -static -I ./ test.c -o test_complete_static ./libmyown.a
$ file test_complete_static
test_complete_static: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.15, not stripped

One more thing to discuss is, in the above output there is something like “not stripped”. Which means there is some extra information like metadata in the executable. That extra unnecessary information can be removed using the tool strip. After stripping the file check out the earlier and current file sizes.
$ ls -l test_complete_static
-rwxr-xr-x 1 gvamsi gvamsi 578100 2011-01-23 17:14 test_complete_static

$ strip test_complete_static
$ ls -l test_complete_static
-rwxr-xr-x 1 gvamsi gvamsi 515108 2011-01-23 17:15 test_complete_static


 Click here to know about Dynamic Library Creation
                                   

Please leave comment :-)                                                  Queries are at free of cost

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.