How to Generate Static Library and Dynamic Library(Shared Libaries) Using Makefile:
First of all i would like give some introduction about static library and dynamic library.
The difference between static and dynamic libraries can be viewed as how you get to work. You can drive your car or you can take a train. Driving your own car is kinda like a static library. Taking the train is kinda like a shared library.
When you drive your car all you need is the car. When you take the train there is usually more than one train car by itself. Usually there's a locomotive, and then some passenger cars, and maybe a caboose to boot. As long as all the cars are working in harmony you continue to get to work. If any of the cars has a problem your chances of getting to work diminish.
When you compile a program with static libraries statically linked libraries are linked into the final executable by the linker. This increases the size of the executable. Likewise when a library needs to be updated you'll need to compile the new library and then recompile the application to take advantage of the new library. Ok, so why do we have static libraries then? Well if you're booting your system into maintenance mode static libraries can be beneficial.
The difference between static and dynamic libraries can be viewed as how you get to work. You can drive your car or you can take a train. Driving your own car is kinda like a static library. Taking the train is kinda like a shared library.
When you drive your car all you need is the car. When you take the train there is usually more than one train car by itself. Usually there's a locomotive, and then some passenger cars, and maybe a caboose to boot. As long as all the cars are working in harmony you continue to get to work. If any of the cars has a problem your chances of getting to work diminish.
When you compile a program with static libraries statically linked libraries are linked into the final executable by the linker. This increases the size of the executable. Likewise when a library needs to be updated you'll need to compile the new library and then recompile the application to take advantage of the new library. Ok, so why do we have static libraries then? Well if you're booting your system into maintenance mode static libraries can be beneficial.
What is Static Library?
Static
libraries are simply a collection of ordinary object files;
conventionally, static libraries end with the ``.a'' suffix. This
collection is created using the ar (archiver) program.
In static linking, the size of the executable becomes greater than in dynamic linking, as the library code is stored within the executable rather than in separate files
Static
libraries permit users to link to programs without having to recompile
its code, saving recompilation time. Note that recompilation time is
less important given today's faster compilers, so this reason is not as
strong as it once was. Static libraries are often useful for developers
if they wish to permit programmers to link to their library, but don't
want to give the library source code.
To create a static library, or to add additional object files to an existing static library, use a command like this:
ar rcs library.a File1.o File2.o
or
ar -qcs library.a File1.o File2.o
Makefile to Generate Static Library.
Let's take small example, suppose there are two files and generate the static library and link it to main file.
int fun1(int a, int b)
{
int c;
/* add the Two Variables */
c= a+b;
return(c);
}
int fun2(int a, int b)
{
int c;
/* add the Two Variables */
c= a+b;
return(c);
}
Above there are two files, here you can find the Makefile to generate the library using file1.o and file2.o
CC = gcc
CFLAGS = -g -Wall
# .a extension for static library
# .so extension for dynamic library
# step 1:
# it goes to step2:
all: libMylibrary.a
#step 3:
# Return to step 2
# Declare this OBJS before it is used, Here OBJS is a variable.
OBJS = $(PWD)/file1.o \
$(PWD)/file2.o
#step 2:
libMylibrary.a : $(OBJS)
ar -qcs libMylibrary.a $(OBJS)
# step 4:
# Return to step 3
$(PWD)/%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o
rm -f *.a
#include<stdio.h>
#include<stdlib.h>
extern int fun1(int a, int b);
extern int fun2(int a, int b);
int main()
{
printf("The value of Function1: %d", fun1(4,5));
printf("The value of Function2: %d", fun2(6,7));
return 0;
}
clean:
rm -f *.o
rm -f *.a
Important Point:
When ever you are linking static library to mainFile, it is mandatory to mention the LIBDIR( where the library is present) using -L option. This $(LIBDIR) should be included when generating .exe file.
Step1: Create Directories of BModule, DModule, CModule
create directories under /root/mreddya/MAKEFILE_EXERCISE/as shown below.
Step2: Create sub-directories of BModule, DModule, CModule
create sub directories under each module as shown below.
file1.c
int fun1(int a, int b)
{
int c;
/* add the Two Variables */
c= a+b;
return(c);
}
file2.c
int fun2(int a, int b)
{
int c;
/* add the Two Variables */
c= a+b;
return(c);
}
Above there are two files, here you can find the Makefile to generate the library using file1.o and file2.o
Makefile to generate MyLibrary.a using file1.o and file2.o
CC = gcc
CFLAGS = -g -Wall
# .a extension for static library
# .so extension for dynamic library
# step 1:
# it goes to step2:
all: libMylibrary.a
#step 3:
# Return to step 2
# Declare this OBJS before it is used, Here OBJS is a variable.
OBJS = $(PWD)/file1.o \
$(PWD)/file2.o
#step 2:
libMylibrary.a : $(OBJS)
ar -qcs libMylibrary.a $(OBJS)
# step 4:
# Return to step 3
$(PWD)/%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f *.o
rm -f *.a
How to Link this library to the Main function file to get .exe
mainFile.c
#include<stdio.h>
#include<stdlib.h>
extern int fun1(int a, int b);
extern int fun2(int a, int b);
int main()
{
printf("The value of Function1: %d", fun1(4,5));
printf("The value of Function2: %d", fun2(6,7));
return 0;
}
Makefile links library and generate the test.exe
CC = gcc
CFLAGS = -g -Wall
# .a extension for static library
# .so extension for dynamic library
# step 1:
# it goes to step2:
all: test
#step 3:
# Return to step 2
OBJS = $(PWD)/mainFile.o \
#step 2:
test : $(OBJS)
$(CC) $(CFLAGS) $(OBJS) $(LIBDIR) $(LIBLOG) -o test.exe
#step 4:
# Return to Step 3
$(PWD)/mainFile.o : mainFile.c
$(CC) $(CFLAGS) -c mainFile.c
# Step 5:
CFLAGS = -g -Wall
# .a extension for static library
# .so extension for dynamic library
# step 1:
# it goes to step2:
all: test
#step 3:
# Return to step 2
OBJS = $(PWD)/mainFile.o \
#step 2:
test : $(OBJS)
$(CC) $(CFLAGS) $(OBJS) $(LIBDIR) $(LIBLOG) -o test.exe
#step 4:
# Return to Step 3
$(PWD)/mainFile.o : mainFile.c
$(CC) $(CFLAGS) -c mainFile.c
# Step 5:
# For static library, always include LIB DIR
# This is Mandatory
LIBDIR = -L./
LIBLOG = -lMylibrary
LIBDIR = -L./
LIBLOG = -lMylibrary
rm -f *.o
rm -f *.a
Important Point:
When ever you are linking static library to mainFile, it is mandatory to mention the LIBDIR( where the library is present) using -L option. This $(LIBDIR) should be included when generating .exe file.
Note: How to run your own makefile, suppose i have makefile as Makefile_org, then run using the below command.
make -f Makefile_org
clean :
make -f Makefile_org clean
Real Time Example.
Suppose there are three modules BMODULE, CMODULE , DMODULE. BMODULE is having dependency upon other two modules i.e. CMODULE , DMODULE .
Hence, first compile CMODULE and DMODULE and link their objects to BMODULE to generate the .exe.
Here DMODULE generates the static library and CMODULE generates the object files(o's)Step1: Create Directories of BModule, DModule, CModule
-bash-3.2# mkdir mreddya
-bash-3.2# mkdir MAKEFILE_EXERCISE
-bash-3.2# mkdir BMODULE
-bash-3.2# mkdir CMODULE
-bash-3.2# mkdir DMODULEStep2: Create sub-directories of BModule, DModule, CModule
create sub directories under each module as shown below.
-bash-3.2# cd DMODULE/
-bash-3.2# mkdir src
-bash-3.2# mkdir inc
-bash-3.2# mkdir obj
-bash-3.2# cd CMODULE/
-bash-3.2# mkdir src
-bash-3.2# mkdir inc
-bash-3.2# mkdir obj
-bash-3.2# cd BMODULE/
-bash-3.2# mkdir src
-bash-3.2# mkdir inc
-bash-3.2# mkdir obj
Step 3: Generate Library for DModule for the below files
-bash-3.2# cd DMODULE/
-bash-3.2# cd
Create four files under source directory, dModulefile1.c dModulefile2.c dModulefile3.c, Makefile
-bash-3.2# cd DMODULE/
-bash-3.2# cd inc
Create three files under inc,dModulefile1.h dModulefile2.h dModulefile3.h
dModulefile1.c
#include "dModulefile1.h"
int DModuleFunction1(int a)
{
printf("I am in DModuleFunction1 and its Value:%d", a);
a = a + FUNC_VALUE4;
return(a);
}
int DModuleFunction1(int a)
{
printf("I am in DModuleFunction1 and its Value:%d", a);
a = a + FUNC_VALUE4;
return(a);
}
dModulefile2.c
#include "dModulefile2.h"
int DModuleFunction2(int b)
{
printf("I am in DModuleFunction2 and its Value:%d", b);
b = b + FUNC_VALUE5;
return(b);
}
int DModuleFunction2(int b)
{
printf("I am in DModuleFunction2 and its Value:%d", b);
b = b + FUNC_VALUE5;
return(b);
}
dModulefile3.c
#include "dModulefile3.h"
int DModuleFunction3(int c)
{
printf("I am in DModuleFunction3 and its Value:%d", c);
c = c + FUNC_VALUE6;
return(c);
}
int DModuleFunction3(int c)
{
printf("I am in DModuleFunction3 and its Value:%d", c);
c = c + FUNC_VALUE6;
return(c);
}
dModulefile1.h
#include<stdio.h>
#define FUNC_VALUE4 14
dModulefile2.h
#include<stdio.h>
#define FUNC_VALUE5 11
dModulefile3.h
#include<stdio.h>
#define FUNC_VALUE6 13
#include<stdio.h>
#define FUNC_VALUE6 13
Step 4: Makefile for DMODULE (Makefile place in src directory)
# define the Compiler as gcc
CC = gcc
# define compiler flags "CFLAGS" if you -g option it is for GDB, -wall to display all
# warnings
CFLAGS= -g -Wall
# TO include Directories, To include any directories give -I/Path Directory
# e.g: INCLUDEDIR = -I/VOBS/CMODULE/INC/, to include one more directory
# then Syntax will be INCLUDEDIR += -I/VOBS/CMODULE/INC/
# INCLUDEDIR = -I/VOBS/BMODULE/INC/
INCLUDEDIR = -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc
# define MACRO for OBJECT DIRETORY
OBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj
# copy all .o( Objects) in to object directory
# All Objects are stored in OBJ-DIR
#
OBJS = $(OBJ-DIR)/dModulefile1.o \
$(OBJ-DIR)/dModulefile2.o \
$(OBJ-DIR)/dModulefile3.o \
# First whenever we give Make, it comes here, and Check OBJS
# Then It will check what and all .o are required from
CC = gcc
# define compiler flags "CFLAGS" if you -g option it is for GDB, -wall to display all
# warnings
CFLAGS= -g -Wall
# TO include Directories, To include any directories give -I/Path Directory
# e.g: INCLUDEDIR = -I/VOBS/CMODULE/INC/, to include one more directory
# then Syntax will be INCLUDEDIR += -I/VOBS/CMODULE/INC/
# INCLUDEDIR = -I/VOBS/BMODULE/INC/
INCLUDEDIR = -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc
# define MACRO for OBJECT DIRETORY
OBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj
# copy all .o( Objects) in to object directory
# All Objects are stored in OBJ-DIR
#
OBJS = $(OBJ-DIR)/dModulefile1.o \
$(OBJ-DIR)/dModulefile2.o \
$(OBJ-DIR)/dModulefile3.o \
# First whenever we give Make, it comes here, and Check OBJS
# Then It will check what and all .o are required from
# OBJS directory
# then it will go Command to generate the .o's.
# then it will go Command to generate the .o's.
all: libDmodule.a
# Generate the Library
libDmodule.a: $(OBJS)
ar -qcs libDmodule.a $(OBJS)
#To Generate %.o means same directory.
# target ( It tells $(OBJ-DIR)/%.o : %.c, generate the %.c files # to .o files using command.)
# To get the Target the below command should be executed,
# target ( It tells $(OBJ-DIR)/%.o : %.c, generate the %.c files # to .o files using command.)
# To get the Target the below command should be executed,
# otherwise Linker error will be there.
$(OBJ-DIR)/%.o : %.c
$(CC) $(CFLAGS) $(INCLUDEDIR) -c $< -o $@
clean:
rm -f $(OBJ-DIR)/*.o
rm -f *.a
Step 5: Run the Makefile and check the results
-bash-3.2# pwd
/root/mreddya/MAKEFILE_EXERCISE/DMODULE/src
/root/mreddya/MAKEFILE_EXERCISE/DMODULE/src
-bash-3.2# make
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc -c dModulefile1.c -o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile1.o
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc -c dModulefile2.c -o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile2.o
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc -c dModulefile3.c -o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile3.o
ar -qcs libDmodule.a /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile1.o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile2.o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile3.o
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc -c dModulefile1.c -o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile1.o
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc -c dModulefile2.c -o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile2.o
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/DMODULE/inc -c dModulefile3.c -o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile3.o
ar -qcs libDmodule.a /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile1.o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile2.o /root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj/dModulefile3.o
-bash-3.2# ls
dModulefile1.c dModulefile2.c dModulefile3.c libDmodule.a Makefile
dModulefile1.c dModulefile2.c dModulefile3.c libDmodule.a Makefile
-bash-3.2# pwd
/root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj
/root/mreddya/MAKEFILE_EXERCISE/DMODULE/obj
-bash-3.2# ls
dModulefile1.o dModulefile2.o dModulefile3.o
dModulefile1.o dModulefile2.o dModulefile3.o
Step 6: Generate objects for CMODULE
-bash-3.2# cd CMODULE/
-bash-3.2# cd
Create four files under source directory, cModulefile1.c cModulefile2.c cModulefile3.c, Makefile
-bash-3.2# cd CMODULE/
-bash-3.2# cd inc
Create three files under inc,cModulefile1.h cModulefile2.h cModulefile3.h
cModulefile1.c
#include "cModulefile1.h"
int CModuleFunction1(int a)
{
printf("I am in CModuleFunction1 and its Value:%d", a);
a = a + FUNC_VALUE1;
return(a);
}
int CModuleFunction1(int a)
{
printf("I am in CModuleFunction1 and its Value:%d", a);
a = a + FUNC_VALUE1;
return(a);
}
cModulefile2.c
#include "cModulefile2.h"
int CModuleFunction2(int b)
{
printf("I am in CModuleFunction2 and its Value:%d", b);
b = b + FUNC_VALUE2;
return(b);
}
{
printf("I am in CModuleFunction2 and its Value:%d", b);
b = b + FUNC_VALUE2;
return(b);
}
dModulefile3.c
#include "cModulefile3.h"
int CModuleFunction3(int c)
{
printf("I am in CModuleFunction3 and its Value:%d", c);
c = c + FUNC_VALUE3;
return(c);
}
int CModuleFunction3(int c)
{
printf("I am in CModuleFunction3 and its Value:%d", c);
c = c + FUNC_VALUE3;
return(c);
}
cModulefile1.h
#include<stdio.h>
#define FUNC_VALUE1 10
cModulefile2.h
#include<stdio.h>
#define FUNC_VALUE2 11
cModulefile2.h
#include<stdio.h>
#define FUNC_VALUE3 11
Step 7: Makefile for CMODULE (Makefile place in src directory)
# define the Compiler as gcc
CC = gcc
# define compiler flags "CFLAGS" if you -g option it is for GDB, -wall to display all
# warnings
CFLAGS= -g -Wall
# TO include Directories, To include any directories give -I/Path Directory
# e.g: INCLUDEDIR = -I/VOBS/CMODULE/INC/, to include one more directory
# then Syntax will be INCLUDEDIR += -I/VOBS/CMODULE/INC/
# INCLUDEDIR = -I/VOBS/BMODULE/INC/
INCLUDEDIR = -I/root/mreddya/MAKEFILE_EXERCISE/CMODULE/inc
# define MACRO for OBJECT DIRETORY
OBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj
# copy all .o( Objects) in to object directory
# All Objects are stored in OBJ-DIR
#
OBJS = $(OBJ-DIR)/cModulefile1.o \
$(OBJ-DIR)/cModulefile2.o \
$(OBJ-DIR)/cModulefile3.o \
# First whenever we give Make, it comes here, and Check OBJS
# Then It will check what and all .o are required from
CC = gcc
# define compiler flags "CFLAGS" if you -g option it is for GDB, -wall to display all
# warnings
CFLAGS= -g -Wall
# TO include Directories, To include any directories give -I/Path Directory
# e.g: INCLUDEDIR = -I/VOBS/CMODULE/INC/, to include one more directory
# then Syntax will be INCLUDEDIR += -I/VOBS/CMODULE/INC/
# INCLUDEDIR = -I/VOBS/BMODULE/INC/
INCLUDEDIR = -I/root/mreddya/MAKEFILE_EXERCISE/CMODULE/inc
# define MACRO for OBJECT DIRETORY
OBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj
# copy all .o( Objects) in to object directory
# All Objects are stored in OBJ-DIR
#
OBJS = $(OBJ-DIR)/cModulefile1.o \
$(OBJ-DIR)/cModulefile2.o \
$(OBJ-DIR)/cModulefile3.o \
# First whenever we give Make, it comes here, and Check OBJS
# Then It will check what and all .o are required from
# OBJS directory
# then it will go Command to generate the .o's.
# then it will go Command to generate the .o's.
all: $(OBJS)
#To Generate %.o means same directory.
# target ( It tells $(OBJ-DIR)/%.o : %.c, generate the %.c files to .o files using command.)
# command.
#To Generate %.o means same directory.
# target ( It tells $(OBJ-DIR)/%.o : %.c, generate the %.c files to .o files using command.)
# command.
# To get the Target the below command should be executed, otherwise
# Linker error will be there.
# target ( It tells $(OBJ-DIR)/%.o : %.c, generate the %.c files to .o files using command.)
# command.
# To get the Target the below command should be executed, otherwise
# Linker error will be there.
$(OBJ-DIR)/%.o : %.c
$(CC) $(CFLAGS) $(INCLUDEDIR) -c $< -o $@
clean:
rm -f $(OBJ-DIR)/*.o
Step 8: Run the Makefile and check the results
-bash-3.2# pwd
/root/mreddya/MAKEFILE_EXERCISE/CMODULE/src
/root/mreddya/MAKEFILE_EXERCISE/CMODULE/src
-bash-3.2# make clean
rm -f /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj/*.o
-bash-3.2# make
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/CMODULE/inc -c cModulefile1.c -o /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj/cModulefile1.o
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/CMODULE/inc -c cModulefile2.c -o /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj/cModulefile2.o
gcc -g -Wall -I/root/mreddya/MAKEFILE_EXERCISE/CMODULE/inc -c cModulefile3.c -o /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj/cModulefile3.o
-bash-3.2# pwd
/root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj
-bash-3.2# ls
cModulefile1.o cModulefile2.o cModulefile3.o
/root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj
-bash-3.2# ls
cModulefile1.o cModulefile2.o cModulefile3.o
Step 9: Get .exe by Linking the CMODULE and DMODULE to BMODULE
-bash-3.2# cd BMODULE/
-bash-3.2# cd
Create two files under source directory, bModulefile.c, Makefile
-bash-3.2# cd BMODULE/
-bash-3.2# cd inc
Create one file under inc,bModulefile.h
bModulefile.c
#include<stdio.h>
#include "bModulefile.h"
/* extern the Functions */
extern int CModuleFunction1(int );
extern int CModuleFunction2(int );
extern int CModuleFunction3(int );
extern int DModuleFunction1(int );
extern int DModuleFunction2(int );
extern int DModuleFunction3(int );
void getFunValue(void)
{
int result = 0;
result = CModuleFunction1(3)* FUNC_VALUE8;
printf("The Result value with CModuleFunction1:%d\n", result);
result = CModuleFunction2(4)* FUNC_VALUE8;
printf("The Result value with CModuleFunction2:%d\n", result);
result = CModuleFunction3(5)* FUNC_VALUE8;
printf("The Result value with CModuleFunction3:%d\n", result);
result = DModuleFunction1(3)* FUNC_VALUE8;
printf("The Result value with DModuleFunction1:%d\n", result);
result = DModuleFunction2(4)* FUNC_VALUE8;
printf("The Result value with DModuleFunction2:%d\n", result);
result = DModuleFunction3(5)* FUNC_VALUE8;
printf("The Result value with DModuleFunction3:%d\n", result);
}
int main()
{
/* call the getFunValue Function */
getFunValue();
return 0;
}
bModulefile.h
#include "bModulefile.h"
/* extern the Functions */
extern int CModuleFunction1(int );
extern int CModuleFunction2(int );
extern int CModuleFunction3(int );
extern int DModuleFunction1(int );
extern int DModuleFunction2(int );
extern int DModuleFunction3(int );
void getFunValue(void)
{
int result = 0;
result = CModuleFunction1(3)* FUNC_VALUE8;
printf("The Result value with CModuleFunction1:%d\n", result);
result = CModuleFunction2(4)* FUNC_VALUE8;
printf("The Result value with CModuleFunction2:%d\n", result);
result = CModuleFunction3(5)* FUNC_VALUE8;
printf("The Result value with CModuleFunction3:%d\n", result);
result = DModuleFunction1(3)* FUNC_VALUE8;
printf("The Result value with DModuleFunction1:%d\n", result);
result = DModuleFunction2(4)* FUNC_VALUE8;
printf("The Result value with DModuleFunction2:%d\n", result);
result = DModuleFunction3(5)* FUNC_VALUE8;
printf("The Result value with DModuleFunction3:%d\n", result);
}
int main()
{
/* call the getFunValue Function */
getFunValue();
return 0;
}
bModulefile.h
#define FUNC_VALUE8 1
Step 10: Makefile for BMODULE (Makefile place in src directory)
This Makefile links both CMODULE and DMODULE and generates the test.exe
This Makefile links both CMODULE and DMODULE and generates the test.exe
Some points to be Noted here:
Before compiling BMODULE, first it is mandate to compile CMODULE and DMODULE.
Once CMODULE and DMODULE compiled and run the Makefile of BMODULE.
Step 11: Makefile compiles first CMODULE and DMODULE then BMODULE
Run this Makefile using make all command
Run this Makefile using make all command
# This is the Main Make file which incorporates all the files and
# generates the .exe file.
# define the Compiler Macro as gcc
CC = gcc
# define any Flags whether to compile as 64 bit(-m64) or with -g option
# to debug in gdb and also to show file name with warnings.
CFLAGS = -g -Wall
# Include the Directories which you want to link here.
# Include the .h directories.
# Whenever multiple directories are included then use += with -I option
INCL_DIR += -I/root/mreddya/MAKEFILE_EXERCISE/BMODULE/inc
# define MACRO for OBJECT DIRETORY
OBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/BMODULE/obj
EXE-DIR = /root/mreddya/MAKEFILE_EXERCISE/BMODULE/src
COBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj
DLIB_DIR = /root/mreddya/MAKEFILE_EXERCISE/DMODULE/src
OBJS = $(OBJ-DIR)/bModulefile.o
COBJS = $(COBJ-DIR)/cModulefile1.o \
$(COBJ-DIR)/cModulefile2.o \
$(COBJ-DIR)/cModulefile3.o \
EXTERNALLIBS = -L$(DLIB_DIR)
LIBLOG = -lDmodule
CMODULE_COMPILE:
cd /root/mreddya/MAKEFILE_EXERCISE/CMODULE/src && make
DMODULE_COMPILE:
cd /root/mreddya/MAKEFILE_EXERCISE/DMODULE/src && make
BMODULE_COMPILE:
$(CC) $(CFLAGS) $(INCL_DIR) -c *.c -o $(OBJS)
all:
make all_modules
all_modules:
make CMODULE_COMPILE
make DMODULE_COMPILE
make BMODULE_COMPILE
$(CC) -o test.exe $(OBJS) $(EXTERNALLIBS) $(LIBLOG) $(COBJS)
clean:
rm -f $(OBJ-DIR)/*.o
rm -f $(EXE-DIR)/*.exe
rm -f $(COBJ-DIR)/*.o
rm -f $(DOBJ-DIR)/*.o
There are several ways to write make files, this is one way.
write small script and compile the Makefiles like show below.
# generates the .exe file.
# define the Compiler Macro as gcc
CC = gcc
# define any Flags whether to compile as 64 bit(-m64) or with -g option
# to debug in gdb and also to show file name with warnings.
CFLAGS = -g -Wall
# Include the Directories which you want to link here.
# Include the .h directories.
# Whenever multiple directories are included then use += with -I option
INCL_DIR += -I/root/mreddya/MAKEFILE_EXERCISE/BMODULE/inc
# define MACRO for OBJECT DIRETORY
OBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/BMODULE/obj
EXE-DIR = /root/mreddya/MAKEFILE_EXERCISE/BMODULE/src
COBJ-DIR = /root/mreddya/MAKEFILE_EXERCISE/CMODULE/obj
DLIB_DIR = /root/mreddya/MAKEFILE_EXERCISE/DMODULE/src
OBJS = $(OBJ-DIR)/bModulefile.o
COBJS = $(COBJ-DIR)/cModulefile1.o \
$(COBJ-DIR)/cModulefile2.o \
$(COBJ-DIR)/cModulefile3.o \
EXTERNALLIBS = -L$(DLIB_DIR)
LIBLOG = -lDmodule
CMODULE_COMPILE:
cd /root/mreddya/MAKEFILE_EXERCISE/CMODULE/src && make
DMODULE_COMPILE:
cd /root/mreddya/MAKEFILE_EXERCISE/DMODULE/src && make
BMODULE_COMPILE:
$(CC) $(CFLAGS) $(INCL_DIR) -c *.c -o $(OBJS)
all:
make all_modules
all_modules:
make CMODULE_COMPILE
make DMODULE_COMPILE
make BMODULE_COMPILE
$(CC) -o test.exe $(OBJS) $(EXTERNALLIBS) $(LIBLOG) $(COBJS)
clean:
rm -f $(OBJ-DIR)/*.o
rm -f $(EXE-DIR)/*.exe
rm -f $(COBJ-DIR)/*.o
rm -f $(DOBJ-DIR)/*.o
There are several ways to write make files, this is one way.
write small script and compile the Makefiles like show below.
build.sh script
cd /root/mreddya/MAKEFILE_EXERCISE/CMODULE/src
make
cd /root/mreddya/MAKEFILE_EXERCISE/DMODULE/src
make
cd /root/mreddya/MAKEFILE_EXERCISE/BMODULE/src
make
By using shared library concept, one can make the code is position-independent, meaning that the code may be loaded anywhere in memory. Applications linked to shared objects at run time.
Step 1:
make
cd /root/mreddya/MAKEFILE_EXERCISE/DMODULE/src
make
cd /root/mreddya/MAKEFILE_EXERCISE/BMODULE/src
make
What is Dynamic Library or Shared Library (.so)?
Dynamic library is also called as Shared Library.
Shared Library is a binary file(.so file) contains object (.o) files. All object files form as shared library and this library can be loaded or unloaded dynamically.By using shared library concept, one can make the code is position-independent, meaning that the code may be loaded anywhere in memory. Applications linked to shared objects at run time.
How to generate a shared library:
Step 1: Create object code, it means generate object files (.o files)
gcc -fPIC -c <filename.c>
The -fPIC option tells gcc to create position independent code which is necessary for shared libraries.
e.g: gcc -fPIC -c myfilename.c
Step 2: Create shared library
gcc -g -Wall -shared -o <library Name> <objectfile1.o, objectfile2.o>
It will create the library with .so extension.
e.g: gcc -g -Wall -shared -o libMyfuncs.so file1.o file2.o
How to use the shared library to your application
Step 1:
Set the environment for Library using
export LD_LIBRARY_PATH=.
The above indicates the path directory where the library is present. ./ or . indicates the present directory
Step 3:
And then Link the shared library to the main file as mentioned below.
Compile your Main file and generate the object code.
e.g: gcc -c mainFile
And then Link the shared library to the main file as mentioned below.
e.g: gcc -L./ -lMyfuncs mainFile.o -o test.exe
Notes:
suppose if "-L/opt/exp", means library is present in this directory and link the library using -llibName. The name of the library is Myfuncs.so.
The libraries will NOT be included in the executable but will be dynamically linked during run time execution.
The libraries will NOT be included in the executable but will be dynamically linked during run time execution.
That's reason size of .exe is small when we compare with static library.
How to check the list of shared libraries using by the application.
Use simple command.
ldd <.exe>
-bash-3.2# ldd test.exe
libMyFun.so => ./libMyFun.so (0x00002ab25d70f000)
libc.so.6 => /lib64/libc.so.6 (0x0000003ef7c00000)
/lib64/ld-linux-x86-64.so.2 (0x0000003ef6c00000)
Simple Makefile to generate shared library
file1.c
int func1(int a, int b)
{
int c;
/* Add */
c= a+b;
return(c);
}
file2.c
{
int c;
/* Add */
c= a+b;
return(c);
}
CC = gcc
CFLAGS = -g -Wall
OBJS = $(PWD)/file1.o \
$(PWD)/file2.o
all: libMyFun.so
libMyFun.so : $(OBJS)
$(CC) $(CFLAGS) -shared -o libMyFun.so $(OBJS)
$(PWD)/%.o : %.c
$(CC) $(CFLAGS) -fPIC -c *.c
clean:
rm -f *.o
rm -f *.so
How to Link this shared library to the mainFile.c
mainFile.c
#include<stdio.h>
extern int func1(int, int);
extern int func2(int, int);
int main()
{
printf("The result of Function 1 is: %d\n", func1(4,5));
printf("The result of Function 1 is: %d\n", func2(10,20));
return 0;
}
Build.sh <Generate the test.exe using small script>
#step 1: clean the Library
make clean
#step 2: Generated the Library
make
#step 3: Generates the mainFile.o
gcc -c mainFile.c
#step 4: clean the .exe
rm -f *.exe
#step 5: Link the Shared library to mainFile.o and
#generates the test.exe file.
gcc -L./ -lMyFun mainFile.o -o test.exe
make clean
#step 2: Generated the Library
make
#step 3: Generates the mainFile.o
gcc -c mainFile.c
#step 4: clean the .exe
rm -f *.exe
#step 5: Link the Shared library to mainFile.o and
#generates the test.exe file.
gcc -L./ -lMyFun mainFile.o -o test.exe
Run the Build.sh
chmod +x Build.sh
./Build.sh