Monday, September 2, 2013

Create C Program with Static Library using Command Line in Mac OS X

The following program is a complete program that uses some math functions:

#include <stdio.h>
#define PI 3.1415;
 
double CircleArea (double radius);
double CircleCircum (double radius);

double PowerOf2 (double number);
double PowerOf3 (double number);
 
int main ( )
{
 
 double r = 4.0;
 double n = 5.0;

 printf ("Radius %.2f, area is %.2f \n", r, CircleArea(r));
 printf ("Radius %.2f, circumference is %.2f \n", r, CircleCircum(r));
 printf ("%.2f to the power of 2 is %.2f \n", n, PowerOf2(n));
 printf ("%.2f to the power of 3 is %.2f \n", n, PowerOf3(n));

 return 0;

 
}
 
double CircleArea (double radius)
{
 return radius * radius * PI;
}

double CircleCircum (double radius)
{
 return 2 * radius * PI;
}
 

double PowerOf2 (double number)
{
 return number * number;
}

double PowerOf3 (double number)
{
 return number * number * number;
}


We create a static library so that we could reuse all the custom math functions for other programs. In this example, we will place the function declaration into libmymath.h. Then, we place the functions for circle in libmymath1.c and the power functions in libmymath2.c.

Note: You can have many C program file with just one header file such as lib.h, lib1.c, lib2.c ... and so on.

The header file for libmymath.h is as follows:

#define PI 3.1415;
 
double CircleArea (double radius);
double CircleCircum (double radius);

double PowerOf2 (double number);
double PowerOf3 (double number);


The program file for libmymath1.c is as follows:

#include "libmymath.h"
 
double CircleArea (double radius)
{
 return radius * radius * PI;
}

double CircleCircum (double radius)
{
 return 2 * radius * PI;
}
 

The program file for libmymath2.c is as follows:

#include "libmymath.h"


double PowerOf2 (double number)
{
 return number * number;
}

double PowerOf3 (double number)
{
 return number * number * number;
}


To compile the function program use the following command:
gcc -Wall -c libmymath1.c libmymath2.c

Note:
-c compile only
This command creates libmymath1.o libmymath2.o

Create Static Library
You can create static library using the command ar. This command also allows you to add additions library functions.

Library Naming Convention
The naming convention of a library package must be prefix with lib follow by the name of the library and the file must end with .a. Therefore a typical library should be named as libmymath.a

Common usage of ar command is as follows:
ar rcs libmymath.a libmymath1.o

Options:
r - insert the object files to archive
c - create archive if not exist
s - create index

You can append additional object file to the library file as follows: 
ar rcs libmymath.a libmymath2.o

Alternatively, you can use the command libtool to achive the same result:
libtool -static -o libmymath.a libmymath1.o libmymath2.o

Note:
Please note that the command ar can append additional object files to the archive whereas libtool can only replace the entire archive.


Create the Application Program
Create the following application program named as app1.c:
#include <stdio.h>
#include "libmymath.h"
 
int main ( )
{
 
        double r = 4.0;
 double n = 5.0;

 printf ("Radius %.2f, area is %.2f \n", r, CircleArea(r));
 printf ("Radius %.2f, circumference is %.2f \n", r, CircleCircum(r));
 printf ("%.2f to the power of 2 is %.2f \n", n, PowerOf2(n));
 printf ("%.2f to the power of 3 is %.2f \n", n, PowerOf3(n));

 return 0;
 
}

Note: Please note that you can use #include "libmymath.h" or #include "~/Documents/cprog/include/libmymath.h", depending on where your header file is.


Compile The Application
If static library file and header file are in the same folder then use any of the following command:
gcc -Wall app1.c -o app1 -lmymath -L ./
or
gcc -Wall app1.c -o app1 libmymath.a

Options:
-l option follow by library name indicate which static library to link, note that this option automatically add prefix lib and append .a, If you have more than one library file you must indicate it separately.
-L locates the path of library


If your file libmymath.a is located in /usr/lib or /usr/local/lib (man ld to see search path) then you no need -L, you can just use:
gcc -Wall app1.c -o app1 -lmymath


If your library file and header file are located in separate folder then:
gcc -Wall app1.c -o app1 -lmymath -I ~/Documents/cprog/include/ -L ~/Documents/cprog/slib/


Additional Tools
Besides gcc, ar or libtool, you can also use ranlib. Ranlib is equivalent to the command ar -s. There is also another tool known as ld. This is the basic linker which usually runs behind the scene when you run gcc. In Mac OS X, the linker ld is use with dyld, gcc is the symbolic link to llvm-gcc.

Library Display Tools
To display the contents of the static library, we use ar, otool or nm

To check what is inside libmymath.a, use any of the following command:
ar t libmymath.a 

otool -I libmymath.a

nm libmymath.a 

Note: Both ar and otool will only list the objects files contained in the library. The command nm is the better method because it also list the function names and object files. Linux and Mac uses nm but the usage is different, the options are not compatible

Special Notes:
Do we need to create a library file?
When you use the command ar to create a library file, it is basically an archive of many object files. A library file is useful for packaging and distribution purpose.

You can always compile your program without library file and use object files. The above program can be compile as follows:
gcc -Wall app1.c mymath1.o -o app1 

As you create more and more object files, then it is easier to group all the similar object files into a single library file. It is easier to use library file to distribute to other software developers instead of multiple object files.


*****

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.