How to create Shared Library in Linux ?

If you want to create static library visit our another article “How to Create Static Library in Linux ?”

Below program demos how to create a shared library and link it with the main program to create a executable. Shared libraries requires less RAM than static libraries, has only one copy in RAM at any point of time. You can read more information at “Difference between static and dynamic library linking”

For simple demo, we will write two files / c program each of which has one function defined inside it.

$ vim first.c
#include <stdio.h>
#include "header.h"

void function1(void) {
        printf("This is function1\n");
}
$ vim second.c
#include <stdio.h>
#include "header.h"
 
void function2(void) {
        printf("This is Function2\n");
}
$ vim header.h
#ifndef __HEADER_H
#define __HEADER_H

void function1(void);
void function2(void);

#endif
$ gcc -c first.c 
-rw-rw-r-- 1 myuser myuser 1.1K Sep  1 20:49 first.o
 $ gcc -c second.c
-rw-rw-r-- 1 myuser myuser 1.1K Sep  1 20:49 second.o
$ gcc -o testlib.so -shared first.o second.o
-rwxrwxr-x 1 myuser myuser 6.9K Sep  1 22:18 testlib.so
 $ file testlib.so testlib.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, BuildID[sha1]=00cebe431ba7f5a5df7d019d265db58916552303, not stripped
$ nm -s testlib.so 
00002010 B __bss_start
00002010 b completed.7200
         w __cxa_finalize@@GLIBC_2.1.3
00000420 t deregister_tm_clones
000004b0 t __do_global_dtors_aux
00001f14 t __do_global_dtors_aux_fini_array_entry
0000200c d __dso_handle
00001f1c d _DYNAMIC
00002010 D _edata
00002014 B _end
00000574 T _fini
00000500 t frame_dummy
00001f10 t __frame_dummy_init_array_entry
0000064c r __FRAME_END__
00000540 T function1
00000559 T function2
00002000 d _GLOBAL_OFFSET_TABLE_
         w __gmon_start__
000005ac r __GNU_EH_FRAME_HDR
000003cc T _init
         w _ITM_deregisterTMCloneTable
         w _ITM_registerTMCloneTable
00001f18 d __JCR_END__
00001f18 d __JCR_LIST__
         w _Jv_RegisterClasses
         U puts@@GLIBC_2.0
00000460 t register_tm_clones
00002010 d __TMC_END__
00000410 t __x86.get_pc_thunk.bx
0000053c t __x86.get_pc_thunk.dx

From “nm” command, we can see that now our created library has the symbols from both the object files first.o and second.o. so, now our shared library is ready. Now lets write a main program or application which will use this library and write its own application using library functions as,

$ vim main.c
$ vim main.c
#include <stdio.h>
#include "header.h"
int main(int argc, char *argv[]) {
        function1(); //call function1 from first.c
        function2(); //call function2 from second.c
        return 0;
}
$ gcc -o main main.c testlib.so
 $ file main
main: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=a7f9aee8eb8dbed81d4894af0a25be7d36476f02, not stripped

Now, lets try to execute our newly created executable “main” as,

 $ ./main 
./main: error while loading shared libraries: testlib.so: cannot open shared object file: No such file or directory 

Despite having our library created and linked, Why this happened ? Lets try to diagnose,

$ ldd main
	linux-gate.so.1 =>  (0xb772e000)
	testlib.so => not found
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb754a000)
	/lib/ld-linux.so.2 (0x800e4000) 

As per ldd, its showing that main is unable to find the “testlib.so” since this is dynamically linked library, we have to mention the path where this library is stored to the executable during the start. Ideally, the path searched are what has been seen in “LD_LIBRARY_PATH” so, we have to add our present path to this environment variable as,

 $ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD 

Now, check with “ldd”, it shows library found.

$ ldd main	linux-gate.so.1 =>  (0xb776d000)
	testlib.so (0xb7766000)
	libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7586000)
	/lib/ld-linux.so.2 (0x80092000)
$ ./main 
This is function1
This is Function2

OR You can use the Makefile as below to compile everything and just type “make” in same directory by copying this Makefile.

$ vim Makefile 
all:
        gcc -c first.c
        gcc -c second.c
        gcc -o testlib.so -shared first.o second.o
        gcc -o main main.c testlib.so
clean:
        rm -rf main testlib.so first.o second.o

If you want to create static library visit our another article “How to Create Static Library in Linux ?”

2 thoughts on “How to create Shared Library in Linux ?”

Leave a Comment