Chapter 2. Binding with gnatbind

Table of Contents
2.1. Running gnatbind
2.2. Consistency-Checking Modes
2.3. Binder Error Message Control
2.4. Elaboration Control
2.5. Output Control
2.6. Binding for Non-Ada Main Programs
2.7. Summary of Binder Switches
2.8. Search Paths for gnatbind
2.9. Examples of gnatbind Usage

This chapter describes the XGC Ada binder, gnatbind, which is used to bind compiled XGC Ada objects. The gnatbind program performs four separate functions:

  1. Checks that a program is consistent, in accordance with the rules in Chapter 10 of the Ada 95 Reference Manual. In particular, error messages are generated if a program uses inconsistent versions of a given unit.

  2. Checks that an acceptable order of elaboration exists for the program and issues an error message if it cannot find an order of elaboration satisfying the rules in Chapter 10 of the Ada 95 Reference Manual.

  3. Generates a main program incorporating the given elaboration order. This program is a small C source file that must be subsequently compiled using the C compiler. The two most important functions of this program are to call the elaboration routines of units in an appropriate order and to call the main program.

  4. Determines the set of object files required by the given main program. This information is output as comments in the generated C program, to be read by the gnatlink utility used to link the Ada application.

2.1. Running gnatbind

The form of the gnatbind command is


$ prefix-gnatbind [switches] mainprog.ali [switches]

where mainprog.adb is the Ada file containing the main program unit body. If no switches are specified, gnatbind constructs a C file whose name is b_mainprog.c. For example, if given the parameter "hello.ali", for a main program contained in file hello.adb, the binder output file would be b_hello.c.

When doing consistency checking, the binder takes any source files it can locate into consideration. For example, if the binder determines that the given main program requires the package Pack, whose ALI file is pack.ali and whose corresponding source spec file is pack.ads, it attempts to locate the source file pack.ads (using the same search path conventions as previously described for the gcc command). If it can located this source file, the time stamps or source checksums must match. In other words, any ALI files mentioning this spec must have resulted from compiling this version of the source file (or in the case where the source checksums match, a version close enough that the difference does not matter).

The effect of this consistency checking, which includes source files, is that the binder ensures that the program is consistent with the latest version of the source files that can be located at bind time. Editing a source file without compiling files that depend on the source file cause error messages to be generated from the binder.

For example, suppose you have a main program hello.adb and a package P, from file p.ads and you perform the following steps:

  1. Enter gcc -c hello.adb to compile the main program.

  2. Enter gcc -c p.ads to compile package P.

  3. Edit file p.ads.

  4. Enter gnatbind hello.ali.

At this point, the file p.ali contains an out-of-date time stamp because the file p.ads has been edited. The attempt at binding fails, and the binder generates the following error messages:


error: "hello.adb" must be recompiled ("p.ads" has been modified)
error: "p.ads" has been modified and must be recompiled

Now both files must be recompiled as indicated, and then the bind can succeed, generating a main program. You need not normally be concerned with the contents of this file, but it is similar to the following:


int
main ()
{
  /* system___elabs (); */
  /* system__unsigned_types___elabs (); */
  /* io___elabs (); */
     io___elabb ();
  /* hello___elabb (); */
  _ada_hello ();
}
unsigned helloB = 0x31D2BFE2;
unsigned ioB = 0x1A691C13;
unsigned ioS = 0x75F3301D;
unsigned systemS = 0x3DBA2639;
unsigned system__unsigned_typesS = 0x44A29692;

/* BEGIN Object file/option list
./io.o
./hello.o
-L./
-L/opt/.../lib/gcc-lib/prefix/2.8.1/adalib/
-lgnat
   END Object file/option list */

The list of unsigned constants gives the version number information. Version numbers are computed by combining all the characters from the source file, omitting blanks and characters in comments. These values are used for implementation of the Version and Body_Version attributes.

Finally, a set of comments gives full names of all the object files required to be linked for the Ada component of the program. As seen in the previous example, this list includes the files explicitly supplied and referenced by the user as well as implicitly referenced run-time unit files. The latter are omitted if the corresponding units reside in shared libraries. The directory names for the run-time units depend on the system configuration.