Revision history (first version, published Nov 1, 2026)
- First published
Cite this article(DOI: 10.5281/zenodo.23856524)
This article is archived on Zenodo. Below are both the DOI that always resolves to the latest version and the DOI pinned to the version you are reading.
Go Komura (2026). Starting an Ada Project with Alire — Creating a Project, Adding Dependencies, Build Profiles, and GNATprove. KomuraSoft LLC. https://doi.org/10.5281/zenodo.23856524 https://comcomponent.com/en/blog/alire-getting-started/
- DOI (latest version)
- 10.5281/zenodo.23856524
- DOI (this version)
- 10.5281/zenodo.23856525
When you start writing programs in Ada, you may get stuck on where to install the GNAT compiler from and how to fetch libraries. Alire is the package manager for Ada and SPARK that handles both. Its command, alr, takes care of creating projects, fetching the libraries you depend on, fetching GNAT and GPRbuild, and building and running.
This article walks through creating a project with alr init, adding a dependency, switching build profiles, and proving code with GNATprove. Along the way, it also uses real output to confirm that the default build does not check preconditions.
The commands and output were run on November 1, 2026, on Ubuntu (x86-64), with alr 2.1.0 and with alr 2.1.1, the latest version at the time of writing. Both versions gave the same results. Long output is partly omitted. The Windows installer and the MSYS2 steps were not tried in this environment, so for those this article only describes what the Alire documentation says.
Ada itself is covered in “The Appeal of the Ada Language”, and SPARK and GNATprove in “Introduction to Formal Verification with SPARK”.
What Alire takes care of
In Alire, the unit of distribution and dependency is called a crate. At the root of a crate is a manifest named alire.toml, which records the name, the version, the crates it depends on, and so on in TOML format1. Information about published crates is collected in the community index (the alire-index repository on GitHub), and alr looks for dependency candidates there2.
Builds use GPRbuild. GPRbuild is a tool that reads project files (.gpr) and builds systems written in multiple languages3. alr build sets up environment variables such as GPR_PROJECT_PATH and then calls GPRbuild4.
flowchart TB
accTitle: The parts of Alire
accDescr: Shows how the alr command reads the manifest, fetches dependency crates from the index and the GNAT and GPRbuild that Alire distributes, and builds with GPRbuild.
U["Developer"] --> A["alr command"]
A --> M["alire.toml (manifest)"]
A --> I["Community index"]
I --> D["Dependency crates"]
A --> T["GNAT and GPRbuild"]
A --> G["Build with GPRbuild"]
D --> G
T --> G
Figure 1: alr reads the manifest, fetches the dependency crates and the toolchain, and builds with GPRbuild.
In the diagram a solid line marks a relation that always holds and a dashed line marks a conditional one (the conditions are given per relation on the detail page). The full list of relations (11 in total, with evidence and certainty) and the definitions of the main concepts are collected on the knowledge map detail page (in Japanese). Data: JSON-LD / Turtle
Installing alr
Windows
For Windows, the GitHub releases page has an installer (for 2.1.1, alr-2.1.1-installer-x86_64-windows.exe). The installer creates a shortcut that opens PowerShell with alr already on the PATH4.
The first time you run alr, it asks whether to install MSYS2. MSYS2 is a collection of tools and libraries for building and running native Windows software, and it uses Pacman for package management5. Alire installs the tools it needs, such as git and make, and the external libraries that some crates use, from MSYS2. For that reason the documentation recommends installing MSYS24. If pacman is already on the PATH, Alire uses that MSYS2 and does not install a new one4.
Linux and macOS
On Linux and macOS, you extract the archive and add its bin folder to the PATH4. This article used the zip for Linux (x86-64).
unzip alr-2.1.1-bin-x86_64-linux.zip -d ~/alire
export PATH="$HOME/alire/bin:$PATH"
alr --version
alr 2.1.1
On macOS, a warning that the developer cannot be verified may stop it from launching. The documentation gives xattr -d com.apple.quarantine bin/alr as a way to remove the quarantine attribute4.
flowchart TB
accTitle: How to install alr on each OS
accDescr: Shows that on Windows you use the installer and decide on the first run whether to install MSYS2, and that on Linux and macOS you extract the archive and add it to the PATH.
S["Install alr"] --> W["Windows"]
S --> L["Linux and macOS"]
W --> WI["Run the installer"]
WI --> WF["The first alr run asks whether to install MSYS2"]
WF --> WP["If pacman is on the PATH, the existing MSYS2 is used"]
L --> LZ["Extract the archive"]
LZ --> LP["Add bin to the PATH"]
Figure 2: On Windows, install with the installer and MSYS2; on Linux and macOS, extract the archive.
Creating a project with alr init
A project that builds an executable is created with alr init --bin <name>. For a library, use --lib.
alr init --bin hello_alire
When you run it, it first asks for a description of the crate. The first time you use it, it then also asks for your name, your GitHub login, and your email address. You can skip these and change them later with alr settings. After that it asks for the license, tags, and website. The GitHub login is used to identify the maintainer when you publish to the community index4.
The files it created were these:
hello_alire/.gitignore
hello_alire/alire.toml
hello_alire/alire/alire.lock
hello_alire/alire/build_hash_inputs
hello_alire/alire/settings.toml
hello_alire/config/hello_alire_config.ads
hello_alire/config/hello_alire_config.gpr
hello_alire/config/hello_alire_config.h
hello_alire/hello_alire.gpr
hello_alire/src/hello_alire.adb
The .gitignore contained the following four lines. Alire regenerates the alire and config folders, so they stay out of version control. What goes into the repository is alire.toml, the .gpr file, and the sources under src.
/obj/
/bin/
/alire/
/config/
flowchart TB
accTitle: Files that alr init creates
accDescr: Shows the files that alr init creates, divided into those that go into the repository and those excluded because Alire regenerates them.
R["Files created by alr init"] --> K["Go into the repository"]
R --> X["Excluded (.gitignore)"]
K --> K1["alire.toml and .gpr"]
K --> K2["Sources under src"]
X --> X1["alire and config"]
X --> X2["obj and bin"]
X1 -.-> N["Regenerated by Alire"]
Figure 3: Put alire.toml, the .gpr file, and the sources in the repository, and exclude the folders that Alire creates.
The alire.toml manifest looks like this. It was created with -n (non-interactive), so the name and other fields contain default values.
name = "hello_alire"
description = ""
version = "0.1.0-dev"
authors = ["Your Name"]
maintainers = ["Your Name <example@example.com>"]
licenses = "MIT OR Apache-2.0 WITH LLVM-exception"
website = ""
tags = []
executables = ["hello_alire"]
The project file hello_alire.gpr reads config/hello_alire_config.gpr with with and takes the compiler switches from it. The build profile settings described later also reach the compiler through this generated file.
with "config/hello_alire_config.gpr";
project Hello_Alire is
for Source_Dirs use ("src/", "config/");
for Object_Dir use "obj/" & Hello_Alire_Config.Build_Profile;
for Create_Missing_Dirs use "True";
for Exec_Dir use "bin";
for Main use ("hello_alire.adb");
package Compiler is
for Default_Switches ("Ada") use Hello_Alire_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_Alire;
The first alr build installs GNAT
Running alr build with nothing configured, Alire chose a toolchain, downloaded it, and then built the project.
Note: Alire has selected automatically this toolchain:
gprbuild=26.0.1
gnat_native=16.1.0
You can select a different toolchain at any time with `alr toolchain --select`
Download will start now:
Note: Deploying gprbuild=26.0.1...
Note: gprbuild=26.0.1 installed successfully.
Note: Deploying gnat_native=16.1.0...
Note: gnat_native=16.1.0 installed successfully.
Note: Building hello_alire=0.1.0-dev/hello_alire.gpr...
...
Success: Build finished successfully in 0.61 seconds.
gnat_native is the name of the crate that represents the native compiler for the platform6. This environment also had GNAT 13.3.0 installed through apt, but Alire chose 16.1.0, which it distributes itself. Which version is chosen depends on the index at the time.
Next, edit src/hello_alire.adb and run alr run. alr run builds if needed and then starts the executable. Hello_Alire_Config is a package generated in the config folder, and it holds the selected build profile as a constant.
with Ada.Text_IO;
with Hello_Alire_Config;
procedure Hello_Alire is
begin
Ada.Text_IO.Put_Line ("Hello from Alire");
Ada.Text_IO.Put_Line
("Build profile: "
& Hello_Alire_Config.Build_Profile_Kind'Image
(Hello_Alire_Config.Build_Profile));
end Hello_Alire;
$ alr run
Note: Building hello_alire=0.1.0-dev/hello_alire.gpr...
...
Success: Build finished successfully in 0.59 seconds.
Hello from Alire
Build profile: DEVELOPMENT
flowchart TB
accTitle: The flow of the first build
accDescr: Shows that on the first alr build, if no toolchain has been selected, Alire selects and downloads one, generates the configuration files, builds with GPRbuild, and alr run runs the result.
B["alr build"] --> Q{"Is a toolchain selected?"}
Q -->|"No"| S["Alire selects and downloads one"]
Q -->|"Yes"| C["Generate settings in config"]
S --> C
C --> G["Build with GPRbuild"]
G --> E["Executable in bin"]
E --> R["Run with alr run"]
Figure 4: The first build fetches the toolchain, generates the settings, and then builds with GPRbuild.
Adding a dependency crate with alr with
You can search the crates in the index with alr search --crates <term>.
$ alr search --crates log
elogs Embedded logging, proven absent of runtime errors
gnatcoll_syslog GNAT Components Collection - syslog binding
journada Simple and nice configurable logging
loga Simple library for simple logging. Like npm package "debug", but for Ada
pico_ada_c04_pwm Chapter 4: Analog LED with PWM
prolog Simple Prolog library
simple_logging Simple logging to console
testlog Log test activity to support unit testing of Ada packages
utilada Utility Library with streams, processes, logs, serialization, encoders
Here we add simple_logging, which writes logs to the console.
$ alr with simple_logging
Requested changes:
+ simple_logging ^3.0.0 (add)
Changes to dependency solution:
+ simple_logging 3.0.0 (new)
Do you want to proceed?
Note: Deploying simple_logging=3.0.0...
The dependency is appended to the end of the manifest.
[[depends-on]]
simple_logging = "^3.0.0"
^3.0.0 accepts versions 3.0.0 and later with the same major number. Alire expresses crate versions with semantic versioning: ^ accepts newer versions within the same major number, and ~ accepts newer versions within the same minor number7. However, ^ and ~ get no special treatment for versions before 1.0. ^0.2 also means every version below 1.0, so the documentation recommends the ~0.x form for versions before 1.07.
After the dependency was added, with "simple_logging.gpr"; appeared at the top of the generated config/hello_alire_config.gpr. That is why you can with Simple_Logging from your sources without editing your own .gpr.
with Simple_Logging;
with Hello_Alire_Config;
procedure Hello_Alire is
package Log renames Simple_Logging;
begin
Log.Level := Log.Debug;
Log.Info ("Hello from Alire");
Log.Debug
("Build profile: "
& Hello_Alire_Config.Build_Profile_Kind'Image
(Hello_Alire_Config.Build_Profile));
end Hello_Alire;
$ alr run
...
Build Libraries
[gprlib] simple_logging.lexch
[archive] libsimple_logging.a
[index] libsimple_logging.a
...
Success: Build finished successfully in 4.58 seconds.
Hello from Alire
-->> Build profile: DEVELOPMENT
Because Log.Level was set to Debug, the Log.Debug message was printed too. That line starts with -->>.
You can check the resolved dependencies with alr with --solve or alr with --tree.
$ alr with --tree
hello_alire=0.1.0-dev
+-- simple_logging=3.0.0 (^3.0.0)
flowchart TB
accTitle: The flow of adding a dependency with alr with
accDescr: Shows alr with appending the dependency to the manifest, resolving the version, fetching the sources, and adding a with to the generated configuration file so the sources can use it.
W["alr with simple_logging"] --> M["Add depends-on to alire.toml"]
M --> S["Resolve the version (^3.0.0 → 3.0.0)"]
S --> D["Fetch the sources"]
D --> C["Add with to the .gpr in config"]
C --> U["Sources can with it"]
Figure 5: alr with writes the dependency into the manifest, resolves the version, and makes it usable through the configuration file.
alire.lock and pinning versions
The resolved versions are recorded in alire/alire.lock. However, this file sits inside the alire folder, which .gitignore excludes. The Alire documentation also says that alire.lock is an internal file that is regenerated as needed, so it does not need to be under version control8.
What the repository shares, then, is the version range written in the manifest, such as ^3.0.0. To fix a version to a single one, use alr pin. The pin is written into the manifest.
$ alr pin simple_logging
...
. simple_logging 3.0.0 (pin=3.0.0)
[[depends-on]]
simple_logging = "^3.0.0"
[[pins]]
simple_logging = { version='3.0.0' }
alr update re-resolves the unpinned dependencies against the configured index. With --online, it updates the index first. Pins can also point to a local folder or a git repository7. For example, you can use a library of your own that is still in development with alr with <name> --use=<path>.
flowchart TB
accTitle: Version ranges, pins, and the resolution result
accDescr: Shows alr resolving versions from the version ranges and pins written in the manifest, recording the result in alire.lock, and alire.lock staying out of version control.
M["depends-on in alire.toml (version range)"] --> S["alr resolves the versions"]
P["pins in alire.toml (fixed)"] --> S
S --> L["Recorded in alire/alire.lock"]
L --> X["Kept out of version control"]
U["alr update"] -.->|"Only unpinned dependencies"| S
Figure 6: What you share are the ranges and pins in the manifest; alire.lock is regenerated locally.
What build profiles change
Alire has three build profiles: Development, Release, and Validation. By default, your own crate is built with Development and dependency crates with Release7. You can change your own crate’s profile with a switch on alr build.
$ alr build --release
...
$ alr run --skip-build
Hello from Alire
-->> Build profile: RELEASE
alr run builds with the profile last used by alr build8.
The compiler switches for each profile are written to config/hello_alire_config.gpr. Here is what alr 2.1 wrote (the -gnaty… style checks are omitted).
| Profile | Main switches |
|---|---|
| Development | -Og -g -gnatwa -gnatVa |
| Release | -O3 -gnatn |
| Validation | -O3 -gnatn -g -gnato -gnatwa -gnatVa -gnatwe -gnata |
Only Validation includes -gnata. According to the GNAT documentation, -gnata is the switch that enables assertions such as preconditions, postconditions, type invariants, and predicates, and without it these assertions are disabled9. In other words, in a program built with the default alr build, the conditions written in Pre are not checked at run time.
Testing whether preconditions are checked
I checked this with the following program. Half assumes it only receives even numbers, and its precondition says so. The caller deliberately passes the odd number 7.
with Ada.Text_IO;
procedure Profile_Demo with SPARK_Mode is
function Half (X : Integer) return Integer
with Pre => X mod 2 = 0;
function Half (X : Integer) return Integer is (X / 2);
begin
Ada.Text_IO.Put_Line (Integer'Image (Half (7)));
end Profile_Demo;
Built with Development, the precondition was not checked: the program printed 3 and ended with exit code 0.
$ alr build
$ ./bin/profile_demo
3
Built with Validation, the precondition violation raised Assertion_Error, and the exit code was 1.
$ alr build --validation
$ ./bin/profile_demo
raised ADA.ASSERTIONS.ASSERTION_ERROR : failed precondition from profile_demo.adb:6
When you test a crate that has contracts, build with Validation, or specify the profile in the manifest’s [build-profiles]. With the following, even alr build without a switch used Validation.
[build-profiles]
profile_demo = "validation"
Dependency crates’ profiles can be set in the same table. You can also set the profile for everything from the command line, as in alr build --profiles='*=development'8.
flowchart TB
accTitle: Build profiles and precondition checks
accDescr: Shows that of the three build profiles Development, Release, and Validation, only Validation, which includes -gnata, checks preconditions at run time, and the other two do not.
P["Build profile"] --> D["Development (default)"]
P --> R["Release"]
P --> V["Validation"]
D --> N["No -gnata"]
R --> N
V --> A["-gnata present"]
N --> N2["Pre is not checked at run time"]
A --> A2["A Pre violation raises Assertion_Error"]
Figure 7: Preconditions are checked at run time only with Validation, which includes -gnata.
Choosing a toolchain
alr toolchain shows the toolchains available locally and the ones used by default.
$ alr toolchain
CRATE VERSION STATUS NOTES
gprbuild 18.0.0 Available Detected at /usr/bin/gprbuild
gprbuild 26.0.1 Default
gprbuild 2024.1.20231009 Available Provided by system package: gprbuild
gnat_native 16.1.0 Default
gnat_external 13.3.0 Available Detected at /usr/bin/gnat
Without arguments, alr toolchain --select shows an interactive selection screen; given a version, it makes that version the default. With --local, it sets the version used only in that working folder rather than in the global settings6.
$ alr toolchain --select --local gnat_native=15.2.1
Note: Deploying gnat_native=15.2.1...
Note: gnat_native=15.2.1 installed successfully.
Note: gnat_native=15.2.1 set as default in local configuration.
The --local choice was written to alire/settings.toml. That folder is excluded by .gitignore, so this choice is not shared with others. When a crate only works with certain compiler versions, the documentation shows how to express that as a dependency on gnat, such as gnat = ">=13"6.
The toolchain Alire chose is used by commands you run through alr exec. In the same terminal, the GNAT that was called changed depending on whether the command went through alr exec.
$ gnat --version
GNAT 13.3.0
$ alr exec -- gnat --version
GNAT 15.2.0
15.2.1 for gnat_native is the crate version; the compiler itself reported 15.2.0. alr exec sets up GPR_PROJECT_PATH and PATH before starting the command. alr printenv shows the same environment variables, so you can use it when running GPRbuild from an editor4.
flowchart TB
accTitle: The order in which Alire chooses a compiler
accDescr: Shows the order: if a dependency requires a target-specific compiler, use it; otherwise use the compiler the user selected; and if there is none, use what is in the user's environment.
Q1{"Does a dependency require a target-specific compiler?"} -->|"Yes"| C1["Use that compiler"]
Q1 -->|"No"| Q2{"Has the user selected a default?"}
Q2 -->|"Yes"| C2["Use the selected compiler"]
Q2 -->|"No"| C3["Use what is in the user's environment"]
Figure 8: The compiler is chosen in this order: what a dependency requires, what the user selected, what is in the environment.
This order comes from the Alire documentation. At every step, a compiler that has already been downloaded takes priority, and a new one is downloaded only when nothing suitable is available6. In this article’s environment, Alire selected the default automatically on the first build, so the second step applied.
Adding GNATprove as a dependency and proving code
GNATprove, which proves SPARK code, can also be added as a crate.
$ alr with gnatprove
...
+b gnatprove 16.1.0 (new,binary)
...
Note: Deploying gnatprove=16.1.0...
alr gnatprove is built into alr as an alias for alr exec -P1 -- gnatprove (it appears under ALIASES in alr help). -P1 means the crate’s .gpr is passed with -P as the first argument. Proving the Profile_Demo from earlier flagged the call that passes an odd number.
$ alr gnatprove
Phase 1 of 3: generation of data representation information ...
Phase 2 of 3: generation of Global contracts ...
Phase 3 of 3: flow analysis and proof ...
medium: precondition might fail
--> profile_demo.adb:11:41
11 | Ada.Text_IO.Put_Line (Integer'Image (Half (7)));
| ^~~~~~~
+ provers gave up before completing the proof
It found, without running anything, the call that printed 3 without an error in the Development build. However, the exit code of alr gnatprove was 0 here. By default, GNATprove returns exit code 0 even when some checks cannot be proved, and returns a nonzero code only with --checks-as-errors=on10.
$ alr gnatprove --checks-as-errors=on
...
gnatprove: unproved check messages considered as errors
ERROR: Command ["gnatprove", "-P", "profile_demo.gpr", "--checks-as-errors=on"] exited with code 1
Changing the call to Half (8) made every check prove.
$ alr gnatprove --checks-as-errors=on --report=all
...
info: precondition proved
--> profile_demo.adb:11:41
Success: all checks proved (4 checks).
To make a CI job fail when some checks cannot be proved, add --checks-as-errors=on. GNATprove proof levels and how to write contracts are explained in “Introduction to Formal Verification with SPARK”.
flowchart TB
accTitle: alr gnatprove results and exit codes
accDescr: Shows that when alr gnatprove has unproved checks, the exit code is 0 by default and 1 with checks-as-errors, and that it is 0 when everything is proved.
G["alr gnatprove"] --> Q{"Are there unproved checks?"}
Q -->|"No"| OK["all checks proved, exit code 0"]
Q -->|"Yes"| O{"--checks-as-errors=on?"}
O -->|"No"| Z["Shows the findings, exit code 0"]
O -->|"Yes"| F["Shows the findings, exit code 1"]
Figure 9: Even with unproved checks, the default exit code is 0. In CI, add –checks-as-errors=on.
What alr test checks
alr test is not a command that runs unit tests. Run without arguments in the crate you are working on, it runs the test action if the manifest has one, and otherwise runs alr build --release (alr help test). Given a crate name as an argument, it fetches the versions in the index and tries in bulk whether they build.
A test action is written in the manifest with type = "test". When there is an action, the crate is not built first, so if a build is needed, include that command in the action as well7. The following example runs the proof as the test.
[[actions]]
type = "test"
command = ["alr", "gnatprove", "--checks-as-errors=on"]
$ alr test
Note: Synchronizing workspace...
Nothing to update.
Success: Test ended successfully.
After changing the call back to Half (7), alr test ended with exit code 1.
$ alr test
ERROR: Local test of profile_demo=0.1.0-dev failed:
ERROR: Check alire/alr_test_local.log for details.
In this environment, the alr called from alr test was looked up from the PATH. At first, a different version of alr installed through apt came first on the PATH, and that one ran and failed. When you have several versions installed, check the order of the PATH.
As a layout for writing unit tests, the documentation shows creating a test crate under the main crate and pinning the main crate to it by relative path. That way, dependencies used only for tests, such as AUnit, stay out of the main crate’s manifest7.
# tests/alire.toml
[[depends-on]]
my_crate = "*"
aunit = "*"
[[pins]]
my_crate = { path = ".." }
flowchart TB
accTitle: What alr test runs
accDescr: Shows that alr test without arguments runs the action of type test if the manifest has one, and otherwise runs alr build --release.
T["alr test (no arguments)"] --> Q{"Is there an action with type = test?"}
Q -->|"Yes"| A["Run the action (no build)"]
Q -->|"No"| B["alr build --release"]
A --> R["Success or failure by exit code"]
B --> R
Figure 10: alr test runs either the test action or a Release build.
Publishing a crate
To publish a crate you made to the community index, use alr publish. This was not tried in this article’s environment, so here is only the flow described in the documentation2.
- Commit the version you want to publish and push it to a git repository on a trusted site such as GitHub. Leave the working tree with no changes.
- Create a GitHub Personal Access Token (classic) with the
public_reposcope. Put it in theGH_TOKENenvironment variable, or enter it whenalrasks. - Run
alr publishat the root of the repository.alrchecks the contents, forks alire-index, and creates a pull request.
flowchart TB
accTitle: The flow of publishing a crate with alr publish
accDescr: Shows the flow: commit and push the version to publish, prepare a Personal Access Token, and run alr publish; alr forks alire-index and creates a pull request, and the first submission is reviewed and approved by a person.
C["Commit and push the version"] --> T["Prepare a Personal Access Token"]
T --> P["Run alr publish"]
P --> F["Fork alire-index"]
F --> R["Create a pull request"]
R --> A["A person reviews and approves the first submission"]
Figure 11: alr publish creates a pull request to the index from a version you have already pushed.
The first submission of a new crate is approved after a person reviews it. After that, only the maintainers listed in maintainers-logins in the manifest can submit new versions2. For crates used only within your organization, --for-private-index creates a manifest for your own index without submitting to the community index8.
Related articles
- The Appeal of the Ada Language — Expressing Design Through Types and Powering Software That Runs for Decades
- Introduction to Formal Verification with SPARK — From Ada Contracts to Mathematical Proof
- Proving AI-Written Code with SPARK
- Memory Management in Ada
References
-
Alire, Documentation. Describes the
alire.tomlmanifest, the build environment, and the catalog format. ↩ -
Alire, Publishing your projects in Alire.
alr publish, the Personal Access Token, and the review of submissions to the index. ↩ ↩2 ↩3 -
AdaCore, Building with GPRbuild. What GPRbuild is and project files. ↩
-
Alire, Getting Started. Installation for each OS, MSYS2, the
alr initquestions, andalr printenv. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 -
Alire, Toolchain management.
gnat_native,alr toolchain --select, the order in which compilers are chosen, and dependencies ongnat. ↩ ↩2 ↩3 ↩4 -
Alire, Catalog format specification. Version specifications in
depends-on, actions, pins, build profiles and switches, and the layout of test crates. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 -
Alire, User-facing changes log. The location and handling of
alire.lock,alr build --profiles, andalr runusing the last profile. ↩ ↩2 ↩3 ↩4 -
GCC, Alphabetical List of All Switches (GNAT User’s Guide). The assertions that
-gnataenables and the default when it is not specified. ↩ -
AdaCore, How to Run GNATprove (SPARK User’s Guide). Exit codes and
--checks-as-errors=on. ↩
Related Articles
Recent articles sharing the same tags. Deepen your understanding with closely related topics.
The Appeal of the Ada Language — Expressing Design Through Types and Powering Software That Runs for Decades
An introduction to the appeal of the Ada language: strong typing, range constraints, separation of specification and implementation via p...
Generic Programming in Ada — Contracts, Types, and Zero-Cost Reuse
A systematic introduction to generic programming in Ada. Covers generic subprograms, generic packages, formal subprogram parameters, type...
Introduction to Formal Verification with SPARK — From Ada Contracts to Mathematical Proof
A practical introduction to formal verification using the SPARK subset of Ada. Covers how to step up from contracts (Pre/Post) to proofs,...
Memory Management in Ada — When to Use Access Types, Controlled Types, and Storage Pools
Ada does not rely on GC: values go on the stack first, and when the heap is needed, access types put lifetime rules into types. Deallocat...
How Ada and Rust Think About Safety — Comparing Types, Overflow, Ownership, Data Races, and Formal Verification by Running Them
Ada and Rust both put safety first, but they stop errors in different places. We compare value ranges, overflow, memory, data races, unch...
Related Topics
These are topic pages close to this theme. Starting from the article, you can go on to related services and other articles.
Windows Technical Topics
Entry point collecting technical topics on Windows development, bug investigation, and use of existing assets.
Services Connected to This Topic
This article leads to the following service pages. Start from the entry point closest to your situation.
Technical Consulting & Design Review
If you want to decide whether to standardize your Ada development environment on Alire, or how to migrate existing GPR projects, we can take this on as technical consulting and design review.
Modification & Maintenance of Existing Windows Software
If you maintain existing software written in Ada and run into problems such as each developer using a different compiler version or a build environment you cannot reproduce, that is a good fit for modernization and maintenance work.
Frequently Asked Questions
Questions commonly asked at the time of consultation about the topic of this article.
- What is Alire?
- It is the package manager for Ada and SPARK. Its command is alr, and it handles creating projects (crates), fetching dependency crates, fetching and selecting GNAT and GPRbuild, and building and running, all in one tool.
- Do I need to install GNAT separately to use Alire?
- On x86-64 Linux, Windows, and macOS, Alire downloads GNAT and GPRbuild on the first build and uses them. In the Linux environment used for this article, gnat_native 16.1.0 and gprbuild 26.0.1 were selected without installing anything by hand. You can also configure it to use a GNAT installed on the system.
- Should alire.lock be put under version control?
- The Alire documentation says alire.lock is an internal file that is regenerated as needed, so it does not need to be under version control. The .gitignore that alr init creates also excludes the alire folder that holds it. To fix a dependency's version, use alr pin, which writes the pin into the alire.toml manifest.
- Are preconditions (Pre) checked in a program built with alr build?
- They were not checked with the default Development profile, because the Development switches do not include -gnata. With the Validation profile (alr build --validation), -gnata is added, and a call that did not satisfy the precondition raised Assertion_Error.
- Is alr test a command that runs unit tests?
- It has no testing framework of its own. If the manifest has an action with type = "test", it runs that; otherwise it runs alr build --release to check that the crate builds. For unit tests, the Alire documentation recommends a layout where you create a separate test crate and pin the main crate to it by relative path.
Author Profile
Profile page for the article author.
Go Komura
Representative of KomuraSoft LLC
Focused on Windows software development, technical consulting, and bug investigation, with particular strength in projects where existing assets remain and in investigating failures whose cause is hard to see.