[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
gnatbind
This chapter describes the GNAT binder, gnatbind
, which is used
to bind compiled GNAT objects. The gnatbind
program performs
four separate functions:
gnatlink
utility used to link the Ada application.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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~ada_main.ads', and
`b~ada_main.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 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
gnatgcc
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:
gnatgcc -c hello.adb
to compile the main program.
gnatgcc -c p.ads
to compile package P
.
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 it is similar to the following (when using -C):
extern int gnat_argc; extern char **gnat_argv; extern char **gnat_envp; extern int gnat_exit_status; void adafinal (); void adainit () { __gnat_set_globals ( -1, /* Main_Priority */ -1, /* Time_Slice_Value */ ' ', /* Locking_Policy */ ' ', /* Queuing_Policy */ ' ', /* Tasking_Dispatching_Policy */ adafinal); system___elabs (); /* system__standard_library___elabs (); */ /* system__task_specific_data___elabs (); */ /* system__tasking_soft_links___elabs (); */ system__tasking_soft_links___elabb (); /* system__task_specific_data___elabb (); */ /* system__standard_library___elabb (); */ /* m___elabb (); */ } void adafinal () { } int main (argc, argv, envp) int argc; char **argv; char **envp; { gnat_argc = argc; gnat_argv = argv; gnat_envp = envp; __gnat_initialize(); adainit(); _ada_m (); adafinal(); __gnat_finalize(); exit (gnat_exit_status); } unsigned mB = 0x2B0EB17F; unsigned system__standard_libraryB = 0x0122ED49; unsigned system__standard_libraryS = 0x79B018CE; unsigned systemS = 0x08FBDA7E; unsigned system__task_specific_dataB = 0x6CC7367B; unsigned system__task_specific_dataS = 0x47178527; unsigned system__tasking_soft_linksB = 0x5A75A73C; unsigned system__tasking_soft_linksS = 0x3012AFCB; /* BEGIN Object file/option list ./system.o ./s-tasoli.o ./s-taspda.o ./s-stalib.o ./m.o END Object file/option list */ |
The call to __gnat_set_globals
establishes program parameters,
including the priority of the main task, and parameters for tasking
control. It also passes the address of the finalization routine so
that it can be called at the end of program execution.
Next there is code to save the argc
and argv
values for
later access by the Ada.Command_Line
package. The variable
gnat_exit_status
saves the exit status set by calls to
Ada.Command_Line.Set_Exit_Status
and is used to return an exit
status to the system.
The call to __gnat_initialize
and the corresponding call at the
end of execution to __gnat_finalize
allow any specialized
initialization and finalization code to be hooked in. The default
versions of these routines do nothing.
The calls to xxx___elabb
and
xxx___elabs
perform necessary elaboration of the bodies and
specs respectively of units in the program. These calls are commented
out if the unit in question has no elaboration code.
The call to
m
is the call to the main program.
The list of unsigned constants gives the version number information.
Version numbers are computed by combining time stamps of a unit and all
units on which it depends. These values are used for implementation of
the Version
and Body_Version
attributes.
Finally, a set of comments gives the full names of all the object files that must be linked to provide 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. See section 4.5 Output Control.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
As described in the previous section, 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
-x
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] | [ ? ] |
The following switches provide control over the generation of error messages from the binder:
-v
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
stderr
even if verbose mode is
specified. This is relevant only when used with the
-v
switch.
-mn
-Mxxx
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
-we
-t
-t
should be used only in unusual situations,
with extreme care.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following switches provide additional control over the elaboration order. For full details see See section 9. Elaboration Order Handling in GNAT.
-f
Elaborate_All
pragmas, and to use full Ada 95 Reference
Manual semantics in an attempt to find a legal elaboration order,
even if it seems likely that this order will cause an elaboration
exception.
-p
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.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following switches allow additional control over the output generated by the binder.
-A
-o
gnatbind
option.
-C
-o
gnatbind
option.
-e
stdout
.
-h
stdout
.
-l
stdout
.
-O
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
-c
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
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
adainit
is
required before the first call to an Ada subprogram.
adafinal
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\/OUTPUT=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.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following are the switches available with gnatbind
:
-aO
-aI
-A
-b
stderr
even if verbose mode set.
-c
-C
-e
-E
gnatgcc
flag -funwind-tables
when
compiling every file in your application. See also the packages
GNAT.Traceback
and GNAT.Traceback.Symbolic
-f
-h
-I
-I-
gnatbind
was
invoked, and do not look for ALI files in the directory containing the
ALI file named in the gnatbind
command line.
-l
-Mxyz
-mn
-n
-nostdinc
-nostdlib
-o file
-O
-p
-s
-static
-shared
-t
-Tn
-v
stdout
.
-wx
-x
-z
You may obtain this listing by running the program gnatbind
with
no arguments.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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] | [ ? ] |
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 gnatgcc
(see section 3.3 Search Paths and the Run-Time Library (RTL)). For ALI files the
directories searched are:
-I-
is specified.
-I
switches on the gnatbind
command line, in the order given.
ADA_OBJECTS_PATH
environment variable.
Construct this value
exactly as the PATH
environment variable: a list of directory
names separated by colons.
-nostdlib
is specified.
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] | [ ? ] |
gnatbind
Usage
This section contains a number of examples of using the GNAT binding
utility gnatbind
.
gnatbind hello
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
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
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
gnatbind -n math dbase -C -o ada-control.c
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] | [ ? ] |