Wednesday, September 4, 2013

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

For those who are not familiar with static and dynamic library, the differences between static and dynamic library is the way it was compile and run. To use a static library, the application and the static library must be present during compilation. The compiler will extract the code from the static library and incorporated into the application program. You'll have only one application binary file.

When using dynamic library, the compiler do not incorporate the code from the dynamic library into the application program. The application program will load the library during runtime. In this case, you'll need to deliver two binary files to the user; the main application binary and the dynamic library file.

The advantages of using dynamic library are smaller application size since the library code is not incorporated in the application program and it may reduce memory usage when since the library is loaded only when the function is needed.

There are two usage of dynamic library in Mac OS X. The first usage is to load the library when the application is loaded. For preparation of such usage, you need to link the dynamic library while compiling the application. 

The second usage is to use the library as runtime-loaded library, in this case, the library is loaded when the application call for it using command such as dlopen in the application program. The implementation of such usage is beyond the scope of this article.


Example

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;
}


To create a dynamic library so that we could share and reuse all the custom math functions with other programs; 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;
}



Create Dynamic Library

In Mac OS X, you can create dynamic library using the command gcc or clang or libtool

Library Naming Convention
The naming convention is a little different in Mac OS X. The library is prefix with lib and end with extension .dylib. Before the extension you can put in major release and minor release. The major release can be an alphabet or a number.

An example would be libmymath.A.dylib or libmymath.1.dylib or libmymath.I.dylib.

You can also specify the minor revision which should be after the major version symbol. Alternatively, you can specify it during compilation.


Compiling a Dynamic Library
Use the following command to create a dynamic library instead of executable:

If you have only one C implementation program for the library use the command: 
gcc -dynamiclib libmymath.c -o libmymath.1.dylib -current_version 1.0 -compatibility_version 1.0
or
clang -dynamiclib libmymath.c -o libmymath.1.dylib -current_version 1.0 -compatibility_version 1.0

If you have more than one C implementation program, use the following:
gcc -dynamiclib libmymath1.c libmymath2.c -o libmymath.1.dylib -current_version 1.0 -compatibility_version 1.0
or
clang -dynamiclib libmymath1.c libmymath2.c -o libmymath.1.dylib -current_version 1.0 -compatibility_version 1.0

If you do not have the C implementation program file with you, you can also use libtool to create the dynamic library from object file:
libtool -dynamic libmymath1.o libmymath2.o -o libmymath.1.dylib -current_version 1.0 -compatibility_version 1.0

Note:
The standard location for dynamic library is at /usr/lib.
The standard location for header file is at /usr/include.

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;
 
}


Compile The Application
The command to compile the application program is as follows:
gcc -Wall -g app1.c -o app1 libmymath.1.dylib
or  
clang app1.c -o app1 libmymath.1.dylib 

Options:
-g is to produce debugging information

If your dynamic library is already located some where in the system. Use the following command and indicate the full path of the library location:
gcc -Wall -g app1.c -o app1 /usr/lib/libmymath.1.dylib
or  
clang app1.c -o app1 /usr/lib/libmymath.1.dylib 

Note:
Please note that in Max OS X the linker ld is use with dyld, gcc is the symbolic link to llvm-gcc.

Library Tools
To check the library dependencies of a particular application program use the command otool
otool -L app1

The system will return libmymath.1.dylib (compatibility version 1.0.0, current version 1.0.0)

Special Note (Important)

Please note that using dynamic libraries is a very complex operation. The above tutorial is to give you a simple idea about using dynamic library in the simplest form.

If you have more complex requirement such as exposing only some of the function in the program and hide internal function, you might need to use EXPORT in the C program file and use -fvisibility=hidden during compilation. There are many issues to consider when there are multiple dependencies and multiple versions involved. You might also need to use dlopen command to open the dynamic library.

For more information pleaser refer to Mac Developer Guide on Dynamic Library Programming.


*****

No comments:

Post a Comment

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