更新履歴(初版のみ・2026年11月01日公開)
- 初版公開
この記事を引用する(DOI: 10.5281/zenodo.23855029)
この記事はZenodoにアーカイブされています。常に最新版へ解決されるDOIと、いま表示している版に固定されたDOIの両方を下に示します。
小村 豪(2026)「Alire で Ada のプロジェクトを始める ── プロジェクト作成、依存の追加、ビルドプロファイル、GNATproveまで」合同会社小村ソフト. https://doi.org/10.5281/zenodo.23855029 https://comcomponent.com/blog/alire-getting-started/
- DOI(最新版)
- 10.5281/zenodo.23855029
- DOI(この版)
- 10.5281/zenodo.23855030
Ada でプログラムを書き始めるとき、コンパイラの GNAT をどこから入れるか、ライブラリをどう取ってくるかで手が止まることがあります。Alire はこの2つをまとめて扱う、Ada と SPARK のパッケージマネージャーです。コマンドの alr がプロジェクトの作成、依存するライブラリの取得、GNAT と GPRbuild の取得、ビルドと実行を受け持ちます。
この記事では alr init でプロジェクトを作ってから、依存を足し、ビルドプロファイルを切り替え、GNATprove で証明するところまでを順に説明します。途中で、既定のビルドでは事前条件が検査されないことも実際の出力で確かめます。
コマンドと出力は 2026年11月1日に Ubuntu(x86-64)で alr 2.1.0 と、執筆時点で最新の alr 2.1.1 を使って実行したものです。どちらのバージョンでも同じ結果になりました。長い出力は一部を省いています。Windows のインストーラーと MSYS2 の手順はこの環境では試していないので、Alire の資料に書かれている内容だけを書きます。
Ada そのものについては「Ada言語の魅力」、SPARK と GNATprove については「SPARKによる形式検証入門」で扱っています。
Alire が受け持つもの
Alire では配布や依存の単位をクレートと呼びます。クレートのルートには alire.toml というマニフェストがあり、名前・バージョン・依存するクレートなどを TOML 形式で書きます1。公開されたクレートの情報はコミュニティのインデックス(GitHub の alire-index リポジトリ)に集められていて、alr はそこから依存の候補を探します2。
ビルドには GPRbuild を使います。GPRbuild はプロジェクトファイル(.gpr)を読んで複数の言語で書かれたシステムをビルドするツールです3。alr build は GPR_PROJECT_PATH などの環境変数を整えてから GPRbuild を呼び出します4。
flowchart TB
accTitle: Alireを構成するもの
accDescr: alrコマンドがマニフェストを読み、インデックスから依存クレートを、Alireが配るGNATとGPRbuildを取得し、GPRbuildでビルドする関係を示す。
U["開発者"] --> A["alr コマンド"]
A --> M["alire.toml(マニフェスト)"]
A --> I["コミュニティのインデックス"]
I --> D["依存クレート"]
A --> T["GNAT と GPRbuild"]
A --> G["GPRbuild でビルド"]
D --> G
T --> G
図1: alr はマニフェストを読み、依存クレートとツールチェーンを取得して、GPRbuild でビルドする。
図の実線は常に成り立つ関係、破線は条件付きの関係です(成立条件は詳細ページの各関係の説明に記載)。関係すべての一覧(全11件、根拠・確度つき)と主要概念の定義は知識マップ詳細ページにまとめています。データ: JSON-LD / Turtle
alr を入れる
Windows
Windows 向けには GitHub のリリースページにインストーラー(2.1.1 なら alr-2.1.1-installer-x86_64-windows.exe)があります。インストーラーは alr を PATH に入れた状態で PowerShell を開くショートカットを作ります4。
最初に alr を実行すると、MSYS2 を入れるかを聞かれます。MSYS2 は Windows のネイティブなソフトウェアをビルドして動かすためのツールとライブラリの集まりで、パッケージ管理に Pacman を使います5。Alire は git や make のような必要なツールと、一部のクレートが使う外部のライブラリを MSYS2 から入れます。そのため、資料は MSYS2 を入れることを勧めています4。すでに pacman が PATH にあれば、その MSYS2 を使い、新しくは入れません4。
Linux と macOS
Linux と macOS では、アーカイブを展開して bin フォルダーを PATH に足します4。この記事では Linux(x86-64)用の zip を使いました。
unzip alr-2.1.1-bin-x86_64-linux.zip -d ~/alire
export PATH="$HOME/alire/bin:$PATH"
alr --version
alr 2.1.1
macOS では開発元を確認できないという警告が出て起動できないことがあります。資料は xattr -d com.apple.quarantine bin/alr で隔離の属性を外す方法を挙げています4。
flowchart TB
accTitle: OSごとのalrの入れ方
accDescr: Windowsではインストーラーを使い、初回の実行でMSYS2を入れるかを決め、LinuxとmacOSではアーカイブを展開してPATHに足す流れを示す。
S["alr を入れる"] --> W["Windows"]
S --> L["Linux・macOS"]
W --> WI["インストーラーを実行"]
WI --> WF["初回の alr で MSYS2 を入れるか聞かれる"]
WF --> WP["pacman が PATH にあれば既存の MSYS2 を使う"]
L --> LZ["アーカイブを展開"]
LZ --> LP["bin を PATH に足す"]
図2: Windows はインストーラーと MSYS2、Linux と macOS はアーカイブの展開で入れる。
alr init でプロジェクトを作る
実行ファイルを作るプロジェクトは alr init --bin <名前> で作ります。ライブラリなら --lib です。
alr init --bin hello_alire
実行すると、まずクレートの説明を聞かれます。初めて使うときは、続けて名前、GitHub のログイン名、メールアドレスも聞かれます。これらは省略でき、あとから alr settings で変えられます。そのあとライセンス、タグ、Web サイトを聞かれます。GitHub のログイン名はコミュニティのインデックスに公開するときに管理者を示すのに使われます4。
作られたファイルは次のとおりです。
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
.gitignore には次の4行が書かれていました。alire と config のフォルダーは Alire が作り直すので、バージョン管理には入れません。リポジトリに入れるのは、alire.toml、.gpr ファイル、src の下のソースです。
/obj/
/bin/
/alire/
/config/
flowchart TB
accTitle: alr initが作るファイル
accDescr: alr initが作るファイルを、リポジトリに入れるものと、Alireが作り直すため除外するものに分けて示す。
R["alr init が作るファイル"] --> K["リポジトリに入れる"]
R --> X["除外する(.gitignore)"]
K --> K1["alire.toml と .gpr"]
K --> K2["src の下のソース"]
X --> X1["alire と config"]
X --> X2["obj と bin"]
X1 -.-> N["Alire が作り直す"]
図3: alire.toml と .gpr とソースをリポジトリに入れ、Alire が作るフォルダーは除外する。
マニフェストの alire.toml は次のとおりです。-n(対話なし)で作ったので、名前などには既定の値が入っています。
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"]
プロジェクトファイルの hello_alire.gpr は config/hello_alire_config.gpr を with で読み込み、コンパイラのスイッチをそこから受け取ります。後で説明するビルドプロファイルの設定も、この生成されたファイルを通してコンパイラに渡ります。
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;
最初の alr build で GNAT が入る
設定が何もない状態で alr build を実行すると、Alire がツールチェーンを選んでダウンロードしてから、ビルドしました。
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 はそのプラットフォーム向けのネイティブコンパイラを表すクレートの名前です6。この環境には apt で入れた GNAT 13.3.0 もありましたが、Alire は自身が配布する 16.1.0 を選びました。選ばれるバージョンはそのときのインデックスによって変わります。
このあと、src/hello_alire.adb を書き換えて alr run を実行します。alr run は必要ならビルドしてから実行ファイルを起動します。Hello_Alire_Config は config フォルダーに生成されたパッケージで、選んだビルドプロファイルを定数として持っています。
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: 最初のビルドの流れ
accDescr: 最初のalr buildでツールチェーンが選ばれていなければAlireが選んでダウンロードし、設定ファイルを生成してからGPRbuildでビルドし、alr runで実行する流れを示す。
B["alr build"] --> Q{"ツールチェーンは選ばれているか"}
Q -->|"いいえ"| S["Alire が選んでダウンロード"]
Q -->|"はい"| C["config に設定を生成"]
S --> C
C --> G["GPRbuild でビルド"]
G --> E["bin に実行ファイル"]
E --> R["alr run で実行"]
図4: 最初のビルドでツールチェーンを取得し、設定を生成してから GPRbuild でビルドする。
alr with で依存クレートを足す
インデックスにあるクレートは alr search --crates <語> で探せます。
$ 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
ここではコンソールにログを出す simple_logging を足します。
$ 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...
マニフェストの末尾に依存が書き足されます。
[[depends-on]]
simple_logging = "^3.0.0"
^3.0.0 は 3.0.0 以上でメジャー番号が同じバージョンを受け入れる指定です。Alire ではクレートのバージョンをセマンティックバージョニングで表し、^ は同じメジャー番号の中の新しいバージョンを、~ は同じマイナー番号の中の新しいバージョンを受け入れます7。ただし、1.0 より前のバージョンでは ^ と ~ に特別な扱いはありません。^0.2 も 1.0 未満のすべてのバージョンを意味するので、資料は 1.0 より前のバージョンには ~0.x の形を使うよう勧めています7。
依存を足したあと、生成される config/hello_alire_config.gpr の先頭に with "simple_logging.gpr"; が入りました。そのため、自分の .gpr を書き換えなくても、ソースから Simple_Logging を with できます。
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
Log.Level を Debug にしたので、Log.Debug のメッセージも表示されました。その行の先頭には -->> が付いています。
依存の解決結果は alr with --solve や alr with --tree で確かめられます。
$ alr with --tree
hello_alire=0.1.0-dev
+-- simple_logging=3.0.0 (^3.0.0)
flowchart TB
accTitle: alr withで依存を足す流れ
accDescr: alr withがマニフェストに依存を書き足し、バージョンを解決してソースを取得し、生成する設定ファイルにwithを入れてソースから使えるようにする流れを示す。
W["alr with simple_logging"] --> M["alire.toml に depends-on を追加"]
M --> S["バージョンを解決(^3.0.0 → 3.0.0)"]
S --> D["ソースを取得"]
D --> C["config の .gpr に with を追加"]
C --> U["ソースから with できる"]
図5: alr with は依存をマニフェストに書き、バージョンを解決して、設定ファイル経由で使えるようにする。
alire.lock とバージョンの固定
解決したバージョンは alire/alire.lock に記録されます。ただし、このファイルは alire フォルダーの中にあり、.gitignore で除外されています。Alire の資料も、alire.lock は内部用のファイルで、必要に応じて作り直されるため、バージョン管理に入れなくてよいとしています8。
そのため、リポジトリで共有されるのは、マニフェストに書いた ^3.0.0 のようなバージョンの範囲です。バージョンをひとつに固定したいときは alr pin を使います。固定はマニフェストに書かれます。
$ 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 は、固定していない依存を、設定されたインデックスで解決し直します。--online を付けると、先にインデックスを更新します。固定はほかに、ローカルのフォルダーや git リポジトリにも向けられます7。開発中の自作ライブラリを alr with <名前> --use=<パス> で使う、といった場合です。
flowchart TB
accTitle: バージョンの範囲と固定と解決結果
accDescr: マニフェストに書いたバージョンの範囲とpinsからalrがバージョンを解決し、その結果をalire.lockに記録し、alire.lockはバージョン管理に入れないことを示す。
M["alire.toml の depends-on(バージョンの範囲)"] --> S["alr がバージョンを解決"]
P["alire.toml の pins(固定)"] --> S
S --> L["alire/alire.lock に記録"]
L --> X["バージョン管理には入れない"]
U["alr update"] -.->|"固定していない依存だけ"| S
図6: 共有するのはマニフェストの範囲と固定で、alire.lock は手元で作り直される。
ビルドプロファイルで変わるもの
Alire のビルドプロファイルは Development、Release、Validation の3つです。既定では、自分のクレートが Development、依存クレートが Release でビルドされます7。自分のクレートのプロファイルは alr build のスイッチで変えられます。
$ alr build --release
...
$ alr run --skip-build
Hello from Alire
-->> Build profile: RELEASE
alr run は最後に alr build で使ったプロファイルでビルドします8。
プロファイルごとのコンパイラのスイッチは config/hello_alire_config.gpr に書き出されます。alr 2.1 が書き出した内容は次のとおりです(スタイル検査の -gnaty… は省いています)。
| プロファイル | 主なスイッチ |
|---|---|
| Development | -Og -g -gnatwa -gnatVa |
| Release | -O3 -gnatn |
| Validation | -O3 -gnatn -g -gnato -gnatwa -gnatVa -gnatwe -gnata |
-gnata を含むのは Validation だけです。GNAT の資料によると、-gnata は事前条件・事後条件・型不変条件・述語などの表明を有効にするスイッチで、指定しないときはこれらの表明が無効になると書かれています9。つまり、既定の alr build で作ったプログラムでは、Pre に書いた条件が実行時に検査されません。
事前条件が検査されるかを試す
次のプログラムで確かめました。Half は偶数だけを受け取る前提で、事前条件にそう書いています。呼び出し側はわざと奇数の 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;
Development でビルドすると、事前条件は検査されず、そのまま 3 を表示して終了コード 0 で終わりました。
$ alr build
$ ./bin/profile_demo
3
Validation でビルドすると、事前条件の違反で Assertion_Error が発生し、終了コードは 1 でした。
$ alr build --validation
$ ./bin/profile_demo
raised ADA.ASSERTIONS.ASSERTION_ERROR : failed precondition from profile_demo.adb:6
契約を書いたクレートを試験するときは、Validation でビルドするか、マニフェストの [build-profiles] でプロファイルを指定します。次のように書くと、スイッチを付けない alr build でも Validation になりました。
[build-profiles]
profile_demo = "validation"
依存クレートのプロファイルも同じ表で指定できます。alr build --profiles='*=development' のように、コマンドラインから全体を指定することもできます8。
flowchart TB
accTitle: ビルドプロファイルと事前条件の検査
accDescr: Development・Release・Validationの3つのビルドプロファイルのうち、-gnataを含むValidationだけで事前条件が実行時に検査され、ほかの2つでは検査されないことを示す。
P["ビルドプロファイル"] --> D["Development(既定)"]
P --> R["Release"]
P --> V["Validation"]
D --> N["-gnata なし"]
R --> N
V --> A["-gnata あり"]
N --> N2["Pre は実行時に検査されない"]
A --> A2["Pre の違反で Assertion_Error"]
図7: 事前条件が実行時に検査されるのは、-gnata を含む Validation だけ。
ツールチェーンを選ぶ
alr toolchain は手元にあるツールチェーンと、既定で使うものを表示します。
$ 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
alr toolchain --select は、引数なしなら対話で選ぶ画面を出し、バージョンを指定すればそれを既定にします。--local を付けると、設定全体ではなくその作業フォルダーだけで使うバージョンを決めます6。
$ 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.
--local の選択は alire/settings.toml に書かれました。このフォルダーは .gitignore で除外されているので、この選択はほかの人には共有されません。クレートを動かせるコンパイラのバージョンに制約があるときは、gnat = ">=13" のように gnat への依存として書く方法が資料に示されています6。
Alire が選んだツールチェーンは alr exec で動かすコマンドから使えます。同じ端末でも、alr exec を通すかで呼ばれる GNAT が変わりました。
$ gnat --version
GNAT 13.3.0
$ alr exec -- gnat --version
GNAT 15.2.0
gnat_native の 15.2.1 はクレートのバージョンで、コンパイラ自身は 15.2.0 と表示しました。alr exec は GPR_PROJECT_PATH や PATH を整えてからコマンドを起動します。同じ環境変数は alr printenv で表示できるので、エディターから GPRbuild を動かすときに使えます4。
flowchart TB
accTitle: Alireがコンパイラを選ぶ順序
accDescr: 依存がターゲット専用のコンパイラを求めていればそれを使い、なければ利用者が選んだコンパイラを使い、それもなければ利用者の環境にあるものを使う順序を示す。
Q1{"依存がターゲット専用のコンパイラを求めるか"} -->|"はい"| C1["そのコンパイラを使う"]
Q1 -->|"いいえ"| Q2{"利用者が既定を選んだか"}
Q2 -->|"はい"| C2["選んだコンパイラを使う"]
Q2 -->|"いいえ"| C3["利用者の環境にあるものを使う"]
図8: コンパイラは、依存が求めるもの、利用者が選んだもの、環境にあるものの順に選ばれる。
この順序は Alire の資料によるものです。どの段でも、すでにダウンロードしてあるコンパイラが優先され、合うものがないときだけ新しくダウンロードします6。この記事の環境では、最初のビルドで Alire が既定を自動で選んだので、2段目が当てはまりました。
GNATprove を依存に入れて証明する
SPARK のコードを証明する GNATprove も、クレートとして入れられます。
$ alr with gnatprove
...
+b gnatprove 16.1.0 (new,binary)
...
Note: Deploying gnatprove=16.1.0...
alr gnatprove は alr exec -P1 -- gnatprove の別名として alr に組み込まれています(alr help の ALIASES に表示されます)。-P1 は1番目の引数としてクレートの .gpr を -P で渡す指定です。先ほどの Profile_Demo を証明すると、奇数を渡す呼び出しが指摘されました。
$ 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
Development のビルドではエラーを出さずに 3 を表示した呼び出しを、実行せずに見つけています。ただし、このときの alr gnatprove の終了コードは 0 でした。GNATprove は証明できない検査があっても既定では終了コード 0 を返し、--checks-as-errors=on を付けたときだけ 0 以外を返します10。
$ 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
呼び出しを Half (8) に直すと、すべての検査が証明されました。
$ alr gnatprove --checks-as-errors=on --report=all
...
info: precondition proved
--> profile_demo.adb:11:41
Success: all checks proved (4 checks).
証明できない検査があったときに CI のジョブを失敗させるには、--checks-as-errors=on を付けます。GNATprove の証明レベルや契約の書き方は「SPARKによる形式検証入門」で説明しています。
flowchart TB
accTitle: alr gnatproveの結果と終了コード
accDescr: alr gnatproveで証明できない検査があったとき、既定では終了コード0、checks-as-errorsを付けると終了コード1になり、すべて証明できれば0になることを示す。
G["alr gnatprove"] --> Q{"証明できない検査があるか"}
Q -->|"ない"| OK["all checks proved・終了コード 0"]
Q -->|"ある"| O{"--checks-as-errors=on か"}
O -->|"いいえ"| Z["指摘を表示・終了コード 0"]
O -->|"はい"| F["指摘を表示・終了コード 1"]
図9: 証明できない検査があっても、既定の終了コードは 0。CI では –checks-as-errors=on を付ける。
alr test が確かめるもの
alr test は単体テストを実行するコマンドではありません。作業中のクレートで引数なしに実行すると、マニフェストにテスト用のアクションがあればそれを実行し、なければ alr build --release を実行します(alr help test)。引数にクレート名を与えると、インデックスにあるバージョンを取得してビルドできるかをまとめて試します。
テスト用のアクションはマニフェストに type = "test" で書きます。アクションがあるときはクレートを先にビルドしないので、ビルドが要るなら、そのコマンドもアクションに含めます7。次の例では証明をテストとして実行しています。
[[actions]]
type = "test"
command = ["alr", "gnatprove", "--checks-as-errors=on"]
$ alr test
Note: Synchronizing workspace...
Nothing to update.
Success: Test ended successfully.
Half (7) に戻すと、alr test は終了コード 1 で終わりました。
$ alr test
ERROR: Local test of profile_demo=0.1.0-dev failed:
ERROR: Check alire/alr_test_local.log for details.
この環境では、alr test から呼ばれる alr は PATH から探されました。最初は PATH に apt で入れた別のバージョンの alr が先にあり、そちらが動いて失敗しました。複数のバージョンを入れているときは、PATH の順序を確かめておきます。
単体テストを書くときの構成として、資料はテスト用のクレートを本体の下に作り、本体のクレートを相対パスで固定する形を示しています。テストだけに使う AUnit などの依存を本体のマニフェストに入れずに済みます7。
# tests/alire.toml
[[depends-on]]
my_crate = "*"
aunit = "*"
[[pins]]
my_crate = { path = ".." }
flowchart TB
accTitle: alr testが実行するもの
accDescr: 引数なしのalr testは、マニフェストにtype testのアクションがあればそれを実行し、なければalr build --releaseを実行することを示す。
T["alr test(引数なし)"] --> Q{"type = test のアクションがあるか"}
Q -->|"ある"| A["アクションを実行(ビルドはしない)"]
Q -->|"ない"| B["alr build --release"]
A --> R["終了コードで成否"]
B --> R
図10: alr test はテスト用のアクションか、Release でのビルドを実行する。
クレートを公開するとき
作ったクレートをコミュニティのインデックスに公開するには alr publish を使います。この記事の環境では試していないので、資料に書かれている流れだけを示します2。
- 公開するバージョンをコミットし、GitHub などの信頼されたサイトにある git リポジトリへプッシュする。作業ツリーは変更のない状態にしておく。
- GitHub の Personal Access Token(classic)を、
public_repoの権限で作る。環境変数GH_TOKENに入れるか、alrに聞かれたときに入力する。 - リポジトリのルートで
alr publishを実行する。alrは内容を確かめ、alire-index をフォークして、プルリクエストを作る。
flowchart TB
accTitle: alr publishでクレートを公開する流れ
accDescr: 公開するバージョンをコミットしてプッシュし、Personal Access Tokenを用意してalr publishを実行すると、alrがalire-indexのフォークとプルリクエストを作り、最初の登録は人が確認して承認する流れを示す。
C["バージョンをコミットしてプッシュ"] --> T["Personal Access Token を用意"]
T --> P["alr publish を実行"]
P --> F["alire-index をフォーク"]
F --> R["プルリクエストを作成"]
R --> A["最初の登録は人が確認して承認"]
図11: alr publish はプッシュ済みのバージョンからインデックスへのプルリクエストを作る。
新しいクレートの最初の登録は人が確認してから承認されます。その後のバージョンはマニフェストの maintainers-logins に書かれた管理者だけが登録できます2。社内だけで使うクレートは、--for-private-index を付けると、コミュニティのインデックスへ提出せずに、自前のインデックス向けのマニフェストを作れます8。
関連記事
- Ada言語の魅力 ── 型で設計を語り、数十年動き続けるソフトウェアを支える言語
- SPARKによる形式検証入門 ── Adaの契約から数学的証明へ
- AIが書いたコードを SPARK で証明する
- Ada のメモリ管理
参考リンク
-
Alire, Documentation. マニフェスト
alire.toml、ビルド環境、カタログの書式の説明。 ↩ -
Alire, Publishing your projects in Alire.
alr publish、Personal Access Token、インデックスへの登録の確認。 ↩ ↩2 ↩3 -
AdaCore, Building with GPRbuild. GPRbuild の位置づけとプロジェクトファイル。 ↩
-
Alire, Getting Started. OSごとの入れ方、MSYS2、
alr initの質問、alr printenv。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 -
Alire, Toolchain management.
gnat_native、alr toolchain --select、コンパイラが選ばれる順序、gnatへの依存。 ↩ ↩2 ↩3 ↩4 -
Alire, Catalog format specification.
depends-onのバージョンの指定、アクション、固定(pins)、ビルドプロファイルとスイッチ、テスト用のクレートの構成。 ↩ ↩2 ↩3 ↩4 ↩5 ↩6 -
Alire, User-facing changes log.
alire.lockの位置と扱い、alr build --profiles、alr runが最後のプロファイルを使うこと。 ↩ ↩2 ↩3 ↩4 -
GCC, Alphabetical List of All Switches (GNAT User’s Guide).
-gnataが有効にする表明と、指定しないときの既定。 ↩ -
AdaCore, How to Run GNATprove (SPARK User’s Guide). 終了コードと
--checks-as-errors=on。 ↩
関連する記事
同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。
Ada言語の魅力 ── 型で設計を語り、数十年動き続けるソフトウェアを支える言語
Ada言語の魅力を紹介します。強い型付け、範囲制約、パッケージによる仕様と実装の分離、契約による設計、言語組み込みのタスク、SPARKによる形式検証、GNATとAlireでの開発環境まで、高信頼ソフトウェアを支える設計思想を整理します。
Adaのジェネリックプログラミング ── 型で契約を書き、再利用をゼロコストで実現する
Adaのジェネリックプログラミングを、総称サブプログラム、総称パッケージ、仮サブプログラム、型カテゴリ、実務上の設計指針まで体系的に解説します。型安全な再利用とゼロコスト抽象化の考え方を整理します。
SPARKによる形式検証入門 ── Adaの契約から数学的証明へ
Adaのサブセット言語SPARKによる形式検証の実践的な入門記事です。契約(Pre/Post)から証明へステップアップする方法、GNATproveの使い方、ループ不変条件、データフロー契約、証明レベル、そして実プロジェクトへの適用方法までを整理します。
Adaのメモリ管理 ── アクセス型・Controlled型・ストレージプールの使い分け
AdaはGCに頼らず、まず値をスタックに置き、ヒープが要るときはアクセス型で寿命の規則を型に書きます。解放の危うさ、Controlled型での後始末、ストレージプールでの確保先の制御を、GNATで動かした例で説明します。
Ada と Rust の安全性の考え方の違い ── 型・オーバーフロー・所有権・データ競合・形式検証を実際に動かして比べる
Ada と Rust はどちらも安全性を重視する言語ですが、誤りを止める場所が違います。値の範囲、整数オーバーフロー、メモリ、データ競合、検査を外す仕組み、形式検証の6点を、GNAT・GNATprove・rustc で実際に動かして比べます。
関連トピック
このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。
Windows技術トピック
Windows 開発、不具合調査、既存資産活用の技術トピックをまとめた入口です。
このテーマがつながるサービス
この記事は次のサービスページにつながります。近い入口からご覧ください。
技術相談・設計レビュー
Adaの開発環境をAlireにそろえるか、既存のGPRプロジェクトをどう移すかを決めたい場合に、技術相談・設計レビューとして扱えます。
既存Windowsソフトの改修・保守
Adaで書かれた既存のソフトを保守していて、開発者ごとにコンパイラのバージョンが違う、ビルド環境を再現できないといった問題がある場合は、改修・保守の題材として進めやすいものです。
よくある質問
この記事のテーマについて、相談時によくある質問をまとめています。
- Alireとは何ですか?
- AdaとSPARKのパッケージマネージャーです。コマンドは alr で、プロジェクト(クレート)の作成、依存クレートの取得、GNATとGPRbuildの取得と選択、ビルドと実行をまとめて扱います。
- AlireでGNATを別に入れる必要はありますか?
- x86-64のLinux・Windows・macOSでは、Alireが初回のビルドでGNATとGPRbuildをダウンロードして使います。この記事のLinux環境では、手で何も入れずに gnat_native 16.1.0 と gprbuild 26.0.1 が選ばれました。システムに入っているGNATを使う構成もできます。
- alire.lock はバージョン管理に入れるべきですか?
- Alireの資料は、alire.lock は内部用のファイルで、必要に応じて作り直されるため、バージョン管理に入れなくてよいとしています。alr init が作る .gitignore も、それを置く alire フォルダーを除外しています。依存のバージョンを固定したいときは alr pin を使うと、マニフェストの alire.toml に固定が書かれます。
- alr build で作ったプログラムで、事前条件(Pre)は検査されますか?
- 既定の Development プロファイルでは検査されませんでした。Development のスイッチに -gnata が含まれないためです。Validation プロファイル(alr build --validation)では -gnata が付き、事前条件を満たさない呼び出しで Assertion_Error が発生しました。
- alr test は単体テストを実行するコマンドですか?
- テスト用の仕組みは持っていません。マニフェストに type = "test" のアクションがあればそれを実行し、なければ alr build --release を実行してビルドできるかを確かめます。単体テストは、テスト用のクレートを別に作り、本体のクレートを相対パスで固定する構成がAlireの資料で勧められています。