[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4. Binding Using gnatbind

4.1 Running gnatbind  
4.2 Switches for gnatbind  
4.3 Command-Line Access  
4.4 Search Paths for gnatbind  
4.5 Examples of gnatbind Usage  

This chapter describes the GNAT binder, gnatbind, which is used to bind compiled GNAT 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 that satisfies the rules in Chapter 10 of the Ada 95 Language Manual.

  3. Generates a main program incorporating the given elaboration order. This program is a small Ada package (body and spec) that must be subsequently compiled using the GNAT compiler. The necessary compilation step is usually performed automatically by gnatlink. 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 in the forms of comments in the generated program, to be read by the gnatlink utility used to link the Ada application.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.1 Running gnatbind

The form of the gnatbind command is

 
$ 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 an Ada package in two files whose names are `b~mainprog.ads', and `b~mainprog.adb'. For example, if given the parameter `hello.ali', for a main program contained in file `hello.adb', the binder output files would be `b~hello.ads' and `b~hello.adb'.

When doing consistency checking, the binder takes into consideration any source files it can locate. 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 locate this source file, it checks that the time stamps or source checksums of the source and its references to in `ALI' files match. In other words, any `ALI' files that mentions 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 by 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.

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 for reference purposes a sample binder output file is given in B. Example of Binder Output File.

In most normal usage, the default mode of gnatbind which is to generate the main package in Ada, as described in the previous section. In particular, this means that any Ada programmer can read and understand the generated main program. It can also be debugged just like any other Ada code provided the `-g' switch is used for gnatbind and gnatlink.

However for some purposes it may be convenient to generate the main program in C rather than Ada. This may for example be helpful when you are generating a mixed language program with the main program in C. The GNAT compiler itself is an example. The use of the `-C' switch for both gnatbind and gnatlink will cause the program to be generated in C (and compiled using the gnu C compiler).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2 Switches for gnatbind

The following switches are available with gnatbind; details will be presented in subsequent sections.

4.2.1 Consistency-Checking Modes  
4.2.2 Binder Error Message Control  
4.2.3 Elaboration Control  
4.2.4 Output Control  
4.2.5 Binding with Non-Ada Main Programs  
4.2.6 Binding Programs with No Main Subprogram  

`-aO'
Specify directory to be searched for ALI files.

`-aI'
Specify directory to be searched for source file.

`-A'
Generate binder program in Ada (default)

`-b'
Generate brief messages to `stderr' even if verbose mode set.

`-c'
Check only, no generation of binder output file.

`-C'
Generate binder program in C

`-e'
Output complete list of elaboration-order dependencies.

`-E'
Store tracebacks in exception occurrences when the target supports it. This is the default with the zero cost exception mechanism. See also the packages GNAT.Traceback and GNAT.Traceback.Symbolic for more information. Note that on x86 ports, you must not use `-fomit-frame-pointer' gcc option.

`-F'
Force the checks of elaboration flags. gnatbind does not normally generate checks of elaboration flags for the main executable, except when a Stand-Alone Library is used. However, there are cases when this cannot be detected by gnatbind. An example is importing an interface of a Stand-Alone Library through a pragma Import and only specifying through a linker switch this Stand-Alone Library. This switch is used to guarantee that elaboration flag checks are generated.

`-h'
Output usage (help) information

`-I'
Specify directory to be searched for source and ALI files.

`-I-'
Do not look for sources in the current directory where gnatbind was invoked, and do not look for ALI files in the directory containing the ALI file named in the gnatbind command line.

`-l'
Output chosen elaboration order.

`-Lxxx'
Bind the units for library building. In this case the adainit and adafinal procedures (see section 4.2.5 Binding with Non-Ada Main Programs) are renamed to xxxinit and xxxfinal. Implies -n. (See section 19. GNAT and Libraries, for more details.)

`-Mxyz'
Rename generated main program from main to xyz

`-mn'
Limit number of detected errors to n, where n is in the range 1..999_999. The default value if no switch is given is 9999. Binding is terminated if the limit is exceeded. Furthermore, under Windows, the sources pointed to by the libraries path set in the registry are not searched for.

`-n'
No main program.

`-nostdinc'
Do not look for sources in the system default directory.

`-nostdlib'
Do not look for library files in the system default directory.

`--RTS=rts-path'
Specifies the default location of the runtime library. Same meaning as the equivalent gnatmake flag (see section 6.2 Switches for gnatmake).

`-o file'
Name the output file file (default is `b~xxx.adb'). Note that if this option is used, then linking must be done manually, gnatlink cannot be used.

`-O'
Output object list.

`-p'
Pessimistic (worst-case) elaboration order

`-s'
Require all source files to be present.

`-Sxxx'
Specifies the value to be used when detecting uninitialized scalar objects with pragma Initialize_Scalars. The xxx string specified with the switch may be either

In addition, you can specify `-Sev' to indicate that the value is to be set at run time. In this case, the program will look for an environment variable of the form GNAT_INIT_SCALARS=xx, where xx is one of `in/lo/hi/xx' with the same meanings as above. If no environment variable is found, or if it does not have a valid value, then the default is `in' (invalid values).

`-static'
Link against a static GNAT run time.

`-shared'
Link against a shared GNAT run time when available.

`-t'
Tolerate time stamp and other consistency errors

`-Tn'
Set the time slice value to n milliseconds. If the system supports the specification of a specific time slice value, then the indicated value is used. If the system does not support specific time slice values, but does support some general notion of round-robin scheduling, then any non-zero value will activate round-robin scheduling.

A value of zero is treated specially. It turns off time slicing, and in addition, indicates to the tasking run time that the semantics should match as closely as possible the Annex D requirements of the Ada RM, and in particular sets the default scheduling policy to FIFO_Within_Priorities.

`-v'
Verbose mode. Write error messages, header, summary output to `stdout'.

`-wx'
Warning mode (x=s/e for suppress/treat as error)

`-x'
Exclude source files (check object consistency only).

`-z'
No main subprogram.

You may obtain this listing of switches by running gnatbind with no arguments.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2.1 Consistency-Checking Modes

As described earlier, by default gnatbind checks that object files are consistent with one another and are consistent with any source files it can locate. The following switches control binder access to sources.

`-s'
Require source files to be present. In this mode, the binder must be able to locate all source files that are referenced, in order to check their consistency. In normal mode, if a source file cannot be located it is simply ignored. If you specify this switch, a missing source file is an error.

`-x'
Exclude source files. In this mode, the binder only checks that ALI files are consistent with one another. Source files are not accessed. The binder runs faster in this mode, and there is still a guarantee that the resulting program is self-consistent. If a source file has been edited since it was last compiled, and you specify this switch, the binder will not detect that the object file is out of date with respect to the source file. Note that this is the mode that is automatically used by gnatmake because in this case the checking against sources has already been performed by gnatmake in the course of compilation (i.e. before binding).


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2.2 Binder Error Message Control

The following switches provide control over the generation of error messages from the binder:

`-v'
Verbose mode. In the normal mode, brief error messages are generated to `stderr'. If this switch is present, a header is written to `stdout' and any error messages are directed to `stdout'. All that is written to `stderr' is a brief summary message.

`-b'
Generate brief error messages to `stderr' even if verbose mode is specified. This is relevant only when used with the `-v' switch.

`-mn'
Limits the number of error messages to n, a decimal integer in the range 1-999. The binder terminates immediately if this limit is reached.

`-Mxxx'
Renames the generated main program from main to xxx. This is useful in the case of some cross-building environments, where the actual main program is separate from the one generated by gnatbind.

`-ws'
Suppress all warning messages.

`-we'
Treat any warning messages as fatal errors.

`-t'
The binder performs a number of consistency checks including:

Normally failure of such checks, in accordance with the consistency requirements of the Ada Reference Manual, causes error messages to be generated which abort the binder and prevent the output of a binder file and subsequent link to obtain an executable.

The `-t' switch converts these error messages into warnings, so that binding and linking can continue to completion even in the presence of such errors. The result may be a failed link (due to missing symbols), or a non-functional executable which has undefined semantics. This means that `-t' should be used only in unusual situations, with extreme care.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2.3 Elaboration Control

The following switches provide additional control over the elaboration order. For full details see C. Elaboration Order Handling in GNAT.

`-p'
Normally the binder attempts to choose an elaboration order that is likely to minimize the likelihood of an elaboration order error resulting in raising a Program_Error exception. This switch reverses the action of the binder, and requests that it deliberately choose an order that is likely to maximize the likelihood of an elaboration error. This is useful in ensuring portability and avoiding dependence on accidental fortuitous elaboration ordering.

Normally it only makes sense to use the `-p' switch if dynamic elaboration checking is used (`-gnatE' switch used for compilation). This is because in the default static elaboration mode, all necessary Elaborate_All pragmas are implicitly inserted. These implicit pragmas are still respected by the binder in `-p' mode, so a safe elaboration order is assured.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2.4 Output Control

The following switches allow additional control over the output generated by the binder.

`-A'
Generate binder program in Ada (default). The binder program is named `b~mainprog.adb' by default. This can be changed with `-o' gnatbind option.

`-c'
Check only. Do not generate the binder output file. In this mode the binder performs all error checks but does not generate an output file.

`-C'
Generate binder program in C. The binder program is named `b_mainprog.c'. This can be changed with `-o' gnatbind option.

`-e'
Output complete list of elaboration-order dependencies, showing the reason for each dependency. This output can be rather extensive but may be useful in diagnosing problems with elaboration order. The output is written to `stdout'.

`-h'
Output usage information. The output is written to `stdout'.

`-K'
Output linker options to `stdout'. Includes library search paths, contents of pragmas Ident and Linker_Options, and libraries added by gnatbind.

`-l'
Output chosen elaboration order. The output is written to `stdout'.

`-O'
Output full names of all the object files that must be linked to provide the Ada component of the program. The output is written to `stdout'. 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.

`-o file'
Set name of output file to file instead of the normal `b~mainprog.adb' default. Note that file denote the Ada binder generated body filename. In C mode you would normally give file an extension of `.c' because it will be a C source program. Note that if this option is used, then linking must be done manually. It is not possible to use gnatlink in this case, since it cannot locate the binder file.

`-r'
Generate list of pragma Restrictions that could be applied to the current unit. This is useful for code audit purposes, and also may be used to improve code generation in some cases.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2.5 Binding with Non-Ada Main Programs

In our description so far we have assumed that the main program is in Ada, and that the task of the binder is to generate a corresponding function main that invokes this Ada main program. GNAT also supports the building of executable programs where the main program is not in Ada, but some of the called routines are written in Ada and compiled using GNAT (see section 2.10 Mixed Language Programming). The following switch is used in this situation:

`-n'
No main program. The main program is not in Ada.

In this case, most of the functions of the binder are still required, but instead of generating a main program, the binder generates a file containing the following callable routines:

adainit
You must call this routine to initialize the Ada part of the program by calling the necessary elaboration routines. A call to adainit is required before the first call to an Ada subprogram.

Note that it is assumed that the basic execution environment must be setup to be appropriate for Ada execution at the point where the first Ada subprogram is called. In particular, if the Ada code will do any floating-point operations, then the FPU must be setup in an appropriate manner. For the case of the x86, for example, full precision mode is required. The procedure GNAT.Float_Control.Reset may be used to ensure that the FPU is in the right state.

adafinal
You must call this routine to perform any library-level finalization required by the Ada subprograms. A call to adafinal is required after the last call to an Ada subprogram, and before the program terminates.

If the `-n' switch is given, more than one ALI file may appear on the command line for gnatbind. The normal closure calculation is performed for each of the specified units. Calculating the closure means finding out the set of units involved by tracing with references. The reason it is necessary to be able to specify more than one ALI file is that a given program may invoke two or more quite separate groups of Ada units.

The binder takes the name of its output file from the last specified ALI file, unless overridden by the use of the `-o file'. The output is an Ada unit in source form that can be compiled with GNAT unless the -C switch is used in which case the output is a C source file, which must be compiled using the C compiler. This compilation occurs automatically as part of the gnatlink processing.

Currently the GNAT run time requires a FPU using 80 bits mode precision. Under targets where this is not the default it is required to call GNAT.Float_Control.Reset before using floating point numbers (this include float computation, float input and output) in the Ada code. A side effect is that this could be the wrong mode for the foreign code where floating point computation could be broken after this call.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2.6 Binding Programs with No Main Subprogram

It is possible to have an Ada program which does not have a main subprogram. This program will call the elaboration routines of all the packages, then the finalization routines.

The following switch is used to bind programs organized in this manner:

`-z'
Normally the binder checks that the unit name given on the command line corresponds to a suitable main subprogram. When this switch is used, a list of ALI files can be given, and the execution of the program consists of elaboration of these units in an appropriate order.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.3 Command-Line Access

The package Ada.Command_Line provides access to the command-line arguments and program name. In order for this interface to operate correctly, the two variables

 
int gnat_argc;
char **gnat_argv;

are declared in one of the GNAT library routines. These variables must be set from the actual argc and argv values passed to the main program. With no `n' present, gnatbind generates the C main program to automatically set these variables. If the `n' switch is used, there is no automatic way to set these variables. If they are not set, the procedures in Ada.Command_Line will not be available, and any attempt to use them will raise Constraint_Error. If command line access is required, your main program must set gnat_argc and gnat_argv from the argc and argv values passed to it.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.4 Search Paths for gnatbind

The binder takes the name of an ALI file as its argument and needs to locate source files as well as other ALI files to verify object consistency.

For source files, it follows exactly the same search rules as gcc (see section 3.3 Search Paths and the Run-Time Library (RTL)). For ALI files the directories searched are:

  1. The directory containing the ALI file named in the command line, unless the switch `-I-' is specified.

  2. All directories specified by `-I' switches on the gnatbind command line, in the order given.

  3. Each of the directories listed in the text file whose name is given by the ADA_PRJ_OBJECTS_FILE environment variable.

    ADA_PRJ_OBJECTS_FILE is normally set by gnatmake or by the gnat driver when project files are used. It should not normally be set by other means.

  4. Each of the directories listed in the value of the ADA_OBJECTS_PATH environment variable. Construct this value exactly as the PATH environment variable: a list of directory names separated by colons (semicolons when working with the NT version of GNAT).

  5. The content of the `ada_object_path' file which is part of the GNAT installation tree and is used to store standard libraries such as the GNAT Run Time Library (RTL) unless the switch `-nostdlib' is specified. 19.2.2 Installing a library

In the binder the switch `-I' is used to specify both source and library file paths. Use `-aI' instead if you want to specify source paths only, and `-aO' if you want to specify library paths only. This means that for the binder `-I'dir is equivalent to `-aI'dir `-aO'dir. The binder generates the bind file (a C language source file) in the current working directory.

The packages Ada, System, and Interfaces and their children make up the GNAT Run-Time Library, together with the package GNAT and its children, which contain a set of useful additional library functions provided by GNAT. The sources for these units are needed by the compiler and are kept together in one directory. The ALI files and object files generated by compiling the RTL are needed by the binder and the linker and are kept together in one directory, typically different from the directory containing the sources. In a normal installation, you need not specify these directory names when compiling or binding. Either the environment variables or the built-in defaults cause these files to be found.

Besides simplifying access to the RTL, a major use of search paths is in compiling sources from multiple directories. This can make development environments much more flexible.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.5 Examples of gnatbind Usage

This section contains a number of examples of using the GNAT binding utility gnatbind.

gnatbind hello
The main program Hello (source program in `hello.adb') is bound using the standard switch settings. The generated main program is `b~hello.adb'. This is the normal, default use of the binder.

gnatbind hello -o mainprog.adb
The main program Hello (source program in `hello.adb') is bound using the standard switch settings. The generated main program is `mainprog.adb' with the associated spec in `mainprog.ads'. Note that you must specify the body here not the spec, in the case where the output is in Ada. Note that if this option is used, then linking must be done manually, since gnatlink will not be able to find the generated file.

gnatbind main -C -o mainprog.c -x
The main program Main (source program in `main.adb') is bound, excluding source files from the consistency checking, generating the file `mainprog.c'.

gnatbind -x main_program -C -o mainprog.c
This command is exactly the same as the previous example. Switches may appear anywhere in the command line, and single letter switches may be combined into a single switch.

gnatbind -n math dbase -C -o ada-control.c
The main program is in a language other than Ada, but calls to subprograms in packages Math and Dbase appear. This call to gnatbind generates the file `ada-control.c' containing the adainit and adafinal routines to be called before and after accessing the Ada units.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Mail Server on June, 15 2005 using texi2html