Ada: First Steps

This article gives an overview how to get started with an Ada project. It covers installing the compiler tool-chain, creating a hello world project, and project management for both application and library projects.

Programming in Ada 2022 by John Barnes is a good starting point for learning the Ada programming language. Alternatively, I suggest visiting learn.adacore.com.

Alire

Alire is a package manager provided by AdaCore. It comes as a script. Place it in any folder accessible from the PATH, e.g., ~/bin.

Path Setup

Afterwards, I add the path ~/.alire/bin to the PATH. For this, extend the file ~/.profile to contain

# .profile

if [ -d "$HOME/.alire/bin" ] ; then
    PATH="$HOME/.alire/bin:$PATH"
fi

Proxy Setup

If Alire needs to be run through a proxy, we need to set up a .curlrc file.

# ~/.curlrc

proxy = <domain>:<port>

Here, <domain> and <port> need to be replaced with the proxy configuration.

Tool Chain Installation

Install at least gnat and gprbuild.

alr install gnat gprbuild

Note

If you cannot set up an Alire workflow, you can install tools like gnat and gprbuild via the package manager. Alternatively, you can download binaries for these and other tools, like gnatprove or gnattest, from the Alire release page.

Hello World

Below, a program consisting of a single procedure putting “Hello world.” on the screen.

-- src/main.adb

with Ada.Text_IO;

procedure Main is
    use Ada.Text_IO;
begin
    Put_Line("Hello world.");
end Main;

You can compile this program using the gnat compiler:

gnat make -g -gnat2022 -gnatw.e -gnatw.Y -gnatw.N src/main.adb

GPRbuild Workflow

GPRbuild is a build system for Ada projects. It requires a project file describing the project.

Building an Application

-- hello.gpr

project Hello is
    for Languages use ("Ada");
    for Source_Dirs use ("src");
    for Object_Dir use "build";

    for Main use ("main.adb");      -- main procedure

    package Compiler is
        for Switches ("Ada") use ("-g", "-gnat2022", "-gnatw.e", "-gnatw.Y", "-gnatw.N");
    end Compiler;
end Hello;

The -g switch turns on debug info inside the resulting binary. The switches -gnatw.e and -gnatw.Y control the compiler’s warning output. The switch -gnat2022 enables Ada 2022. I find this important because only Ada 2022 supports transparent records (nonscalar ‘Image).

Building a Library

-- hello.gpr

project Hello is
    for Languages use ("Ada");
    for Source_Dirs use ("src");
    for Object_Dir use "build";

    for Library_Name use "hello";   -- generates hello.so or hello.a
    for Library_Kind use "dynamic"; -- either "dynamic" or "static"
    for Library_Dir use "lib";      -- destination

    package Compiler is
        for Switches ("Ada") use ("-g", "-gnat2022", "-gnatw.e", "-gnatw.Y", "-gnatw.N");
    end Compiler;
end Hello;

With this project file in place, build the project like this:

gprbuild

GNU Make Workflow

What follows is a simple GNU Make-based workflow that drives gprbuild.

# Makefile

PROJECT := hello

.PHONY: all
all:
       gprbuild -P$(PROJECT)

.PHONY: clean
clean:
       $(RM) -r build
       $(RM) -r lib

With this Makefile in place, build the project like this:

make

IDE Setup

This section describes how to set up various IDEs.

Emacs Setup

Enable MELPA, then install the following package:

  • ada-ts-mode

Sublime Text Setup

Enable Package Control, then install the following package:

  • Ada

Visual Studio Code Setup

Here, I describe how to setup Visual Studio Code. In the Settings, set the following:

  • Chat, Miscellaneous: check Disable AI Features.

Install the following extensions:

  • Ada & SPARK

  • Emacs Friendly Keymap

Open the project directory via File, Open Folder....

From the main menu select ..., Terminal, Configure Default Build Task.... Select ada: Build current project.

You can now build the project via ..., Terminal, Run Build Task....

You can run the project via Run, Run Without Debugging.

Debugging

Ensure, that the flag -g is enabled as an Ada compiler flag. Now, debug the executable the same way a C executable would.

gdb hello_world