This article is to explain the compilation and linking process. This also covers static and dynamic library concept.
- Program Compilation Phases
- How libraries Linked With Program ?
- Static and Dynamic Library scenario
- Static/dynamic library Advantages and Disadvantages
- How to generate dynamic/shared library on windows/linux platform ?
Application Compilation ,Linking and Loading Process
When we compile a code, compiler start to convert high level language to binaries and it create symbolic links to for all type of function calls
Lets refresh some basics first.
As you know the purpose of Build system (Compiler, Assembler and Linker) to convert HLL(High Level Language) to executable binary. The binary in the embedded system contains standard libraries , Legacy tested library and application.
The header file used in source code will have links to other code modules in terms of function prototypes. Library files contain actual definition of these functions.
For Example when you install a build ecosystem , It not only installs IDE for software development but also default standard libraries associated with compiler.
Application Build Phases
Pre-processing ->> Compilation ->> Linking
Pre-processor: Replace all pre-processor Directives indicated by “#” symbol.
Compilation: Check the code syntax and if there is no error converts code to object files . It also generates symbols for global variables, function calls etc .
Also it creates Symbol for all Function Calls and Global Variables etc.
Linker: After compilation process, Linker creates symbolic link between symbols and function call definition or global variable address.
-llibrary Search the library named library when linking
-l library Search the library named library when linking
-lobjc in order to link an Objective-C or Objective-C++ program
-nodefaultlibs Do not use the standard system libraries when linking
-nostartfiles Do not use the standard system startup files when linking
-nolibc Do not use the C library
-nostdlib Do not use the standard system startup files/library
-pie Produce a dynamically linked position independent executable
-static static Linking If dynamic Linking is default
-shared Produce a shared object
Executable will be generated at the end of Linker phase. Now the final executable binary will have all symbolic links with function definitions. It will also contain standard library functions.
What is Symbolic Link ?
The symbolic link mentioned here should not be confused with Linux File System Symbolic Link or Soft link.
So there are user defined libraries and also standard libraries. Following shows how library is linked with an application program.
Static Library Scenario
Lets to try to understand a case of static library with multiple applications say 100 applications. If every application is using same static library and libraries are statically linked with individual application, the particular library will become part of application program memory map. It will be wastage of program memory and hundred times duplication of same static library .
As Shown in above picture “User_lib” will consume space individually for each application Program. After Creation of executable file when we run the application, Application Loader only loads the executable file. There are no other dependencies, because all dependency already exist in the executable.
Dynamic Library Scenario
When application is compiled with dynamic or shared library attributes. Linker will create symbols only. Actual symbolic links are connected when application is loaded. This symbolic links are formed by loader /Dynamic Loader, when we are loading application.
If application is compiled with dynamic library options , then all applications will have symbols of user defined library functions as shown in above picture.
When dynamic loader is triggered to load a particular file(which is using dynamic/shared library), It will first load the dynamic/shared library in the memory and then loads the application in memory. Finally the symbol links will be formed. Dynamic loader search the shared library in the path provided. If it can’t find specific library, It terminates the loading procedure and raise error message.
It is programmer’s responsibility to make sure the shared library is present in the defined path or the path should be updated.
Now in this scenario only one instance of library will be loaded and all applications will have symbolic link to that particular dynamic/shared library.
Advantages and Disadvantages
|Static Library||Dynamic Library|
|Advantages||1: Application executable contains the library so independent of any version.||1: Application and shared/dynamic library are linked with symbolic link . In case of two or more applications using shared library, the overall size taken by library will be less.|
|2: Static library is already linked , so application load time is less/||2: Application binary will be smaller|
|3: For small updates/ bug fixes in library , One has to compile only dynamic and restart the application.|
|Disadvantages||1: If multiple applications are using the same library, then it is not the optimal memory utilization.||1: Application loading time is more because of dynamic library loading and dynamic link creation activity.|
|2: Executable file size will be bigger. The whole application needs to be re-build even for small patch work in library.||2: Application execution and behavior depend on library version.|
Dynamic Library creation in windows/Linux operating system
Shared_lib.c (user defined Shared library)
Main_prog.c (This is application which use user defined shared library)
Following are the steps to compile and link
gcc –c –pie shared_lib.c //Creates a position independent binary shared_lib.o
gcc –shared –o libshared_lib.so shared_lib.o //Create a shared library
gcc -L/home/project/ -o main_prog main_prog.c -lshared_lib
//Compile main_prog executable program with shared Library Input
/*Adding Path to library Variable so this path will be also checked by Loader when application is loading to attach library*/
main application with shared library will run and print output as expected. You may also validate the shared library use by checking address map.
Check PID of application in TOP(typ e top on shell). Type “top” to know PID
Address MAP of 316 “main_prog”
Did you notice libshared_lib.so ?
You may do further experiment by creating multiple applications which use same library .
Note – If applications use library service routine or it’s global data , then it is programmer’s responsibility to make the particular function re-entrant and avoid race condition while accessing global data.
Embedded Software EngineerSkills: C Programming, Embedded System DesigningQualification: Electrical Engineering, PGd- Embedded Systems designing
Thanks for reading till end. If you liked it, Please share in your network.
Have a look at Embedkari Low Cost Products