[Contents] [Prev. Chapter] [Next Section] [Next Chapter] [Index] [Help]

8    Postmigration Programming Features

After you migrate your source code from an ULTRIX to a DIGITAL UNIX system, you might want to enhance it by using features of the DIGITAL UNIX system. This chapter gives an overview of using three DIGITAL UNIX features: shared libraries, semaphores, and the number of open file descriptors.

For complete information on using DIGITAL UNIX features, see the Programmer's Guide.


[Contents] [Prev. Chapter] [Next Section] [Next Chapter] [Index] [Help]

8.1    Using Shared Libraries

Shared libraries allow several applications to use a single copy of a library routine at run time. Shared libraries help save disk space and memory, and they can improve the performance of your application and system.

Using DIGITAL UNIX shared libraries is similar to using archive libraries.

To link your application with a shared library, you must have compiled it on a DIGITAL UNIX system. Therefore, you must recompile and relink ULTRIX applications if you want them to use shared libraries.

This section describes how to use the cc command to link with a shared library. It also describes how to create shared libraries.

For complete information about using shared libraries, see the Programmer's Guide.


[Contents] [Prev. Chapter] [Prev. Section] [Next Section] [Next Chapter] [Index] [Help]

8.1.1    Linking with Shared Libraries

On DIGITAL UNIX systems, the cc command links your application with shared libraries by default. The following example shows the command you enter to link with the shared version of libc:

% cc -o hello hello.c

This command creates an executable file named a.out, which you run.

You can also link your application with a shared library that you create. For example, suppose you create a shared library named libspecial_math.so and store that library in the directory /usr/person. To link with that library, use the -l and -L options, as shown:

% cc -o hello hello.c -L/usr/person -lspecial_math

To link the application that does not use shared libraries, you must specify the -non_shared option in the cc command line, as shown:

% cc -non_shared -o hello hello.c -L/usr/person -lspecial_math

Although shared libraries are the default for most applications, the following applications cannot use them:


[Contents] [Prev. Chapter] [Prev. Section] [Next Section] [Next Chapter] [Index] [Help]

8.1.2    Symbol Resolution and Shared Libraries

If you link your application with shared libraries instead of archive libraries, you might notice some differences in the way symbols are resolved. This section describes these differences.


[Contents] [Prev. Chapter] [Prev. Section] [Next Section] [Next Chapter] [Index] [Help]

8.1.2.1    How Libraries Are Searched

The shared libraries supplied with DIGITAL UNIX systems are stored in the /usr/shlib directory. Place all system shared libraries in this directory to avoid confusion. When the linker searches for files that have been specified using the -l option, it searches the following directories, in order:

The linker searches all of the directories for a shared library (an .so file). If it does not find a shared library with the specified name, the linker searches all of the directories a second time for a static (an archive) library (an .a file).

When you develop applications, you might work with private shared libraries that are contained in directories other than the /usr/shlib directory. In this case, use the -L option to specify these directories. Before you execute the program, set the LD_LIBRARY_PATH environment variable to point to the directory containing the private shared libraries. When the program is executed, the run-time loader, /sbin/loader, examines this environment variable and searches the path, if defined, before searching the default list of directories.

Set the LD_LIBRARY_PATH variable in the following ways:

In the following examples, the /usr/person directory contains two versions of the special math library: libspecial_math.so is a shared library and libspecial_math.a is an archive library.

When you link with a shared library, symbols must be referenced before the linker searches the shared library. Otherwise, the linker does not find the symbol in the shared library and lists the symbol as undefined.

For example, suppose your library object file, libspecial_math.o, defines two functions, getvalue and setvalue. Suppose that you create a shared library, libspecial_math.so, and an archive library, libspecial_math.a, from the object file. You call the getvalue routine in the program1 module of your application, and you call the setvalue routine in the program2 module of your application.

Suppose you link your application using the archive library, as follows:

% cc -non_shared program1.o -lspecial_math program2.o

The application module program1 references the getvalue routine, which the libspecial_math archive library defines. That library also defines the setvalue routine, and the linker is able to define setvalue when it encounters that symbol in the program2 module.

Now, suppose you enter the same command, but use the shared library instead of the archive library:

% cc program1.o -lspecial_math program2.o

This command succeeds, but prints a warning message indicating that the symbol is undefined.

To correctly link this application, enter the following command:

% cc program1.o program2.o -lspecial_math

In general, always specify the -l option last in the command line.


[Contents] [Prev. Chapter] [Prev. Section] [Next Section] [Next Chapter] [Index] [Help]

8.1.2.2    When Symbols Are Defined More than Once

Symbol name resolution when using shared libraries is similar to name resolution when using static libraries. Symbol names are resolved according to the order in which the object file or shared object containing the symbols appears on the command line. The linker typically takes the leftmost definition for any symbol that must be resolved.

The sequence in which names are resolved proceeds as if the link command line were stored in the executable. When the program runs, all referenced symbols must be resolved. The program aborts if any undefined symbols are referenced.

When you link your application with shared libraries, do not define the same symbol twice. For example, you cannot use the following cc command to link an application that contains a shared library:

% cc program1.o libspecial_math.so program2.o libspecial_math.a

This command succeeds, but prints warning messages indicating that a symbol is defined multiple times.


[Contents] [Prev. Chapter] [Prev. Section] [Next Section] [Next Chapter] [Index] [Help]

8.1.3    Using Your Makefile with Shared Libraries

If you use the make command to build your ULTRIX application, you can use it to build a DIGITAL UNIX application that uses shared libraries. You need not modify your makefile file to use it with shared libraries. Unlike ULTRIX systems, linking with shared libraries is the default on DIGITAL UNIX systems.

The following example shows a Makefile file that links with shared libraries on a DIGITAL UNIX system:

# Makefile for the Math Program
all: math.h program1.o program2.o
  cc program1.o program2.o -L/usr/person -lspecial_math
program1.o: project.h
  cc -c program1.c


[Contents] [Prev. Chapter] [Prev. Section] [Next Section] [Next Chapter] [Index] [Help]

8.1.4    Creating Shared Libraries from Object Files

To create a shared library:

  1. Create one or more source files that define the routines you want to include in the library.

  2. Compile the source file into an object file, as shown:

    % cc -c special_math.c
    

  3. Create the library by using the ld command. (You cannot use the cc command to create a shared library. You must invoke the ld command directly.) The following shows a sample ld command:

    % ld -shared -no_archive -o libspecial_math.so special_math.o -lc
    

    In this example, the -shared option specifies creating a shared (rather than an archive) library. The -no_archive option tells the linker to resolve all symbols from shared libraries only. The -o option specifies the name of the shared library.

    For this command to succeed without printing warning messages, all symbols in the special_math.o object must be resolved. In this case, the special_math.o object references symbols that are defined in libc. The -lc option specifies that ld search libc to resolve those symbols. The ld linker searches the /usr/shlib directory for libc, by default.

    If the shared library you are creating references symbols defined in another shared library, you must name the other shared library in the ld command line. Name the shared library last in the command line to ensure that the linker encounters the reference to the symbol before it encounters the definition of the symbol.

For more information on using ld to create shared libraries, see ld(1).


[Contents] [Prev. Chapter] [Prev. Section] [Next Section] [Next Chapter] [Index] [Help]

8.1.5    Creating Shared Libraries from Archive Libraries

You can also create a shared library from an existing static (archive) library by using the ld command. The following example converts the static library, old.a, into the shared library, libold.so:

% ld -shared -no_archive -o libold.so -all old.a -none -lc

In this example, the -all option tells the linker to link all objects from the old.a archive library. The -none option tells the linker to turn off the -all option. The -no_archive option applies to the resolution of the -lc option, but not to old.a, since it is explicitly mentioned.


[Contents] [Prev. Chapter] [Prev. Section] [Next Section] [Next Chapter] [Index] [Help]

8.1.6    Optimizing Application Startup when Using Shared Libraries

Your application starts more efficiently if your shared libraries can be loaded at a preassigned starting address in virtual memory. To allow this efficiency, the ld linker preassigns a starting address to each shared library you create.

At application startup time, a shared library's preassigned starting address may already be in use. In this case, the system assigns a new starting address to the library and the advantage of the preassigned starting address is lost.

To make it more likely that a shared library can use its preassigned starting address, you can cause the ld linker to assign a unique starting address to each shared library you create.

If you create a shared library that only you will use, use the -check_registry option in the ld command line. This option causes ld to search the file you specify to determine what starting addresses are assigned to shared libraries. The linker then assigns an unused starting address to your shared library. The following example shows how to use the -check_registry option:

% ld -shared -no_archive -check_registry \
/usr/shlib/so_locations \
libspecial_math.so special_math.o -lc

If the shared library you create will be used by other programmers on your system, use the -update_registry option. This option causes the ld linker to search the file you specify to determine what starting addresses are assigned to shared libraries. The linker then assigns an unused starting address to your shared library. The linker then adds to the file the information that your shared library has been assigned that starting address. Because that information is stored in the file, the linker can determine that the address is already assigned when it assigns a starting address to other shared libraries.

If no -check_registry or -update_registry option is specified when building a shared library, the linker defaults to the -update_registry option and the ./so_locations file.

The following list describes the procedure you follow to use the -update_registry option with the system's /usr/shlib/so_locations file:

  1. Copy the system's so_locations file to your local area:

    % cp /usr/shlib/so_locations .
    

  2. Give yourself write access to the file:

    % chmod +w so_locations
    

  3. Create the shared library and use the -update_registry option:

    % ld -shared -no_archive -update_registry \
    ./so_locations -o libspecial_math.so \
    special_math.o -lc
    

  4. Move the so_locations file back to the /usr/shlib directory:

    % mv /home/smith/so_locations /usr/shlib/so_locations
    

    You must have write privileges to the /usr/shlib directory to move the so_locations file into it. If you cannot write to the directory, ask your system administrator to move the file.


[Contents] [Prev. Chapter] [Prev. Section] [Next Section] [Next Chapter] [Index] [Help]

8.2    Using Semaphores

On an ULTRIX system, you use semaphores through the atomic_op call. This call allows you to test and set a user-space address that you specify. The DIGITAL UNIX system contains the atomic_op call; however, the system also includes library routines that perform semaphore operations.

Modify your source code to use the DIGITAL UNIX library routines rather than the atomic_op system call. The library routines are more portable than the atomic_op system call, which might not be included in all DIGITAL UNIX systems. The library routines are also more powerful than the atomic_op system call.

The DIGITAL UNIX library routines are as follows:

For more information about these routines, see msem_init(3), msem_lock(3), msem_unlock(3), and msem_remove(3).


[Contents] [Prev. Chapter] [Prev. Section] [Next Chapter] [Index] [Help]

8.3    Using File Descriptors

On both the ULTRIX and UWS and the DIGITAL UNIX systems, the number of open file descriptors a process can use is configurable. By default, the number for DIGITAL UNIX systems is 4096; on ULTRIX systems the default is 64. Your system administrator configures the number of open file descriptors. For information about configuring this number, see the System Administration manual.

Because the system administrator can configure the maximum number of open file descriptors your processes can use, you might want to modify your program before you recompile it on a DIGITAL UNIX system. The following list describes the changes needed:


[Contents] [Prev. Chapter] [Prev. Section] [Next Chapter] [Index] [Help]