Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Language Atlas (mini-courses for more languages)  Module 5 – Ada with Alire and GNAT

Ada with Alire and GNAT 16: install and build

Install Alire 2.1.1, select GNAT 16.1.0 and GPRbuild, build a first Ada program, compare the three build profiles and see where Ada is used.

  • Beginner
  • 20 minutes
  • Examples run with Python 3.14.8, Pyodide 314.0.7, Alire 2.1.1 and GNAT 16.1.0
  • By MySmartCoPilot
Free lesson, Pro answers: 20 minutes
Free: the whole lesson. With a pass: the model answers to its 2 interview questions.

What you will learn

  • Install Alire 2.1.1, select GNAT 16.1.0 and GPRbuild 26.0.1, then build and run a program with alr
  • Describe what alire.toml, the project file and the generated configuration file each hold
  • Choose a build profile and predict which checks and warnings a build gets from it
  • Fix the warnings and style messages GNAT reports, and predict when they stop a build
  • Switch a crate to Ada 2022 and explain where Ada is used and what the licence asks of your programs

Before you start

What you’ll learn · Before you start

What you will learn

  • Install Alire 2.1.1, select GNAT 16.1.0 and GPRbuild 26.0.1, then build and run a program with alr
  • Describe what alire.toml, the project file and the generated configuration file each hold
  • Choose a build profile and predict which checks and warnings a build gets from it
  • Fix the warnings and style messages GNAT reports, and predict when they stop a build
  • Switch a crate to Ada 2022 and explain where Ada is used and what the licence asks of your programs

Before you start

On this page

A new Ada program that Alire builds is compiled with 31 GNAT switches, most of the compiler’s optional warnings, its validity checks and 22 style checks among them, and still not one assertion is checked: that takes another build profile. Alire 2.1.1 is the package and toolchain manager of Ada, and GNAT 16.1.0 is the compiler of every example in this mini-course, here on a Mac with Apple silicon; both are released for Linux and Windows too.

Here you install Alire, choose the compiler and build a first program. You read the files a new crate is made of, compare what the three build profiles switch on, fix the messages the default profile reports, switch a crate to Ada 2022, and see where Ada is used and what its licence asks of the programs you build.

Alire installs the compiler, then one command builds the crate

Alire publishes its command, alr, as a zip for each platform on its releases page, and for a Mac with Apple silicon it is alr-2.1.1-bin-aarch64-macos.zip. You put its bin folder on your PATH, and alr then installs everything else itself: the GNAT compiler and GPRbuild, the tool that drives it, come as crate: In Alire, a folder with an alire.toml manifest: a program or library with a name, a version and its dependencies, built with alr build. The compiler and GPRbuild are crates too. of Alire’s community index, downloaded into Alire’s own folder rather than into the system. The Alire documentation says the first alr run offers to choose a toolchain for you; alr toolchain --select makes the choice explicit, which is how you pin a version. Step through the whole path, with the two checks that can send you back:

Interactive · stage by stage From the release zip to a running Ada program Step through installing Alire 2.1.1, choosing the compiler and building a first crate, with the two ways back when a check fails.
From the release zip to a running Ada program, step 9 of 9. Showing Download alr, Check its SHA-256, Put bin/alr on PATH, Select the toolchain, alr init --bin hello, alr build, alr run. In focus: alr run.hash differsnot 2.1.1Download alralr-2.1.1-bin-aarch64-macosCheck its SHA-256starts 2c4867bfPut bin/alr on PATHalr --version: 2.1.1Select the toolchainGNAT 16.1.0, GPRbuild 26.0.1alr init --bin helloalire.toml and hello.gpralr builddevelopment profilealr runHello from Ada

The drawing shows the whole scene; its 9 steps are listed below.

Every step as text
  1. Download the release. Alire publishes alr as a zip per platform on its GitHub releases page. For a Mac with Apple silicon it is alr-2.1.1-bin-aarch64-macos.zip, 8,816,840 bytes, holding bin/alr and the licence.
  2. Check the file. shasum -a 256 prints the SHA-256 of the zip. The release lists 2c4867bf… for this file, and that is the zip this lesson's runs used; a different hash means a different or damaged file.
  3. Hash differs. A mismatch sends you back to the download. Run nothing from a file whose hash does not match.
  4. Put alr on your PATH. Unzip it into a folder you own and add its bin folder to PATH. macOS may refuse to run a downloaded binary; the Alire documentation removes the quarantine with xattr -d com.apple.quarantine bin/alr. alr --version must then say alr 2.1.1.
  5. Another alr first. An older alr earlier on your PATH answers instead, and its index and switches differ. Fix the PATH before you compare any output with this lesson.
  6. Select the toolchain. alr toolchain --select gnat_native=16.1.0 gprbuild=26.0.1 downloads the GNAT FSF compiler, a 146,705,293-byte archive for this Mac, and GPRbuild into Alire's own folder, and makes them the default for every crate. Nothing else on your system changes.
  7. Make a crate. alr -n init --bin hello creates the folder hello with alire.toml, hello.gpr and src/hello.adb, answering its questions with their defaults.
  8. Build. alr build writes config/hello_config.gpr with the 31 switches of the development profile, then calls GPRbuild, which compiles, binds and links the program into bin/hello.
  9. Run. alr run checks that the build is up to date and starts bin/hello, which printed Hello from Ada, Compiled by GNAT 16.1.0 and Integer'Last = 2147483647.

The recorded session starts with Alire installed and alr toolchain --select gnat_native=16.1.0 gprbuild=26.0.1 already run. Its new crate holds an empty main program, which the session replaces with this one; the package GNAT.Compiler_Version reports which compiler built it:

hello.adb, a first Ada program ADB · hello.adb
with Ada.Text_IO;
with GNAT.Compiler_Version;

procedure Hello is
   package Compiler is new GNAT.Compiler_Version;
begin
   Ada.Text_IO.Put_Line ("Hello from Ada");
   Ada.Text_IO.Put_Line ("Compiled by GNAT " & Compiler.Version);
   Ada.Text_IO.Put_Line ("Integer'Last =" & Integer'Last'Image);
end Hello;
Versions, a new crate, a first build and run, the switches it used Python · setup_session.py
from session import run

# The first session of the Ada mini-course, with Alire 2.1.1 installed and its toolchain selected: the versions,
# a new crate made by alr init, the files it wrote, a first build and run, the switches the build used, and the
# compiler's own version. hello.adb replaces the empty main program that alr init writes.
run("""
alr --version
alr toolchain
alr -n init --bin hello
cd hello
find . -type f -not -path './alire/*' | sort
cat src/hello.adb
cp ../hello.adb src/hello.adb
alr build
alr run
grep -o '"-[^"]*"' config/hello_config.gpr | wc -l
alr exec -- gnat --version
""")

Output

$ alr --version
alr 2.1.1
$ alr toolchain
CRATE       VERSION STATUS  NOTES
gprbuild    26.0.1  Default
gnat_native 16.1.0  Default
$ alr -n init --bin hello
Enter a short description of the crate: (default: '')
Using default: ''


Select a software license for the crate?
Using default choice in non-interactive mode: MIT OR Apache-2.0 WITH LLVM-exception
Warning: TRUE
Enter a comma (',') separated list of tags to help people find your crate: (default: '')
Using default: ''
Enter an optional Website URL for the crate: (default: '')
Using default: ''
Success: hello initialized successfully.
$ cd hello
$ find . -type f -not -path './alire/*' | sort
./.gitignore
./alire.toml
./config/hello_config.ads
./config/hello_config.gpr
./config/hello_config.h
./hello.gpr
./src/hello.adb
$ cat src/hello.adb
procedure Hello is
begin
   null;
end Hello;
$ cp ../hello.adb src/hello.adb
$ alr build
Note: Building hello=0.1.0-dev/hello.gpr...
Setup
   [mkdir]        object directory for project Hello
   [mkdir]        exec directory for project Hello
Compile
   [Ada]          hello.adb
Bind
   [gprbind]      hello.bexch
   [Ada]          hello.ali
Link
   [link]         hello.adb
Success: Build finished successfully in … seconds.
$ alr run
Note: Building hello=0.1.0-dev/hello.gpr...
gprbuild: "hello" up to date
Success: Build finished successfully in … seconds.
Hello from Ada
Compiled by GNAT 16.1.0
Integer'Last = 2147483647
$ grep -o '"-[^"]*"' config/hello_config.gpr | wc -l
      31
$ alr exec -- gnat --version
GNAT 16.1.0
Copyright (C) 1996-2025, Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 setup_session.py

Read it from the top. alr toolchain lists the two tools the crate builds with, gnat_native 16.1.0 and gprbuild 26.0.1, both marked Default. alr -n init --bin hello makes the crate: -n answers every question with its default, so the description and website stay empty and the licence becomes MIT OR Apache-2.0 WITH LLVM-exception, which you can change later. The odd line Warning: TRUE comes from alr’s own prompt library, which prints whether its output is a terminal when it answers a choice for you; it changes nothing.

The build runs in four phases: Setup makes the object and program folders, Compile runs GNAT on hello.adb, Bind checks that all units fit together and writes their start-up code, and Link makes the program. alr run rebuilds only if a file changed, and starts it. The program printed what built it, GNAT 16.1.0, and Integer'Last with a space in front of 2147483647: the attribute 'Image gives a non-negative number a leading space, a rule lesson 2 comes back to. alr exec -- gnat --version runs a command with the crate’s toolchain on the PATH.

Repeat the first build

With Alire 2.1.1 installed and the toolchain selected, type alr -n init --bin hello, cd hello, then alr run. The empty main program builds and prints nothing; put the lesson’s hello.adb in src and run again to see the compiler’s version.

Checkpoint

Check: Installing Alire and building a first crate

  1. Question 1 of 2 A project's README says to run alr toolchain --select gnat_native=16.1.0 gprbuild=26.0.1 once. What does that command change?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: It downloads those two crates into Alire's own folder and makes them the default toolchain of your crates

    alr toolchain --select installs the named releases of gnat_native and gprbuild as crates in Alire's own folder and records them as the default, so every crate builds with GNAT 16.1.0 and GPRbuild 26.0.1 until you select another pair. That is how the mini-course pins its compiler.

  2. Question 2 of 2 Which phase of alr build checks that the compiled units fit together and writes the code that starts them up in the right order?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Bind

    The session's build printed Setup, Compile, Bind and Link. The binder checks the consistency of the units and that an order of elaboration exists, and writes the main program that elaborates them in that order.

alire.toml describes the crate, and alr writes the switches

A crate is a folder with a manifest, alire.toml, that names it and the programs it builds. Beside it, alr init wrote hello.gpr, a GPR project file: A .gpr file read by GPRbuild: the source folders, the main programs, the folders for objects and programs, and the compiler switches of an Ada build.: where the sources are, which file is the main program, and where objects and programs go. The third file below was not written by alr init but by alr build:

The crate's manifest, its project file and the configuration alr generated

project/alire.toml

name = "hello"
description = ""
version = "0.1.0-dev"

authors = ["Learner"]
maintainers = ["Learner <learner@example.com>"]
maintainers-logins = ["learner"]
licenses = "MIT OR Apache-2.0 WITH LLVM-exception"
website = ""
tags = []

executables = ["hello"]

project/hello.gpr

with "config/hello_config.gpr";
project Hello is

   for Source_Dirs use ("src/", "config/");
   for Object_Dir use "obj/" & Hello_Config.Build_Profile;
   for Create_Missing_Dirs use "True";
   for Exec_Dir use "bin";
   for Main use ("hello.adb");

   package Compiler is
      for Default_Switches ("Ada") use Hello_Config.Ada_Compiler_Switches;
   end Compiler;

   package Binder is
      for Switches ("Ada") use ("-Es"); --  Symbolic traceback
   end Binder;

   package Install is
      for Artifacts (".") use ("share");
   end Install;

end Hello;

config/hello_config.gpr · project/hello_config.gpr

--  Configuration for hello generated by Alire
abstract project Hello_Config is
   Crate_Version := "0.1.0-dev";
   Crate_Name := "hello";

   Alire_Host_OS := "macos";

   Alire_Host_Arch := "aarch64";

   Alire_Host_Distro := "distribution_unknown";
   Ada_Compiler_Switches := External_As_List ("ADAFLAGS", " ");
   Ada_Compiler_Switches := Ada_Compiler_Switches &
          (
            "-Og" -- Optimize for debug
           ,"-ffunction-sections" -- Separate ELF section for each function
           ,"-fdata-sections" -- Separate ELF section for each variable
           ,"-g" -- Generate debug info
           ,"-gnatwa" -- Enable all warnings
           ,"-gnatw.X" -- Disable warnings for No_Exception_Propagation
           ,"-gnatVa" -- All validity checks
           ,"-gnaty3" -- Specify indentation level of 3
           ,"-gnatya" -- Check attribute casing
           ,"-gnatyA" -- Use of array index numbers in array attributes
           ,"-gnatyB" -- Check Boolean operators
           ,"-gnatyb" -- Blanks not allowed at statement end
           ,"-gnatyc" -- Check comments
           ,"-gnaty-d" -- Disable check no DOS line terminators present
           ,"-gnatye" -- Check end/exit labels
           ,"-gnatyf" -- No form feeds or vertical tabs
           ,"-gnatyh" -- No horizontal tabs
           ,"-gnatyi" -- Check if-then layout
           ,"-gnatyI" -- check mode IN keywords
           ,"-gnatyk" -- Check keyword casing
           ,"-gnatyl" -- Check layout
           ,"-gnatym" -- Check maximum line length
           ,"-gnatyn" -- Check casing of entities in Standard
           ,"-gnatyO" -- Check that overriding subprograms are explicitly marked as such
           ,"-gnatyp" -- Check pragma casing
           ,"-gnatyr" -- Check identifier references casing
           ,"-gnatyS" -- Check no statements after THEN/ELSE
           ,"-gnatyt" -- Check token spacing
           ,"-gnatyu" -- Check unnecessary blank lines
           ,"-gnatyx" -- Check extra parentheses
           ,"-gnatW8" -- UTF-8 encoding for wide characters
          );

   type Build_Profile_Kind is ("release", "validation", "development");
   Build_Profile : Build_Profile_Kind := "development";

end Hello_Config;

The project file’s first line, with "config/hello_config.gpr";, pulls in the generated file, and its Compiler package uses that file’s Ada_Compiler_Switches, so the switches never live in hello.gpr itself. The object folder is obj/ plus the profile’s name, obj/development here, which keeps the objects of different profiles apart. Step through one build and watch who reads what:

Interactive · step by step Who reads which file when you type alr build Step through one build of the hello crate and watch which file each tool reads, and which one alr writes for you.
Who reads which file when you type alr build, step 6 of 6. Showing alire.toml, alr, config/hello_config.gpr, hello.gpr, GPRbuild 26.0.1, GNAT 16.1.0, bin/hello. In focus: bin/hello.readswriteswithcallsrunsobject filesalire.tomlname, version, executablesalrAlire 2.1.1config/hello_config.gprswitches of the profilehello.gprsources, main, foldersGPRbuild 26.0.1reads hello.gprGNAT 16.1.0compiles src/hello.adbbin/hellothe program

The drawing shows the whole scene; its 6 steps are listed below.

Every step as text
  1. The manifest. alr build starts by reading alire.toml, the crate's manifest: its name, version, the programs it builds and, later in this lesson, its build switches.
  2. alr writes the configuration. From the manifest and the build profile, alr writes config/hello_config.gpr, with the list of compiler switches, and config/hello_config.ads. You never edit them: alr writes them again on every build.
  3. The project file. hello.gpr is the GPRbuild project: where the sources are, which file is the main program, where objects and programs go. Its first line, with "config/hello_config.gpr", pulls in the switches alr wrote.
  4. GPRbuild takes over. alr calls GPRbuild with -P hello.gpr. GPRbuild works out what needs compiling and in which order; it is the build tool, and alr only prepares its input.
  5. GNAT compiles. GPRbuild runs GNAT on src/hello.adb with the switches from the configuration file, then binds and links the objects with the Ada run-time library.
  6. The program. The program lands in bin/hello, because hello.gpr says Exec_Dir is bin. alr run starts that file, and you can start it yourself as ./bin/hello.

Two habits follow from it. Change the crate in alire.toml and hello.gpr, never in config/, because alr build writes that folder again every time; the .gitignore that alr init wrote already keeps config/, obj/, bin/ and alire/ out of version control. And add libraries with alr with <crate>, which records the dependency in alire.toml and the exact versions it chose in alire/alire.lock.

Key idea

You edit two files, alire.toml for the crate and hello.gpr for the build; alr writes the switches into config/ on every build, so they follow the profile instead of being copied around.

Checkpoint

Check: What alire.toml, the project file and config/ hold

  1. Question 1 of 2 To silence the "and then" style check, a colleague deletes "-gnatyB" from config/hello_config.gpr and runs alr build. What happens?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: alr writes config/hello_config.gpr again from the profile, so -gnatyB is back and the message returns

    Switches belong in alire.toml, in a [build-switches] table, or come from the profile. config/ is output, written by alr before each GPRbuild run.

  2. Question 2 of 2 Where did the development build put the object files of hello?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: obj/development

    Keeping the objects of each profile apart means a validation build never reuses objects compiled without assertions.

The build profile decides which checks the compiler runs

Alire has three build profile: One of Alire's three named sets of compiler switches for a crate: development (the default), validation or release, chosen with alr build --validation or --release., and its documentation says the crate you are working on builds in development unless you ask for another one, while its dependencies build in release. alr build --validation and alr build --release choose the others. This session builds the same new crate with both and prints the switches each build used:

The same crate built with the validation and release profiles Python · profiles_session.py
from session import run

# The same new crate built with the two other build profiles: alr writes the switches of the profile into
# config/hello_config.gpr before it calls GPRbuild, so each list below is what that build compiled with.
run("""
alr -n init --bin hello
cd hello
alr build --validation
grep -o '"-[^"]*"' config/hello_config.gpr | tr '\\n' ' '
alr build --release
grep -o '"-[^"]*"' config/hello_config.gpr | tr '\\n' ' '
""")

Output

$ alr -n init --bin hello
Enter a short description of the crate: (default: '')
Using default: ''


Select a software license for the crate?
Using default choice in non-interactive mode: MIT OR Apache-2.0 WITH LLVM-exception
Warning: TRUE
Enter a comma (',') separated list of tags to help people find your crate: (default: '')
Using default: ''
Enter an optional Website URL for the crate: (default: '')
Using default: ''
Success: hello initialized successfully.
$ cd hello
$ alr build --validation
Note: Building hello=0.1.0-dev/hello.gpr...
Setup
   [mkdir]        object directory for project Hello
   [mkdir]        exec directory for project Hello
Compile
   [Ada]          hello.adb
Bind
   [gprbind]      hello.bexch
   [Ada]          hello.ali
Link
   [link]         hello.adb
Success: Build finished successfully in … seconds.
$ grep -o '"-[^"]*"' config/hello_config.gpr | tr '\n' ' '
"-O3" "-gnatn" "-ffunction-sections" "-fdata-sections" "-g" "-gnato" "-gnatwa" "-gnatw.X" "-gnatVa" "-gnatwe" "-gnata" "-gnaty3" "-gnatya" "-gnatyA" "-gnatyB" "-gnatyb" "-gnatyc" "-gnaty-d" "-gnatye" "-gnatyf" "-gnatyh" "-gnatyi" "-gnatyI" "-gnatyk" "-gnatyl" "-gnatym" "-gnatyn" "-gnatyO" "-gnatyp" "-gnatyr" "-gnatyS" "-gnatyt" "-gnatyu" "-gnatyx" "-gnatW8"
$ alr build --release
Note: Building hello=0.1.0-dev/hello.gpr...
Setup
   [mkdir]        object directory for project Hello
Compile
   [Ada]          hello.adb
Bind
   [gprbind]      hello.bexch
   [Ada]          hello.ali
Link
   [link]         hello.adb
Success: Build finished successfully in … seconds.
$ grep -o '"-[^"]*"' config/hello_config.gpr | tr '\n' ' '
"-O3" "-gnatn" "-ffunction-sections" "-fdata-sections" "-gnatW8"

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 profiles_session.py

Side by side, with the 31 switches of the first session:

What the build gets development validation release
optimisation -Og -O3 -gnatn -O3 -gnatn
debug information, -g yes yes no
most optional warnings, -gnatwa yes yes no
all validity checks, -gnatVa yes yes no
22 style checks, -gnaty… yes yes no
assertions and contracts, -gnata no yes no
warnings and style as errors, -gnatwe no yes no

Two rows matter most for the rest of the mini-course. Only validation has -gnata, which the GNAT User’s Guide says enables assertions, preconditions, postconditions, type invariants and predicates, all disabled by default; the contracts of lesson 3 are ignored by every other build. And only validation has -gnatwe, so a warning that the development build merely prints stops a validation build. Validation also adds -gnato explicitly, though the User’s Guide says overflow checking is already on when no -gnato is given, as lesson 2’s overflow shows.

One profile for each job

Write and debug with development, run your tests and every CI build with alr build --validation, and ship with --release. The choice does not stick to the crate: a plain alr build builds in development again, while alr run, which rebuilds before it starts the program, reuses the profile of your last alr build.

Checkpoint

Check: What each build profile switches on

  1. Question 1 of 2 Your CI build should stop when a test violates a precondition, and also when someone leaves a style slip in the code. Which command?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: alr build --validation

    Of the three profiles only validation has both -gnata and -gnatwe, so it is the one for tests and CI.

  2. Question 2 of 2 A program built with alr build --release calls a procedure whose precondition the call violates. What happens at the call?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Nothing: the precondition is not checked and the procedure runs

    The GNAT User's Guide says all assertions are disabled by default; -gnata enables preconditions, postconditions, invariants and predicates. Lesson 3 shows the same program with and without it.

A style message is only a warning until validation makes it an error

GNAT’s style check: A GNAT check, switched on with -gnaty, of how code is written rather than what it does, such as casing, line length or and then in conditions. It reports a (style) message. look at how code is written, not what it does. Here is a first draft of a small program that accepts a payment of up to 100,000 paise. It works, and it has four slips:

limits.adb, a first draft ADB · limits/src/limits.adb
with Ada.Command_Line; use Ada.Command_Line;
with Ada.Text_IO;      use Ada.Text_IO;

procedure Limits is
   Amount : constant Integer := Integer'Value (Argument (1));
   Spare  : Integer := 0;
begin
   if Amount >= 0 and Amount <= 100_000 then
      put_line ("Paid:" & Amount'Image & " paise, within the limit of 100000 paise");
   end if;
end Limits;

The development build reports them and still links the program:

The draft with the development profile Python · style_session.py
from session import run

# limits.adb as a first draft often looks: it builds with the development profile, which reports every warning and
# style message and still links the program.
run("""
cd limits
alr build
./bin/limits 1205
""")

Output

$ cd limits
$ alr build
Note: Synchronizing workspace...
Nothing to update.

Note: Building limits=0.1.0-dev/limits.gpr...
Setup
   [mkdir]        object directory for project Limits
   [mkdir]        exec directory for project Limits
Compile
   [Ada]          limits.adb
limits.adb:6:04: warning: variable "Spare" is not referenced [-gnatwu]
limits.adb:8:19: (style) "and then" required [-gnatyB]
limits.adb:9:07: (style) bad casing of "Put_Line" declared at a-textio.ads:565 [-gnatyr]
limits.adb:9:80: (style) this line is too long: 85 [-gnatyM]
Bind
   [gprbind]      limits.bexch
   [Ada]          limits.ali
Link
   [link]         limits.adb
Success: Build finished successfully in … seconds.
$ ./bin/limits 1205
Paid: 1205 paise, within the limit of 100000 paise

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 style_session.py

Each message names its place, line and column, and ends with the switch that produced it. The warning variable "Spare" is not referenced comes from -gnatwu, part of -gnatwa. The three (style) messages come from the -gnaty checks: "and then" required because the User’s Guide’s rule -gnatyB permits and and or only for modular or array operands and simple Boolean variables or constants, so a condition built from comparisons needs the Ada's short-circuit forms: and then evaluates its right side only when the left side is True, or else only when it is False, so the right side may rely on the left.; bad casing of "Put_Line" because -gnatyr wants every use of a name spelt as it was declared, here at line 565 of a-textio.ads, the specification of Ada.Text_IO; and this line is too long: 85 because -gnatym allows 79 characters, a check the message tags with -gnatyM, the switch that sets another length. The same draft with the validation profile, then the fixed file:

The draft with validation, then the fixed file Python · strict_session.py
from session import run

# The same draft with the validation profile, which treats warnings and style messages as errors; then the fixed
# file from limits-fixed, built the same way.
run("""
cd limits
!alr build --validation
cp ../limits-fixed/limits.adb src/limits.adb
alr build --validation
./bin/limits 1205
""")

Output

$ cd limits
$ alr build --validation
Note: Synchronizing workspace...
Nothing to update.

Note: Building limits=0.1.0-dev/limits.gpr...
Setup
   [mkdir]        object directory for project Limits
   [mkdir]        exec directory for project Limits
Compile
   [Ada]          limits.adb
limits.adb:6:04: warning: variable "Spare" is not referenced [-gnatwu]
limits.adb:8:19: (style) "and then" required [-gnatyB]
limits.adb:9:07: (style) bad casing of "Put_Line" declared at a-textio.ads:565 [-gnatyr]
limits.adb:9:80: (style) this line is too long: 85 [-gnatyM]

   compilation of limits.adb failed

gprbuild: *** compilation phase failed
ERROR: Command ["gprbuild", "-s", "-j0", "-p", "-P", "limits/limits.gpr"] exited with code 4
ERROR: Compilation failed.
[exit status 1]
$ cp ../limits-fixed/limits.adb src/limits.adb
$ alr build --validation
Note: Building limits=0.1.0-dev/limits.gpr...
Compile
   [Ada]          limits.adb
Bind
   [gprbind]      limits.bexch
   [Ada]          limits.ali
Link
   [link]         limits.adb
Success: Build finished successfully in … seconds.
$ ./bin/limits 1205
Paid: 1205 paise, within the limit of 100000 paise

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 strict_session.py

Under validation the very same four messages stopped the build, because -gnatwe counts them as errors: compilation of limits.adb failed, exit status 1 from alr. The fixed file removed the unused variable, wrote and then, used the declared casing and split the long line, and it built with no message at all.

Switching the checks off to make CI pass

Removing -gnatwe or setting "*".style_checks = "No" in alire.toml turns a red validation build green and keeps every slip. Fix the messages instead: they are short, the switch in brackets names the rule, and the rule’s entry in the GNAT User’s Guide says exactly what it wants.

Checkpoint

Check: Reading warnings and style messages

  1. Question 1 of 2 GNAT reports (style) "and then" required [-gnatyB] for: if Amount >= 0 and Amount <= 100_000 then. What is the fix?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Write if Amount >= 0 and then Amount <= 100_000 then

    and then evaluates its right side only when the left side is True. GNAT's style rule asks for it in every condition built from comparisons.

  2. Question 2 of 2 The draft of limits.adb built with four messages under development but did not build under validation. Which switch made the difference?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: -gnatwe

    The very same four messages appeared in both builds; under validation they were counted as errors and compilation of limits.adb failed.

GNAT 16 compiles Ada 2012 until a crate asks for Ada 2022

The GNAT User’s Guide says the compiler’s default mode is Ada 2012, and GNAT 16.1.0 still keeps to it: forms that are new in Ada 2022, such as the two below, do not compile until a switch asks for that edition. This program counts the passes in a class with an aggregate in square brackets and @, which stands for the target of an assignment:

brackets.adb, with two Ada 2022 forms ADB · brackets/src/brackets.adb
with Ada.Text_IO; use Ada.Text_IO;

procedure Brackets is
   type Marks is array (1 .. 4) of Natural;
   Class  : constant Marks := [72, 95, 38, 48];
   Passed : Natural := 0;
begin
   for Mark of Class loop
      if Mark >= 40 then
         Passed := @ + 1;
      end if;
   end loop;
   Put_Line ("Passed:" & Passed'Image & " of" & Class'Length'Image);
end Brackets;
The Ada 2012 default, then the crate switched to Ada 2022 Python · ada2022_session.py
from session import run

# brackets.adb uses two Ada 2022 forms, a [ ] aggregate and @ for the target of an assignment. GNAT 16 compiles
# Ada 2012 unless a switch asks for 2022, so the first build stops; the second alire.toml asks for Ada 2022, and the
# switch it adds is then in the generated configuration.
run("""
cd brackets
!alr build
cp ../brackets-2022/alire.toml alire.toml
tail -2 alire.toml
alr build
grep -o '"-gnat2022"' config/brackets_config.gpr
./bin/brackets
""")

Output

$ cd brackets
$ alr build
Note: Synchronizing workspace...
Nothing to update.

Note: Building brackets=0.1.0-dev/brackets.gpr...
Setup
   [mkdir]        object directory for project Brackets
   [mkdir]        exec directory for project Brackets
Compile
   [Ada]          brackets.adb
brackets.adb:5:31: error: illegal character, replaced by "("
brackets.adb:10:20: error: target name is an Ada 2022 feature
brackets.adb:10:20: error: unit must be compiled with -gnat2022 switch

   compilation of brackets.adb failed

gprbuild: *** compilation phase failed
ERROR: Command ["gprbuild", "-s", "-j0", "-p", "-P", "brackets/brackets.gpr"] exited with code 4
ERROR: Compilation failed.
[exit status 1]
$ cp ../brackets-2022/alire.toml alire.toml
$ tail -2 alire.toml
[build-switches]
"*".ada_version = "Ada2022"
$ alr build
Note: Synchronizing workspace...
Nothing to update.

Note: Building brackets=0.1.0-dev/brackets.gpr...
Compile
   [Ada]          brackets.adb
Bind
   [gprbind]      brackets.bexch
   [Ada]          brackets.ali
Link
   [link]         brackets.adb
Success: Build finished successfully in … seconds.
$ grep -o '"-gnat2022"' config/brackets_config.gpr
"-gnat2022"
$ ./bin/brackets
Passed: 3 of 4

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 ada2022_session.py

The first build read [ as an illegal character and said outright that the target name @ is an Ada 2022 feature and the unit must be compiled with -gnat2022. Two lines in alire.toml fixed it: the [build-switches] table with "*".ada_version = "Ada2022", where * means every profile. Alire then adds -gnat2022 to the generated switches, and the program counted 3 passes of 4. Every crate in this mini-course carries those two lines.

Ada 2022 is the fourth edition of the standard, ISO/IEC 8652:2023, and the language specification: The document that defines what a language means for every implementation, often an international standard, such as the Ada Reference Manual (ISO/IEC 8652:2023) or the C standard. More in “Reading language references and release notes” every example of this mini-course follows is its Reference Manual. Walk through the editions to see where the features of the coming lessons came from:

Timeline · 5 events in order Five editions of the Ada standard Walk through the editions in order; the lessons of this mini-course use the last one, Ada 2022.
  1. Ada 83

    The first edition

    The Reference Manual names three overriding concerns of the original design: program reliability and maintenance, programming as a human activity, and efficiency. Readability was put before ease of writing.

  2. Ada 95

    The 1995 revision protected objects

    The revision added flexibility and extensibility, more control over storage management and synchronization, and standard packages for important application areas. Protected objects, which share data between tasks, are new in it.

  3. Ada 2005

    Amendment 1 interfaces

    Interface types arrived, multiple inheritance of interfaces in the manner of Java, together with the standard containers library.

  4. Ada 2012

    Contracts in the language contracts

    Pre and Post aspects, subtype predicates and type invariants became part of the language, with expression functions, quantified expressions and for … of loops.

  5. Ada 2022

    ISO/IEC 8652:2023 [ ] aggregates

    The fourth edition adds parallel loops and blocks, the Global aspect, delta aggregates, the @ shorthand, declare expressions, reduction expressions and an Image attribute for every type. GNAT 16 compiles it with -gnat2022.

The timeline has 5 events, from Ada 83 to Ada 2022.

The Reference Manual marks its history in its paragraph numbers, which helps when you read it next to an older book: a number such as 8/3 changed in the Ada 2012 edition and 1/5 in Ada 2022, while an unmarked number is unchanged since 1995.

Checkpoint

Check: GNAT's default Ada 2012 and the switch to Ada 2022

  1. Question 1 of 2 A crate with no [build-switches] table contains Count := @ + 1;. What does GNAT 16.1.0 do?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: It stops: target name is an Ada 2022 feature, and the unit must be compiled with -gnat2022

    Two lines in alire.toml, [build-switches] and "*".ada_version = "Ada2022", add -gnat2022 to every profile.

  2. Question 2 of 2 Which lines of alire.toml make every profile compile Ada 2022?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: [build-switches] followed by "*".ada_version = "Ada2022"

    The Alire documentation lists Ada_Version among the build-switches categories, with values from Ada83 to Ada2022.

Where Ada is used, and what GNAT’s licence asks of your programs

Ada is a language for software that must keep working. AdaCore, which contributes to GNAT and makes the SPARK tools, lists the industries its tools serve as avionics, defence, automotive, rail, medical, space and security. Its SPARK User’s Guide describes SPARK as a language and a set of verification tools for high-assurance software, based on Ada with the features that defy verification removed, and names air-traffic management and avionics among the systems it suits; lesson 3 runs its prover on a small program. In the Stack Overflow Developer Survey 2025, about 1.4 % of all respondents and 3 % of those learning to code said they had done extensive development work in Ada in the past year. Those are small numbers next to C or Java, and they are why this mini-course spends its time on what makes Ada different rather than on syntax.

The licences are in the crates themselves. Alire’s index lists the gnat_native 16.1.0 compiler as GPL-3.0-or-later AND GPL-3.0-or-later WITH GCC-exception-3.1: the compiler is under the GPL, and the run-time library that every program links, Ada.Text_IO among it, carries the GCC Runtime Library Exception 3.1, as the header of a-textio.ads states. Three licences meet in a program you build:

Part of the program Licence What it asks of you
The GNAT compiler GPL-3.0-or-later nothing for using it; the GPL’s conditions apply if you pass the compiler on
The run-time library it links in GPL-3.0-or-later with the GCC Runtime Library Exception 3.1 nothing for code compiled by GNAT
Your own crate licences in alire.toml, MIT OR Apache-2.0 WITH LLVM-exception after alr -n init your choice

The exception is what makes the middle row harmless: it lets you combine the run-time library with your own code, compiled by an eligible process such as GNAT, and convey the result on terms of your choice, so a program you build need not be GPL.

Organisations named on this page

AdaCore, the Alire project, the Free Software Foundation and Stack Overflow appear here because they make the tools, publish the licence texts or ran the survey this page cites. MySmartCoPilot is not connected with any of them; the runs on this page used the GNAT compiler as Alire installs it.

Checkpoint

Check: Where Ada is used and what the licence asks

  1. One question You sell a closed-source program built with GNAT 16.1.0 through Alire. What do the licences say about it?

    Choose one answer.

    Show the answer: One question

    Answer: The run-time library's GCC Runtime Library Exception lets you convey the program on terms of your choice

    Alire's index lists gnat_native as GPL-3.0-or-later AND GPL-3.0-or-later WITH GCC-exception-3.1. The exception lets a program compiled with GNAT and combined with its run-time library be conveyed under terms of your choice.

Practise: read a build log the way the compiler means it

The exercise turns the messages of this lesson into code: split a line of a build log into its file, line, column, kind, text and switch, then say whether a build with a given profile stops. Its sample tests replay the lesson’s own logs, the four messages about limits.adb and the three errors about brackets.adb.

Exercise · Easy · Python

Read GNAT's messages and say whether a build fails

A build log from alr build mixes progress lines with the compiler's messages. Before you fix anything, you want to know which lines are messages, what kind each one is, and whether the build stops. Write two functions in messages.py.

parse(line) reads one line of the log. When it is a GNAT message, it returns a dictionary with six keys:

  • "file", "line" and "column": the place, as in limits.adb:8:19: (the numbers as int).
  • "kind": "error" when the text after the place starts with error: , "warning" when it starts with warning: , and "style" when it starts with (style) .
  • "text": the message itself, without that prefix and without the switch at the end.
  • "switch": what the square brackets at the very end hold, such as "-gnatyB" or "enabled by default", or None when the line ends without them.

Any other line, such as Compile, [Ada] limits.adb or Success: Build finished successfully in … seconds., gives None.

build_fails(profile, lines) takes a profile name, "development", "validation" or "release", and the lines of one build log. It returns True when the build stops: an error stops every build, and the validation profile also treats every warning and style message as an error, because it compiles with -gnatwe. Otherwise it returns False.

The sample tests use the lesson's own logs: the four messages about limits.adb, and the three errors about brackets.adb in Ada 2012 mode.

Starter code · messages.py

def parse(line):
    """The parts of one GNAT message (file, line, column, kind, text, switch), or None for any other line."""
    # Replace this line with your code.
    return None


def build_fails(profile, lines):
    """Whether a build with this profile ("development", "validation" or "release") stops on these log lines."""
    # Replace this line with your code.
    return False
The sample tests · test_messages.py
from messages import build_fails, parse

LIMITS = [
    "Compile",
    "   [Ada]          limits.adb",
    'limits.adb:6:04: warning: variable "Spare" is not referenced [-gnatwu]',
    'limits.adb:8:19: (style) "and then" required [-gnatyB]',
    'limits.adb:9:07: (style) bad casing of "Put_Line" declared at a-textio.ads:565 [-gnatyr]',
    "limits.adb:9:80: (style) this line is too long: 85 [-gnatyM]",
    "Bind",
]

BRACKETS = [
    'brackets.adb:5:31: error: illegal character, replaced by "("',
    "brackets.adb:10:20: error: target name is an Ada 2022 feature",
    "brackets.adb:10:20: error: unit must be compiled with -gnat2022 switch",
]


def test_a_warning():
    """The unused variable: a warning, with the switch that reports it"""
    assert parse(LIMITS[2]) == {"file": "limits.adb", "line": 6, "column": 4, "kind": "warning", "text": 'variable "Spare" is not referenced', "switch": "-gnatwu"}


def test_style_messages():
    """The three style messages, one of them with a colon inside its text"""
    assert parse(LIMITS[3])["kind"] == "style"
    assert parse(LIMITS[3])["text"] == '"and then" required'
    assert parse(LIMITS[4])["text"] == 'bad casing of "Put_Line" declared at a-textio.ads:565'
    assert parse(LIMITS[4])["switch"] == "-gnatyr"
    assert parse(LIMITS[5]) == {"file": "limits.adb", "line": 9, "column": 80, "kind": "style", "text": "this line is too long: 85", "switch": "-gnatyM"}


def test_an_error_without_a_switch():
    """An error from the Ada 2012 build: no brackets at the end"""
    assert parse(BRACKETS[0]) == {"file": "brackets.adb", "line": 5, "column": 31, "kind": "error", "text": 'illegal character, replaced by "("', "switch": None}
    assert parse(BRACKETS[2])["text"] == "unit must be compiled with -gnat2022 switch"


def test_a_switch_in_words():
    """The warning about a value out of range ends with [enabled by default]"""
    m = parse('marks.adb:11:35: warning: Constraint_Error will be raised at run time [enabled by default]')
    assert m["kind"] == "warning"
    assert m["switch"] == "enabled by default"
    assert m["text"] == "Constraint_Error will be raised at run time"


def test_brackets_inside_the_text():
    """A message that ends with ] but has no switch keeps its whole text"""
    m = parse("scores.adb:3:10: error: no index 5 in Scores[1 .. 4]")
    assert m["text"] == "no index 5 in Scores[1 .. 4]"
    assert m["switch"] is None


def test_other_lines():
    """Progress lines and the last line of a build are not messages"""
    assert parse("Compile") is None
    assert parse("   [Ada]          limits.adb") is None
    assert parse("Success: Build finished successfully in … seconds.") is None
    assert parse("") is None


def test_the_profiles():
    """The draft builds with development and stops with validation; an error stops every profile"""
    assert build_fails("development", LIMITS) is False
    assert build_fails("validation", LIMITS) is True
    assert build_fails("release", LIMITS) is False
    assert build_fails("development", BRACKETS) is True
    assert build_fails("release", BRACKETS) is True
    assert build_fails("validation", ["Compile", "Bind", "Link"]) is False
A hint

Split the line at the first three colons only: the file, the line and the column come first, and the text after them may hold colons of its own, as in bad casing of "Put_Line" declared at a-textio.ads:565. Then look at how the rest starts, and take the switch off the end only when the line ends with ].

The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Then test yourself on the six ideas of this lesson, from installing alr to the licences. Your weakest idea is asked about first, and a wrong pick names the slip behind it:

Practice that adapts to you

Practise this lesson

13 questions about 6 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 13 What does alr run do in a crate whose program is already built and whose files have not changed?

    Choose one answer.

    Show the answer: Question 1 of 13

    Answer: It checks the build, finds it up to date, and starts the program

    The Alire documentation describes alr run as building and then launching the executable, so it is safe to use after every change.

  2. Question 2 of 13 alr -n init --bin hello printed Warning: TRUE. What should you do about it?

    Choose one answer.

    Show the answer: Question 2 of 13

    Answer: Nothing: it is alr's prompt library printing whether its output is a terminal, and the crate was made

    Read what a tool says, then check the result: here the last line said Success, and the crate built.

  3. Question 3 of 13 You add a library with alr with. Where does Alire record the exact version it chose?

    Choose one answer.

    Show the answer: Question 3 of 13

    Answer: In alire/alire.lock

    alire.toml says what the crate needs, such as gnatprove = "^16.1.0"; alire/alire.lock says which release was chosen.

  4. Question 4 of 13 A teammate copies the switches from config/hello_config.gpr into hello.gpr to "make them permanent". What goes wrong?

    Choose one answer.

    Show the answer: Question 4 of 13

    Answer: The build no longer follows the profile: --validation and --release would still get the copied development switches

    Keep switches in one of two places: the profiles, or a [build-switches] table in alire.toml. Then every build gets the switches of the profile it was asked for.

  5. Question 5 of 13 How many switches did the development build of the new crate compile with, as the session counted them?

    Type a number.

    Show the answer: Question 5 of 13

    Answer: 31 switches

    grep counted 31 quoted switches in config/hello_config.gpr: -Og, the two -f section switches and -g, -gnatwa and -gnatw.X, -gnatVa, 23 -gnaty switches (22 checks on, -gnaty-d off) and -gnatW8.

  6. Question 6 of 13 Your program is fast enough in its validation build, and its contracts protect a money calculation. You are about to ship it. Which build should you ship, and why?

    Choose one answer.

    Show the answer: Question 6 of 13

    Answer: Consider shipping a build that keeps -gnata, because release would switch the contracts off

    A profile is a choice of checks, not only of speed. The table of this lesson shows exactly what each one switches on.

  7. Question 7 of 13 What does (style) bad casing of "Put_Line" declared at a-textio.ads:565 [-gnatyr] ask you to change?

    Choose one answer.

    Show the answer: Question 7 of 13

    Answer: Write Put_Line exactly as it is declared, Put_Line, not put_line

    Ada is not case-sensitive, so put_line compiles; the style check keeps one spelling per name across a code base.

  8. Question 8 of 13 The message said this line is too long: 85. How many characters must you remove for the line to pass the style check?

    Type a number.

    A hint

    The User's Guide gives the limit of -gnatym in characters.

    Show the answer: Question 8 of 13

    Answer: 6 characters

    -gnatym allows 79 characters, so 85 − 79 = 6 must go. The fixed limits.adb split the line in two instead.

  9. Question 9 of 13 A validation build fails only on warning: variable "Spare" is not referenced [-gnatwu]. Spare is left over from an old version. What is the right fix?

    Choose one answer.

    Show the answer: Question 9 of 13

    Answer: Delete the variable

    Each GNAT message names the rule in brackets. A warning about unused code is fixed by removing the code.

  10. Question 10 of 13 In Ada 2022, what does Passed := @ + 1; mean?

    Choose one answer.

    Show the answer: Question 10 of 13

    Answer: Passed := Passed + 1;

    The target name saves repeating a long name on both sides, as in Totals (Day) := @ + Mark.

  11. Question 11 of 13 In the Ada Reference Manual, a paragraph is numbered 8/3. What does the /3 tell you?

    Choose one answer.

    Show the answer: Question 11 of 13

    Answer: The paragraph was changed by the Ada 2012 edition

    The markers let you see at a glance which edition last touched a rule, handy when an older book disagrees with your compiler.

  12. Question 12 of 13 Which of these describes SPARK, as its User's Guide does?

    Choose one answer.

    Show the answer: Question 12 of 13

    Answer: A language based on Ada, with features that defy verification removed, and tools that verify programs against their contracts

    Lesson 3 adds GNATprove to a crate with alr with gnatprove and proves a small function.

  13. Question 13 of 13 Your company wants its Ada library to be closed source. Which file do you change, and what does the GNAT licence ask of the library?

    Choose one answer.

    Show the answer: Question 13 of 13

    Answer: Change the licences field of alire.toml; the run-time exception asks nothing of your code's licence

    Two licences meet in every program: your code's, written in alire.toml, and GNAT's run-time library, whose exception leaves the choice of terms to you.

Interview questions

Warm-up (fresher to mid-level): What are Alire, GNAT and GPRbuild, and which one does alr build run?

GNAT is the Ada compiler, part of the GNU Compiler Collection. GPRbuild is the build tool that reads a .gpr project file and runs the compiler, the binder and the linker on the right files in the right order. Alire is Ada’s package and toolchain manager: its alr command installs GNAT and GPRbuild as crates, keeps a crate’s dependencies in alire.toml, and writes the compiler switches of the chosen build profile into config/. alr build runs all three in turn: alr prepares the configuration, then calls GPRbuild with the crate’s project file, and GPRbuild runs GNAT. You can still call gprbuild yourself, through alr exec --, with the same project file.

Two questions an Ada team might put to a new colleague who will run its builds:

Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.

  1. Fresher to senior

    An Ada crate builds on every developer's machine with alr build, but the CI job, which runs alr build --validation, fails with a page of style messages and one warning. What is going on, and how do you get the team back to green without weakening CI?

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Mid to staff

    A new Ada project must build reproducibly for an audit: the same compiler and build tool on every laptop and in CI, for years. How do you set that up with Alire, and what do you check on every build?

    Model answer, Pro. First step and follow-ups

Flashcards · 8 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. How do you pin the compiler and the build tool that Alire uses?

    alr toolchain --select gnat_native=16.1.0 gprbuild=26.0.1. GNAT and GPRbuild are crates of Alire's index, so they install into Alire's own folder instead of the system.

  2. Which files of an Alire crate do you edit, and which one does alr rewrite?

    You edit alire.toml and the crate's .gpr project file. alr writes the config/ folder afresh on every build, with the switches of the current profile, so changes there are lost.

  3. Which Alire build profile turns on assertions and contracts?

    Only validation: it adds -gnata, and also -gnatwe, which makes every warning and style message an error. The development and release profiles leave contracts unchecked.

  4. In which profile does a plain alr build compile your crate, and its dependencies?

    Your crate in development, unless you pass --validation or --release; the crates it depends on in release.

  5. Why does GNAT's style check ask for and then in a condition built from two comparisons?

    Rule -gnatyB allows plain and and or only for modular or array operands and simple Boolean variables or constants. Comparisons joined in a condition take the short-circuit form.

  6. Which Ada edition does GNAT 16.1.0 compile by default, and how does a crate move to Ada 2022?

    Ada 2012. Two lines in alire.toml, a [build-switches] table with "*".ada_version = "Ada2022", make Alire add -gnat2022 to every profile.

  7. Does a program built with GNAT have to be released under the GPL?

    No. The run-time library it links carries the GCC Runtime Library Exception 3.1, so code compiled with GNAT may be passed on under terms of your choice.

  8. A validation build fails on style messages. Why is switching the style checks off the wrong fix?

    It keeps every slip in the code. Each message gives its line, its column and the switch behind it, and that switch's entry in the GNAT User's Guide says exactly what it wants.

Key takeaways

  • Alire 2.1.1 is installed from one zip, and alr toolchain --select gnat_native=16.1.0 gprbuild=26.0.1 pins the compiler and the build tool; alr init, alr build and alr run then make, build and start a crate.
  • A crate is alire.toml plus a GPR project file; alr writes the compiler switches into config/ on every build, so you never edit that folder.
  • The development profile compiled with 31 switches, warnings and style checks among them, but only validation enables assertions with -gnata and turns warnings into errors with -gnatwe; release keeps optimisation only.
  • GNAT’s messages name their place and the switch that produced them, and the same four messages that the development build printed stopped the validation build.
  • GNAT 16 compiles Ada 2012 by default, so every crate here sets "*".ada_version = "Ada2022"; the compiler is under the GPL, and the run-time library’s exception leaves your program’s licence to you.

Terms in this lesson

build profile
One of Alire's three named sets of compiler switches for a crate: development (the default), validation or release, chosen with alr build --validation or --release.
crate
In Alire, a folder with an alire.toml manifest: a program or library with a name, a version and its dependencies, built with alr build. The compiler and GPRbuild are crates too.
GPR project file
A .gpr file read by GPRbuild: the source folders, the main programs, the folders for objects and programs, and the compiler switches of an Ada build.
style check
A GNAT check, switched on with -gnaty, of how code is written rather than what it does, such as casing, line length or and then in conditions. It reports a (style) message.

References

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.