Sunday, July 17, 2011

Programming with Libraries - (static/dynamic)

In computing, a library is a collection of similar objects that are stored for occasional use - most frequently, programs in source code or object code form, data files, scripts, templates, fonts, and physical storage units such as tape cartridges. Here are some common types of libraries that a programmer can "call" when writing code so that the programmer doesn't have to write it.

Benefits of using Libraries
  • First, they provide a way to share code among several applications. If you have such code, you can create a library with it and link the library with any application that needs it.  
  • Second, libraries provide a way to reduce the complexity of very large applications. Such applications can build and maintain relatively independent portions as libraries and so reduce the burden on programmers working on other portions.
Building a library simply means creating .o files (by compiling your code with the -c option) and combining the .o files into a library using the gcc/c++ command. You can build two kinds of libraries, static (archive) libraries and dynamic (shared) libraries.
Types of the Libraries 
  • static library (also known as an archive) consists of routines that are compiled and linked directly into your program. When you compile a program that uses a static library, all the functionality of the static library becomes part of your executable. On Windows, static libraries typically have a .lib extension, whereas on linux, static libraries typically have an .a (archive) extension. One advantage of static libraries is that you only have to distribute the executable in order for users to run your program. Because the library becomes part of your program, this ensures that the right version of the library is always used with your program. Also, because static libraries become part of your program, you can use them just like functionality you’ve written for your own program. On the downside, because a copy of the library becomes part of every executable that uses it, this can cause a lot of wasted space. Static libraries also can not be upgraded easy — to update the library, the entire executable needs to be replaced. With static (archive) libraries, objects within the library are linked into the program’s executable file at link time. Only those .o files from the library that are needed by the application are linked into the executable. The name of a static (archive) library generally ends with a .a suffix.
  • dynamic library (also called a shared library) consists of routines that are loaded into your application at run time. When you compile a program that uses a dynamic library, the library does not become part of your executable — it remains as a separate unit. On Windows, dynamic libraries typically have a .dll (dynamic link library) extension, whereas on Linux, dynamic libraries typically have a .so (shared object) extension. One advantage of dynamic libraries is that many programs can share one copy, which saves space. Perhaps a bigger advantage is that the dynamic library can be upgraded to a newer version without replacing all of the executables that use it. With dynamic (shared) libraries, objects within the library are not linked into the program’s executable file, but rather the linker notes in the executable that the program depends on the library. When the program is executed, the system loads the dynamic libraries that the program requires. If two programs that use the same dynamic library execute at the same time, the operating system shares the library among the programs. The name of a dynamic (shared) library ends with a .so suffix. 
Linking dynamically with shared libraries has several advantages over linking statically with archive libraries: 
  • The size of the executable is smaller 
  • Significant portions of code can be shared among programs at runtime, reducing the amount of memory use. 
  • The library can be replaced at runtime without relinking with the application. (This is the primary mechanism that enables programs to take advantage of many improvements in the Solaris operating system without requiring relinking and redistribution of programs.) 
  • The shared library can be loaded at runtime, using the dlopen() function call.
However, dynamic libraries have some disadvantages: 
  • Runtime linking has an execution-time cost. 
  • Distributing a program that uses dynamic libraries might require simultaneous distribution of the libraries it uses. 
  • Moving a shared library to a different location can prevent the system from finding the library and executing the program. (The environment variable LD_LIBRARY_PATH helps overcome this problem.)
Up to now these are the basics of the libraries, static and dynamic and both. Now we will see the steps required to build the static and the dynamic libraries.

Building the static libraries:

The mechanism for building static (archive) libraries is similar to that of building an executable. A collection of object (.o) files can be combined into a single library using the– GNU ar program.
You should build static (archive) libraries using gcc -ar instead of using the ar command directly. The C++ language generally requires that the compiler maintain more information than can be accommodated with traditional .o files, particularly template instances. The – ar option ensures that all necessary information, including template instances, is included in the library. You might not be able to accomplish this in a normal programming environment since make might not know which template files are actually created and referenced. Without c++ -ar, referenced template instances might not be included in the library, as required. For example:

[sgupta@rhel55x86 static]$ c++ -c MyCode.cpp
[sgupta@rhel55x86 static]$ c++ -ar -o libMyCode.a libMyCode.o.

Following two steps are doing the following things,

1.  C++ -c MyCode.cpp # Compile main file, templates objects are created.
2.  C++ -ar -o libMyCode.a libMyCode.o # Gather all objects into a library.

The –ar flag causes gcc to create a static (archive) library. The– o directive is required to name the newly created library. The compiler examines the object files on the command line, cross-references the object files with those known to the template repository, and adds those templates required by the user’s object files (along with the main object files themselves) to the archive.

Note –
Use the -ar flag for creating or updating an existing archive only. Do not use it to maintain an archive. The -ar option is equivalent to ar -cr.

It is a good idea to have only one function in each .o file. If you are linking with an archive, an entire .o file from the archive is linked into your application when a symbol is needed from that particular .o file. Having one function in each .o file ensures that only those symbols needed by the application will be linked from the archive.

Building the Dynamic (shared) libraries:

Dynamic (shared) libraries are built the same way as static (archive) libraries, except that you use– G instead of– xar on the command line.
You should not use ld directly. As with static libraries, the gcc command ensures that all the necessary template instances from the template repository are included in the library if you are using templates. All static constructors in a dynamic library that is linked to an application are called before main() is executed and all static destructors are called after main() exits. If a shared library is opened using dlopen(), all static constructors are executed at dlopen() and all static destructors are executed at dlclose().
You should use c++ -g to build a dynamic library. When you use ld (the link-editor) or gcc (the C compiler) to build a dynamic library, exceptions might not work and the global variables that are defined in the library are not initialized.
To build a dynamic (shared) library, you must create relocatable object files by compiling each object with the– Kpic or– KPIC option of gcc. You can then build a dynamic library with these relocatable object files. If you get any bizarre link failures, you might have forgotten to compile some objects with -fPIC.
To build a C++ dynamic library named that contains objects from source files lsrc1.cpp and lsrc2.cpp, type:

[sgupta@rhel55x86 static]$ c++ -c MyCode.cpp
[sgupta@rhel55x86 static]$ c++ -shared -Wl,-soname -lc -g -o MyCode.o -L.

The - fPIC option specifies that the object files are to be position-independent.

No comments:

Post a Comment