Sunday 9 September 2012

How to create a static library in linux


: Step 1: 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\n");
}
~
$ vim two.c
#include<stdio.h>
void fun2(){
printf("This is function 2\n");
}
~


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 ramchandra ramchandra 66 2011-01-23 14:59 one.c
-rw-r--r-- 1 ramchandra ramchandra 844 2011-01-23 15:01 one.o
-rw-r--r-- 1 ramchandra ramchandra 66 2011-01-23 14:58 two.c
-rw-r--r-- 1 ramchandra ramchandra 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
 
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\n");
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 following errors.
$ 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 ramchandra ramchandra 578100 2011-01-23 17:14 test_complete_static

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

No comments:

Post a Comment