GNAT GPL User's Guide: Getting Started with GNAT

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

# 1. Getting Started with GNAT

This chapter describes some simple ways of using GNAT to build executable Ada programs. 1.1 Running GNAT, through 1.4 Using the `gnatmake` Utility, show how to use the command line environment. 1.5 Introduction to GPS, provides a brief introduction to the GNAT Programming Studio, a visually-oriented Integrated Development Environment for GNAT. GPS offers a graphical "look and feel", support for development in other programming languages, comprehensive browsing features, and many other capabilities. For information on GPS please refer to Using the GNAT Programming Studio.

> 1.1 Running GNAT |  |
> 1.2 Running a Simple Ada Program |  |
> 1.3 Running a Program with Multiple Units |  |
> 1.4 Using the `gnatmake` Utility |  |
> 1.5 Introduction to GPS |  |

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

## 1.1 Running GNAT

Three steps are needed to create an executable file from an Ada source file:

1. The source file(s) must be compiled.
2. The file(s) must be bound using the GNAT binder.
3. All appropriate object files must be linked to produce an executable.

All three steps are most commonly handled by using the `gnatmake` utility program that, given the name of the main program, automatically performs the necessary compilation, binding and linking steps.

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

## 1.2 Running a Simple Ada Program

Any text editor may be used to prepare an Ada program. (If `Emacs` is used, the optional Ada mode may be helpful in laying out the program.) The program text is a normal text file. We will assume in our initial example that you have used your editor to prepare the following standard format text file:

    with Ada.Text_IO; use Ada.Text_IO;
    procedure Hello is
    begin
       Put_Line ("Hello WORLD!");
    end Hello;

This file should be named ``hello.adb'`. With the normal default file naming conventions, GNAT requires that each file contain a single compilation unit whose file name is the unit name, with periods replaced by hyphens; the extension is ``ads'` for a spec and ``adb'` for a body. You can override this default file naming convention by use of the special pragma `Source_File_Name` (see section 2.4 Using Other File Names). Alternatively, if you want to rename your files according to this default convention, which is probably more convenient if you will be using GNAT for all your compilations, then the `gnatchop` utility can be used to generate correctly-named source files (see section 8. Renaming Files with `gnatchop`).

You can compile the program using the following command (`$` is used as the command prompt in the examples in this document):

    $ gcc -c hello.adb

`gcc` is the command used to run the compiler. This compiler is capable of compiling programs in several languages, including Ada and C. It assumes that you have given it an Ada program if the file extension is either ``.ads'` or ``.adb'`, and it will then call the GNAT compiler to compile the specified file.

The ``-c'` switch is required. It tells `gcc` to only do a compilation. (For C programs, `gcc` can also do linking, but this capability is not used directly for Ada programs, so the ``-c'` switch must always be present.)

This compile command generates a file ``hello.o'`, which is the object file corresponding to your Ada program. It also generates an "Ada Library Information" file ``hello.ali'`, which contains additional information used to check that an Ada program is consistent. To build an executable file, use `gnatbind` to bind the program and `gnatlink` to link it. The argument to both `gnatbind` and `gnatlink` is the name of the ``ALI'` file, but the default extension of ``.ali'` can be omitted. This means that in the most common case, the argument is simply the name of the main program:

    $ gnatbind hello
    $ gnatlink hello

A simpler method of carrying out these steps is to use `gnatmake`, a master program that invokes all the required compilation, binding and linking tools in the correct order. In particular, `gnatmake` automatically recompiles any sources that have been modified since they were last compiled, or sources that depend on such modified sources, so that "version skew" is avoided.

    $ gnatmake hello.adb

The result is an executable program called ``hello'`, which can be run by entering:

    $ hello

assuming that the current directory is on the search path for executable programs.

and, if all has gone well, you will see

    Hello WORLD!

appear in response to this command.

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

## 1.3 Running a Program with Multiple Units

Consider a slightly more complicated example that has three files: a main program, and the spec and body of a package:

    package Greetings is
       procedure Hello;
       procedure Goodbye;
    end Greetings;

    with Ada.Text_IO; use Ada.Text_IO;
    package body Greetings is
       procedure Hello is
       begin
          Put_Line ("Hello WORLD!");
       end Hello;

       procedure Goodbye is
       begin
          Put_Line ("Goodbye WORLD!");
       end Goodbye;
    end Greetings;

    with Greetings;
    procedure Gmain is
    begin
       Greetings.Hello;
       Greetings.Goodbye;
    end Gmain;

Following the one-unit-per-file rule, place this program in the following three separate files:

``greetings.ads'`
  spec of package `Greetings`

``greetings.adb'`
  body of package `Greetings`

``gmain.adb'`
  body of main program

To build an executable version of this program, we could use four separate steps to compile, bind, and link the program, as follows:

    $ gcc -c gmain.adb
    $ gcc -c greetings.adb
    $ gnatbind gmain
    $ gnatlink gmain

Note that there is no required order of compilation when using GNAT. In particular it is perfectly fine to compile the main program first. Also, it is not necessary to compile package specs in the case where there is an accompanying body; you only need to compile the body. If you want to submit these files to the compiler for semantic checking and not code generation, then use the ``-gnatc'` switch:

    $ gcc -c greetings.ads -gnatc

Although the compilation can be done in separate steps as in the above example, in practice it is almost always more convenient to use the `gnatmake` tool. All you need to know in this case is the name of the main program's source file. The effect of the above four commands can be achieved with a single one:

    $ gnatmake gmain.adb

In the next section we discuss the advantages of using `gnatmake` in more detail.

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

## 1.4 Using the `gnatmake` Utility

If you work on a program by compiling single components at a time using `gcc`, you typically keep track of the units you modify. In order to build a consistent system, you compile not only these units, but also any units that depend on the units you have modified. For example, in the preceding case, if you edit ``gmain.adb'`, you only need to recompile that file. But if you edit ``greetings.ads'`, you must recompile both ``greetings.adb'` and ``gmain.adb'`, because both files contain units that depend on ``greetings.ads'`.

`gnatbind` will warn you if you forget one of these compilation steps, so that it is impossible to generate an inconsistent program as a result of forgetting to do a compilation. Nevertheless it is tedious and error-prone to keep track of dependencies among units. One approach to handle the dependency-bookkeeping is to use a makefile. However, makefiles present maintenance problems of their own: if the dependencies change as you change the program, you must make sure that the makefile is kept up-to-date manually, which is also an error-prone process.

The `gnatmake` utility takes care of these details automatically. Invoke it using either one of the following forms:

    $ gnatmake gmain.adb
    $ gnatmake gmain

The argument is the name of the file containing the main program; you may omit the extension. `gnatmake` examines the environment, automatically recompiles any files that need recompiling, and binds and links the resulting set of object files, generating the executable file, ``gmain'`. In a large program, it can be extremely helpful to use `gnatmake`, because working out by hand what needs to be recompiled can be difficult.

Note that `gnatmake` takes into account all the Ada rules that establish dependencies among units. These include dependencies that result from inlining subprogram bodies, and from generic instantiation. Unlike some other Ada make tools, `gnatmake` does not rely on the dependencies that were found by the compiler on a previous compilation, which may possibly be wrong when sources change. `gnatmake` determines the exact set of dependencies from scratch each time it is run.

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

## 1.5 Introduction to GPS

Although the command line interface (`gnatmake`, etc.) alone is sufficient, a graphical Interactive Development Environment can make it easier for you to compose, navigate, and debug programs. This section describes the main features of GPS ("GNAT Programming Studio"), the GNAT graphical IDE. You will see how to use GPS to build and debug an executable, and you will also learn some of the basics of the GNAT "project" facility.

GPS enables you to do much more than is presented here; e.g., you can produce a call graph, interface to a third-party Version Control System, and inspect the generated assembly language for a program. Indeed, GPS also supports languages other than Ada. Such additional information, and an explanation of all of the GPS menu items. may be found in the on-line help, which includes a user's guide and a tutorial (these are also accessible from the GNAT startup menu).

> 1.5.1 Building a New Program with GPS |  |
> 1.5.2 Simple Debugging with GPS |  |

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

### 1.5.1 Building a New Program with GPS

GPS invokes the GNAT compilation tools using information contained in a project (also known as a project file): a collection of properties such as source directories, identities of main subprograms, tool switches, etc., and their associated values. See 11. GNAT Project Manager for details. In order to run GPS, you will need to either create a new project or else open an existing one.

This section will explain how you can use GPS to create a project, to associate Ada source files with a project, and to build and run programs.

1. Creating a project

   Invoke GPS, either from the command line or the platform's IDE. After it starts, GPS will display a "Welcome" screen with three radio buttons:

   - `Start with default project in directory`

   - `Create new project with wizard`

   - `Open existing project`

   Select `Create new project with wizard` and press `OK`. A new window will appear. In the text box labeled with `Enter the name of the project to create`, type ``sample'` as the project name. In the next box, browse to choose the directory in which you would like to create the project file. After selecting an appropriate directory, press `Forward`.

   A window will appear with the title `Version Control System Configuration`. Simply press `Forward`.

   A window will appear with the title `Please select the source directories for this project`. The directory that you specified for the project file will be selected by default as the one to use for sources; simply press `Forward`.

   A window will appear with the title `Please select the build directory for this project`. The directory that you specified for the project file will be selected by default for object files and executables; simply press `Forward`.

   A window will appear with the title `Please select the main units for this project`. You will supply this information later, after creating the source file. Simply press `Forward` for now.

   A window will appear with the title `Please select the switches to build the project`. Press `Apply`. This will create a project file named ``sample.prj'` in the directory that you had specified.

2. Creating and saving the source file

   After you create the new project, a GPS window will appear, which is partitioned into two main sections:

   - A Workspace area, initially greyed out, which you will use for creating and editing source files

   - Directly below, a Messages area, which initially displays a "Welcome" message. (If the Messages area is not visible, drag its border upward to expand it.)

   Select `File` on the menu bar, and then the `New` command. The Workspace area will become white, and you can now enter the source program explicitly. Type the following text

       with Ada.Text_IO; use Ada.Text_IO;
       procedure Hello is
       begin
         Put_Line("Hello from GPS!");
       end Hello;

   Select `File`, then `Save As`, and enter the source file name ``hello.adb'`. The file will be saved in the same directory you specified as the location of the default project file.

3. Updating the project file

   You need to add the new source file to the project. To do this, select the `Project` menu and then `Edit project properties`. Click the `Main files` tab on the left, and then the `Add` button. Choose ``hello.adb'` from the list, and press `Open`. The project settings window will reflect this action. Click `OK`.

4. Building and running the program

   In the main GPS window, now choose the `Build` menu, then `Make`, and select ``hello.adb'`. The Messages window will display the resulting invocations of `gcc`, `gnatbind`, and `gnatlink` (reflecting the default switch settings from the project file that you created) and then a "successful compilation/build" message.

   To run the program, choose the `Build` menu, then `Run`, and select `hello`. An Arguments Selection window will appear. There are no command line arguments, so just click `OK`.

   The Messages window will now display the program's output (the string `Hello from GPS`), and at the bottom of the GPS window a status update is displayed (`Run: hello`). Close the GPS window (or select `File`, then `Exit`) to terminate this GPS session.

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

### 1.5.2 Simple Debugging with GPS

This section illustrates basic debugging techniques (setting breakpoints, examining/modifying variables, single stepping).

1. Opening a project

   Start GPS and select `Open existing project`; browse to specify the project file ``sample.prj'` that you had created in the earlier example.

2. Creating a source file

   Select `File`, then `New`, and type in the following program:

       with Ada.Text_IO; use Ada.Text_IO;
       procedure Example is
          Line : String (1..80);
          N    : Natural;
       begin
          Put_Line("Type a line of text at each prompt; an empty line to exit");
          loop
             Put(": ");
             Get_Line (Line, N);
             Put_Line (Line (1..N) );
             exit when N=0;
          end loop;
       end Example;

   Select `File`, then `Save as`, and enter the file name ``example.adb'`.

3. Updating the project file

   Add `Example` as a new main unit for the project:

   1. Select `Project`, then `Edit Project Properties`.

   2. Select the `Main files` tab, click `Add`, then select the file ``example.adb'` from the list, and click `Open`. You will see the file name appear in the list of main units

   3. Click `OK`

4. Building/running the executable

   To build the executable select `Build`, then `Make`, and then choose ``example.adb'`.

   Run the program to see its effect (in the Messages area). Each line that you enter is displayed; an empty line will cause the loop to exit and the program to terminate.

5. Debugging the program

   Note that the ``-g'` switches to `gcc` and `gnatlink`, which are required for debugging, are on by default when you create a new project. Thus unless you intentionally remove these settings, you will be able to debug any program that you develop using GPS.

   1. Initializing

      Select `Debug`, then `Initialize`, then ``example'`

   2. Setting a breakpoint

      After performing the initialization step, you will observe a small icon to the right of each line number. This serves as a toggle for breakpoints; clicking the icon will set a breakpoint at the corresponding line (the icon will change to a red circle with an "x"), and clicking it again will remove the breakpoint / reset the icon.

      For purposes of this example, set a breakpoint at line 10 (the statement `Put_Line (Line (1..N));`

   3. Starting program execution

      Select `Debug`, then `Run`. When the `Program Arguments` window appears, click `OK`. A console window will appear; enter some line of text, e.g. `abcde`, at the prompt. The program will pause execution when it gets to the breakpoint, and the corresponding line is highlighted.

   4. Examining a variable

      Move the mouse over one of the occurrences of the variable `N`. You will see the value (5) displayed, in "tool tip" fashion. Right click on `N`, select `Debug`, then select `Display N`. You will see information about `N` appear in the `Debugger Data` pane, showing the value as 5.

   5. Assigning a new value to a variable

      Right click on the `N` in the `Debugger Data` pane, and select `Set value of N`. When the input window appears, enter the value `4` and click `OK`. This value does not automatically appear in the `Debugger Data` pane; to see it, right click again on the `N` in the `Debugger Data` pane and select `Update value`. The new value, 4, will appear in red.

   6. Single stepping

      Select `Debug`, then `Next`. This will cause the next statement to be executed, in this case the call of `Put_Line` with the string slice. Notice in the console window that the displayed string is simply `abcd` and not `abcde` which you had entered. This is because the upper bound of the slice is now 4 rather than 5.

   7. Removing a breakpoint

      Toggle the breakpoint icon at line 10.

   8. Resuming execution from a breakpoint

      Select `Debug`, then `Continue`. The program will reach the next iteration of the loop, and wait for input after displaying the prompt. This time, just hit the `Enter` key. The value of `N` will be 0, and the program will terminate. The console window will disappear.

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

This document was generated by GNAT Mailserver on April, 17 2014 using texi2html