2.2. Compiling and linking: A quick overview

This section provides a quick overview for developers about compiling and linking on AIX.

2.2.1. Building C and C++ programs with system libraries

It is quite straightforward to build (compiling and linking) C and C++ programs with system libraries on AIX. For example, to compile and link the very simple C program shown in Example 2-1, do the following:

$ cc helloworld.c

Example 2-1. helloworld.c
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("Hello World
");
    exit(0);
}

Then, the compiler driver[4] will generate an executable file in the current directory (if the executable file name is not specified with the -o option, the compiler driver uses the default executable file name a.out):

[4] Select the appropriate compiler driver as explained in 1.7.1, “Default compiler drivers” on page 30.

$ ls -l a.out
-rwx------   1  k5      k5          4429 Apr 09 16:18 a.out

If you execute the generated executable file, it prints the following output as expected:

$ ./a.out
Hello World

Internally, the compiler driver cc does the following processes in this example:

  1. Pick up the default compiler and linker options listed in /etc/vac.cfg (see Example 2-2), then invokes several internal programs.

  2. Generate an object file (in this example, the file name would be helloworld.o).

  3. Invoke the linker, ld, and it links the object file with default libraries listed in /vac/vac.cfg, in order to generate the executable file, a.out.

  4. Remove the object file helloworld.o and temporary files.

Example 2-2. The cc compiler driver stanza in /etc/vac.cfg
* C compiler, extended mode
cc:     use        = DEFLT
    crt        = /lib/crt0.o
    mcrt       = /lib/mcrt0.o
    gcrt       = /lib/gcrt0.o
    libraries  = -L/usr/lpp/xlopt,-lxlopt,-lc
    proflibs   = -L/lib/profiled,-L/usr/lib/profiled
    options    = -qlanglvl=extended,-qnoro,-qnoroconst

These internal processes are shown if the -v compiler option is specified, as shown in the following example:

$ cc -v helloworld.c
exec:
/usr/vac/exe/xlcentry(/usr/vac/exe/xlcentry,-D_AIX,-D_AIX32,-D_AIX41,-D_AIX43,-
D_AIX50,-D_AIX51,-D_AIX52,-D_IBMR2,-D_POWER,-qlanglvl=extended,-qnoro,-qnorocon
st,-ohelloworld.o,helloworld.c,/tmp/xlcW0m.58Ea,/tmp/xlcW1m.58Eb,/dev/null,hell
oworld.lst,/dev/null,/tmp/xlcW2m.58Ec,NULL)
exec:
/usr/vac/exe/xlCcode(/usr/vac/exe/xlCcode,-qlanglvl=extended,-qnoro,-qnoroconst
,/tmp/xlcW0m.58Ea,/tmp/xlcW1m.58Eb,helloworld.o,helloworld.lst,/tmp/xlcW2m.58Ec
,NULL)
exec:
/bin/ld(/bin/ld,-b32,/lib/crt0.o,-bpT:0x10000000,-bpD:0x20000000,helloworld.o,-
L/usr/lpp/xlopt,-lxlopt,-lc,NULL)
unlink: helloworld.o
unlink: /tmp/xlcW0m.58Ea
unlink: /tmp/xlcW1m.58Eb
unlink: /tmp/xlcW2m.58Ec

Specifying a library name with the -l linker option

If your program needs to be linked with system libraries other than libc.a, specify the library name using the -l linker option.

Note

The standard C library, libc.a, is defined in the compiler driver stanza as an automatically linked library in /etc/vac.cfg, as highlighted in Example 2-2 on page 44. Therefore, you do not have to specify the -lc option in most cases.


For example, the following example shows you how to link a user program, foo.c, with the system provided mathematical library, /usr/lib/libm.a:

$ cc foo.c -lm

If the -l linker option is used, the linker treats it as a part of a library name. In this example, the linker automatically adds “lib” in front of “m” and adds “.a” after “m”, in order to complete the library file name. This is a generic behavior of linker on most UNIX operating systems.

When searching libraries to resolve symbols, the linker always looks into two directories, /usr/lib and /lib[5], where most system libraries are installed.

[5] The /lib directory is actually a symbolic link to the /usr/lib directory on AIX.

This option can be specified more than once in the same command line. In the following example, libabc.a and libdef.a will be searched from the /usr/lib or /lib directories to resolve symbols:

$ cc foo.c -labc -ldef

To find the appropriate system library name, which contains functions or variables you are going to use in your application, please consult the AIX 5L Version 5.2 Technical Reference: Base Operating System and Extensions.

2.2.2. Objects and libraries

Compilers normally generate an object file from an input program source file. The term object file is a generic term for a file containing executable code, data, relocation information, a symbol table, and other information. Objects files are defined by XCOFF[6] (eXtended Common Object File Format) on AIX. Multiple object files can be archived into a single library archive file, which is sometimes simply called library. The merit of creating a library is that it is easy to handle a fewer number of library files than many object files. Once a library is created from several object files, you can erase those object files, as long as the program source files are kept.

[6] For the complete definition of XCOFF, refer to the AIX 5L Version 5.2 Files Reference.

For example, assuming that there are three C program source files, foo1.c, foo2.c, and foo3.c, in the current directory, to generate object files from these source files, do the following:

$ cc -c foo1.c foo2.c foo3.c

The cc compiler driver would generate three object files as follows:

$ ls *.o
foo1.o  foo2.o  foo3.o

To archive them into a library, named libfoo.a, do the following:

$ ar -vq lifoo.a foo1.o foo2.o foo3.o
ar: Creating an archive file lifoo.a.
q - foo1.o
q - foo2.o
q - foo3.o

Note

If the libfoo.a library does not exist, this command creates it and enters copies of the files foo1.o, foo2.o, and foo3.o into it. If the libfoo.a library does exist, then this command adds the new members to the end of the library archive without checking for duplicate members. The -v option sets verbose mode, in which the ar command displays progress reports as it proceeds.


Figure 2-2 on page 50 illustrates these processes to create a library.

Figure 2-1. Object files and a library archive


Figure 2-2. Compiling and linking


Once the library is created, it can be maintained using the ar command as follows:

  • To list the table of contents of a library, enter:

    ar -v -t libfoo.a
    

    This command lists the table of contents of the libfoo.a library, displaying a long listing similar to the output of the ls -l command. To list only the member file names, omit the -v option.

  • To replace or add new members to a library, enter:

    ar -v -r libfoo.a foo1.o foo4.o
    

    This command replaces the foo1.o member and adds foo4.o to the end of the library.

  • To update a member that has been changed, enter:

    ar -v -r -u libfoo.a foo2.o
    

    This command replaces the existing foo2.o member, but only if the foo2.o file has been modified since it was last added to the library.

  • To extract library members, enter:

    ar -v -x libfoo.a foo1.o foo3.o
    

    This command copies the foo1.o and foo3.o members into individual files named foo1.o and foo3.o, respectively.

  • To delete a member, enter:

    ar -v -d libfoo.a foo2.o
    

    This command deletes the foo2.o member from the libfoo.a library.

Note

The object files and libraries explained in this section are static (non-shared). Shared object files and libraries must be created and treated by specific ways, as explained in 2.8, “Creating shared objects” on page 92.


For further information about the usage of the ar command, please consult with AIX 5L Version 5.2 Reference Documentation: Commands Reference.

32- and 64-bit objects

As explained in 2.1, “32- and 64-bit development environments” on page 38, AIX provides two different development environments: 32- and 64-bit. Therefore, object files on AIX have two different bit modes: 32-bit object files and 64-bit object files. To build executable files, all the participated object files and archive members must be in the same bit mode, either 32 or 64.

To distinguish the bit mode of object files, use the file command as follows:

$ file *.o
foo2.o:      executable (RISC System/6000) or object module not stripped
foo3.o:      executable (RISC System/6000) or object module not stripped
foo4.o:      64-bit XCOFF executable or object module not stripped

In this example, foo4.o is a 64-bit object, whereas foo2.o and foo3.o are 32-bit.

Hybrid mode library archives

A library archive can contain both the 32- and 64-bit object modules as its members on AIX. This is called a hybrid mode library archive. In fact, most system libraries provided by AIX are hybrid mode.

As explained in 2.1.3, “Utility commands support” on page 42, utility commands that deal with object files, such as ar, dump, and nm, have been enhanced with the -X option in order to support the 64-bit XCOFF format object format.

For example, to list only 64-bit object modules contained in the standard C library, libc.a, do the following:

$ ar -X 64 -t /usr/lib/libc.a
frexp_64.o
itrunc_64.o
ldexp_64.o
modf_64.o
logb_64.o
scalb_64.o
finite_64.o
... rest of output is omitted on purpose ...

If you omit the -X 64 option, or specify -X 32, the command lists only 32-bit object modules contained in libc.a. If -X 32_64 is specified, the command lists both 32- and 64-bit object modules.

To determine if the functions you require are provided in 64-bit, use the nm command. The mathematical library (libm.a) provided by AIX supports both a 32-bit and a 64-bit version of the acos() sub-routine in the following example output[7]:

[7] The -g option instructs the nm command to handle all archive members contained in the specified library archive.

$ nm -X 32 -g /usr/lib/libm.a | head -5
/usr/lib/libm.a[acos.o]:
._Errno              U           -
.acos                T           0
acos                 D         704      12
guesses              U           -
$ nm -X 64 -g /usr/lib/libm.a | head -7
/usr/lib/libm.a[acos_64.o]:
._Errno              U           -
._restf27            U           -
._savef26            U           -
.acos                T           0
acos                 D         744      24
guesses              U           -

2.2.3. Difference between shared object and library on AIX

If you are already familiar with other UNIX operating systems, there is nothing to be explained in the simple example used in 2.2.1, “Building C and C++ programs with system libraries” on page 43. However, it is worth mentioning that the program is linked with system provided several libraries, as shown in the following ldd[8] command output:

[8] See 2.7.3, “ldd” on page 90 for further information about the ldd command.

$ ldd ./a.out
./a.out needs:
         /usr/lib/libc.a(shr.o)
         /unix
         /usr/lib/libcrypt.a(shr.o)
					

The two system libraries, libc.a and libcrypt.a, are needed by the executable file and they both contain a shared object, named shr.o; in other words, these two objects are dependent modules of the executable file. Although both libraries coincidently contain the same name object file in this case, the two shared objects with the same name shr.o are different modules. Most system libraries provided by AIX contain one or more shared objects.

Figure 2-2 illustrates the compile and link processes of our example program and references to shared objects contained in system libraries.

As shown in the following genkld[9] command output, there are three shared object modules loaded into the system global memory from the libc.a system library on our test system:

[9] The genkld command is used to list already loaded shared objects into the system memory. See 2.7.2, “genkld” on page 88 for further information about this command.

$ genkld | grep 'libc.a'
        d2023070             1df /usr/lib/libc.a/dl.o
        d012cd7a             1da /usr/lib/libc.a/pse.o
        d01cfbe0          1e6257 /usr/lib/libc.a/shr.o

Although, our example program shown in Example 2-1 on page 43 needs only shr.o out of libc.a, the other two have been loaded since other programs needed them.

In fact, this is the marked difference between AIX and other UNIX operating systems. On other UNIX operating systems, shared libraries (also often referred to as dynamic link libraries or DLL) are actually shared objects, whereas multiple shared objects can be contained in a single library on AIX.[10]

[10] Technically, a shared object contained in a shared library archive is referred to as an archive member that has been archived into the library from a separate object file with SHROBJ.

The terms, shared library and shared object, are generally used interchangeably on other UNIX operating systems, whereas there is a distinct difference between the two terms on AIX:

Shared objectA shared object is a single object file that has the SHROBJ flag in the XCOFF header (see Example 2-3 on page 52). A shared object normally has a name of the form name.o on AIX. This is the default file name extension generated by compilers.
Shared libraryA shared library refers to an ar format archive library file[11], where one or more of the archive members is a shared object. Note that the library can also contain regular, non-shared object files, which are handled in the normal way by the linker. A shared library normally has a name of the form libname.a on AIX.

[11] An ar format archive file is a file that is created by the ar command.

The magic number of the file is used by the linker to determine whether the file is valid object file or not. Therefore, it is possible not to use .o as the file name extension for shared objects, though it could be misleading. As for library name naming convention (libname.a), it is strongly recommended to use it; otherwise the linker cannot find the library location if the -l option is used.

2.2.4. Difference between shared and static objects on AIX

The AIX linking and loading mechanism uses an unique file name convention for the shared and static object. On many UNIX operating systems, a shared object file normally has a file name extension “.so” (stands for shared object) and a static object file has normally a file name extension “.o” (stands for object).

However, an object normally has a file name extension “.o” regardless of shared or static on AIX. Therefore, you cannot determine whether an object is shared or regular static object from the file name extension on AIX.

Note

AIX also supports shared objects with a file name extension “.so” like other UNIX operating systems do, which are used for run-time linking (see 2.5, “Run-time linking” on page 68).


To determine whether the object file is shared or static, use the dump command. As highlighted in Example 2-3 on page 52, if the SHROBJ keyword is shown in the Flags line, then the object file is shared; otherwise, it is static.

Example 2-3. SHROBJ flag in the XCOFF header of a shared object
$ dump -ov shr.o

shr.o:

                        ***Object Module Header***
# Sections      Symbol Ptr      # Symbols       Opt Hdr Len     Flags
         5      0x00251764          26925                72     0x3002
Flags=( EXEC DYNLOAD SHROBJ )
Timestamp = "Feb 03 08:59:14 2003"
Magic = 0x1df  (32-bit XCOFF)

                        ***Optional Header***
Tsize       Dsize        Bsize       Tstart     Dstart
0x00171bc0 0x00045ae0   0x00045bc8  0x00000000 0x00000000

SNloader    SNentry      SNtext      SNtoc      SNdata
0x0004     0x0000       0x0001      0x0002     0x0002

TXTalign    DATAalign    TOC         vstamp     entry
0x0005     0x0003       0x00043ad0  0x0001     0xffffffff

maxSTACK    maxDATA      SNbss       magic      modtype
0x00000000 0x00000000   0x0003      0x010b       RE

To determine whether archive members in a library are shared or static, use the dump command with the -g option.[12] For example, the frexp.o archive member is static, whereas shr.o is shared in the /usr/lib/libc.a library, as shown in Example 2-4.

[12] The -g option instructs the dump command to examine archive members in the specified library.

Example 2-4. SHROBJ flag in the XCOFF header of archive members in a library
$ dump -gov /usr/lib/libc.a

/usr/lib/libc.a[frexp.o]:

                        ***Object Module Header***
# Sections      Symbol Ptr      # Symbols       Opt Hdr Len     Flags
         3      0x0000030c             34                28     0x0000
Flags=( )
Timestamp = "Sep 15 16:12:35 2002"
Magic = 0x1df  (32-bit XCOFF)

                       ***Optional Header***
Tsize        Dsize      Bsize       Tstart     Dstart
0x00000108  0x00000080 0x00000000  0x00000000 0x00000108
... many output lines are omitted on purpose ...
/usr/lib/libc.a[shr.o]:

                       ***Object Module Header***
# Sections     Symbol Ptr      # Symbols       Opt Hdr Len     Flags
         5     0x00250c0c          26913                72     0x3002
Flags=( EXEC DYNLOAD SHROBJ )
Timestamp = "Sep 19 00:14:43 2002"
Magic = 0x1df  (32-bit XCOFF)

                        ***Optional Header***
Tsize        Dsize       Bsize       Tstart      Dstart
0x00171360  0x00045a08  0x00045bb8  0x00000000  0x00000000

SNloader     SNentry     SNtext      SNtoc       SNdata
0x0004      0x0000      0x0001      0x0002      0x0002

TXTalign     DATAalign   TOC         vstamp      entry
0x0005      0x0003      0x00043a00  0x0001      0xffffffff

maxSTACK     maxDATA     SNbss       magic       modtype
0x00000000  0x00000000  0x0003      0x010b        RE
... rest of output is omitted on purpose ...

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset