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.

Command line execution

Terminalbash
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 ?”

Risk level: destructive. Review the command before running it.

Implementation details

$ 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.

Gotchas and common issues

  • Permission checks - verify user access rights and sudo privileges before executing system-level operations.

  • Environment configuration - double-check path variables and dependency versions to prevent runtime failures.

  • Backup safeguards - maintain configuration backups before applying system or database modifications.

Following these steps ensures clean configuration and reliable execution for create shared library in linux.