Berkas proyek (project file) adalah berkas teks berakhiran .gpr yang memuat konfigurasi pembangunan (build) sebuah program Ada. Alat gprbuild membaca berkas proyek tersebut untuk menentukan letak sumber, berkas utama, direktori hasil, dan switch, yaitu pengaturan berawalan tanda minus yang diteruskan ke alat yang dipanggil. Topik ini membahas atribut inti berkas proyek, package Compiler untuk switch kompilator, serta pengimporan proyek lain. Setelah topik ini dibaca, proyek multiunit dapat ditulis, dikonfigurasi, dan dibangun dengan satu perintah gprbuild.
Susunan berkas proyek#
Setiap proyek ditulis dalam satu berkas .gpr yang namanya sama dengan nama proyeknya. Proyek bernama Kalkulator wajib disimpan sebagai kalkulator.gpr, dan ketidakcocokan antara nama berkas dan nama proyek dilaporkan oleh gprbuild sebagai peringatan. Isi berkas proyek berupa deklarasi yang dibuka dengan kata project dan ditutup dengan end. Atribut-atribut proyek diletakkan di antara kedua kata tersebut. Bentuk paling sederhana dari berkas proyek hanya memuat satu atribut.
-- tidak-dijalankan
project Sapa is
for Source_Dirs use (".");
end Sapa;Atribut Source_Dirs menentukan direktori yang memuat sumber proyek, dan nilainya berupa daftar direktori yang ditulis relatif terhadap letak berkas proyek. Tanda titik menunjuk direktori berkas proyek itu sendiri, sehingga seluruh berkas .ads dan .adb pada direktori tersebut ikut menjadi bagian proyek. Apabila atribut ini tidak dituliskan, direktori tempat berkas proyek berada yang digunakan. Pembangunan dijalankan dengan perintah gprbuild diikuti switch -P dan nama berkas proyeknya.
Proyek kalkulator#
Contoh pada topik ini adalah proyek kalkulator yang terdiri atas empat berkas, yaitu spesifikasi dan badan package Kalkulator_Ops, prosedur utama Kalkulator, dan berkas proyeknya. Package tersebut memuat fungsi Tambah serta fungsi Bagi yang dilengkapi kontrak Pre dan Post, sedangkan prosedur utama mencetak dua hasil perhitungan. Berkas proyek menggabungkan keempat berkas tersebut dalam satu pembangunan.
package Kalkulator_Ops is
-- Kontrak: penyebut tidak boleh nol, dan hasilnya mengikuti
-- sifat pembagian bilangan bulat.
function Bagi (Pembilang, Penyebut : in Integer) return Integer with
Pre => Penyebut /= 0,
Post => Bagi'Result * Penyebut + Pembilang rem Penyebut = Pembilang;
-- Menjumlahkan dua nilai bulat.
function Tambah (Kiri, Kanan : in Integer) return Integer;
end Kalkulator_Ops;package body Kalkulator_Ops is
function Bagi (Pembilang, Penyebut : in Integer) return Integer is
begin
return Pembilang / Penyebut;
end Bagi;
function Tambah (Kiri, Kanan : in Integer) return Integer is
begin
return Kiri + Kanan;
end Tambah;
end Kalkulator_Ops;with Ada.Text_IO;
with Ada.Integer_Text_IO;
with Kalkulator_Ops;
procedure Kalkulator is
begin
Ada.Text_IO.Put ("Tambah (7, 2) = ");
Ada.Integer_Text_IO.Put (Kalkulator_Ops.Tambah (7, 2), Width => 1);
Ada.Text_IO.New_Line;
Ada.Text_IO.Put ("Bagi (100, 8) = ");
Ada.Integer_Text_IO.Put (Kalkulator_Ops.Bagi (100, 8), Width => 1);
Ada.Text_IO.New_Line;
end Kalkulator;project Kalkulator is
for Source_Dirs use (".");
for Object_Dir use "obj";
for Exec_Dir use "bin";
for Main use ("kalkulator.adb");
package Compiler is
for Default_Switches ("Ada") use ("-gnata");
end Compiler;
end Kalkulator;# bangun proyek dari direktori yang memuat berkas proyeknya
gprbuild -q -P kalkulator.gpr
# jalankan program utama proyek
./bin/kalkulatorTambah (7, 2) = 9
Bagi (100, 8) = 12Perintah gprbuild mengompilasi bukan hanya berkas utama, tetapi juga seluruh unit yang digunakannya, baik langsung maupun tidak langsung. Pada contoh ini, Kalkulator_Ops ikut dikompilasi karena prosedur utama mengimpornya melalui with Kalkulator_Ops, sehingga tidak ada perintah kompilasi terpisah untuk package tersebut. Atribut Main menerima daftar berkas utama, dan setiap berkas dalam daftar tersebut menghasilkan satu program.
Atribut Object_Dir dan Exec_Dir memindahkan hasil pembangunan keluar dari direktori sumber. Berkas objek, berkas .ali, dan berkas sementara lainnya berada di obj, sedangkan program yang dapat dijalankan ditempatkan di bin. Apabila keduanya tidak dituliskan, hasil pembangunan bercampur dengan berkas sumber pada direktori yang sama.
kalkulator.gpr
kalkulator.adb
kalkulator_ops.ads
kalkulator_ops.adb
obj/
kalkulator.o
kalkulator_ops.o
kalkulator.ali
kalkulator_ops.ali
bin/
kalkulatorSwitch pada package Compiler#
Switch kompilator dituliskan pada berkas proyek melalui package Compiler. Atribut Default_Switches dengan indeks “Ada” berlaku untuk seluruh berkas Ada pada proyek, sedangkan atribut Switches dengan indeks nama berkas berlaku untuk satu berkas tertentu. Pada proyek kalkulator, satu switch bernama -gnata diteruskan ke kompilator untuk seluruh sumbernya.
| Switch | Efek |
|---|---|
-gnata | Mengaktifkan pemeriksaan assertion dan kontrak saat run time. |
-gnatwa | Mengaktifkan sebagian besar peringatan opsional. |
-g | Menghasilkan informasi debug untuk debugger. |
Switch lain dituliskan dengan cara yang sama, misalnya tingkat optimasi -O1 dan -O2 atau switch versi bahasa -gnat2022. Perubahan pada package Compiler berlaku bagi kompilasi yang dilakukan pada pembangunan berikutnya, dan perintah gprbuild yang sama meneruskan switch tersebut tanpa pengaturan tambahan. Dengan penempatan switch pada berkas proyek, baris perintah pembangunan tetap pendek, sedangkan riwayat pengaturan tersimpan bersama sumber.
Mengimpor proyek lain#
Proyek berskala besar biasanya terdiri atas beberapa subproyek, sehingga berkas proyek dapat mengimpor proyek lain melalui klausa with. Klausa ini dituliskan sebelum deklarasi proyek dan menyebut nama berkas .gpr yang diimpor. Jalur berkas .gpr yang diimpor ditulis relatif terhadap berkas proyek pengimpor. Pustaka yang sudah terpasang cukup diimpor dengan namanya karena gprbuild mencarinya pada jalur pencarian proyek, yaitu jalur yang diatur melalui variabel lingkungan GPR_PROJECT_PATH.
-- tidak-dijalankan
with "satuan.gpr";
project Aplikasi is
for Source_Dirs use (".");
for Main use ("utama.adb");
end Aplikasi;Proyek Aplikasi pada contoh mewarisi akses ke sumber proyek Satuan, sehingga fungsi yang diekspor oleh proyek tersebut dapat dipanggil dari utama.adb. Pola yang sama digunakan untuk mengimpor pustaka pihak ketiga yang dipasang melalui Alire maupun pustaka AUnit yang terpasang sebagai proyek bernama aunit. Proyek pengujian yang menggunakan AUnit menuliskan with "aunit"; karena pustaka itu ditemukan melalui jalur pencarian proyek yang sama.
Kesalahan umum#
Kesalahan pada berkas proyek umumnya tertangkap saat gprbuild membaca berkas proyek. Dua kesalahan pertama diperlihatkan dengan berkas proyek yang sengaja dibuat salah dan diletakkan pada direktori yang sama dengan proyek kalkulator.
Kesalahan pertama adalah menamai berkas proyek secara berbeda dari nama proyeknya. Berkas salahnama.gpr berikut memuat deklarasi proyek Kalkulator yang sama seperti kalkulator.gpr, tetapi nama berkasnya tidak cocok dengan nama proyek yang dideklarasikan di dalamnya.
project Kalkulator is
for Source_Dirs use (".");
end Kalkulator;# bangun proyek yang nama berkasnya tidak cocok dengan nama proyeknya
gprbuild -q -P salahnama.gprsalahnama.gpr:1:20: warning: file name does not match project name, should be "kalkulator.gpr"Pesan peringatan menyebut nama berkas yang seharusnya, yaitu kalkulator.gpr. Pembangunan tetap dilanjutkan karena perbedaan ini tidak menghalangi pencarian sumber, tetapi peringatan tersebut menandai berkas proyek yang perlu diganti namanya. Perbaikannya, samakan nama berkas dengan nama proyek yang dideklarasikan.
Kesalahan kedua adalah menunjuk direktori sumber yang tidak ada. Berkas salahdir.gpr berikut menuliskan direktori sumber sumber yang belum dibuat.
project Salahdir is
for Source_Dirs use ("sumber");
end Salahdir;# bangun proyek yang direktori sumbernya tidak ada
gprbuild -q -P salahdir.gprsalahdir.gpr:3:25: "sumber" is not a valid directory
gprbuild: "salahdir.gpr" processing failedPembangunan berhenti karena gprbuild gagal memproses berkas proyek tersebut. Pesan error menyebut baris atribut yang bermasalah beserta nama direktori yang tidak ditemukan. Perbaikannya, buat direktori tersebut atau tuliskan direktori yang memang memuat sumber.
Kesalahan ketiga adalah mengubah switch pada berkas proyek lalu menyangka perubahan tersebut langsung berlaku pada hasil pembangunan. gprbuild mengompilasi ulang hanya berkas sumber yang isinya berubah, sedangkan perubahan switch pada berkas proyek tidak memicu kompilasi ulang, sehingga berkas objek yang dikompilasi dengan switch lama masih digunakan. Perbaikannya, hapus direktori objek sebelum membangun ulang agar seluruh sumber dikompilasi dengan switch yang baru.
Ringkasan#
- Berkas proyek .gpr memusatkan konfigurasi pembangunan, dan namanya wajib sama dengan nama proyek yang dideklarasikan di dalamnya.
- Perintah
gprbuild -Pmembangun berkas utama beserta seluruh unit yang digunakannya, sedangkanObject_DirdanExec_Dirmemisahkan hasil pembangunan dari sumber. - Switch kompilator dituliskan pada package
Compiler, proyek lain diimpor dengan klausawith, dan pustaka terpasang ditemukan melaluiGPR_PROJECT_PATH.
Referensi#
- GPRbuild User’s Guide: Your First GPRbuild Project — AdaCore — Dokumentasi atribut Source_Dirs, Object_Dir, Exec_Dir, Main, dan package Compiler.
- GPRbuild User’s Guide: Multi-Project Systems — AdaCore — Klausa with, jalur relatif antarproyek, dan variabel lingkungan GPR_PROJECT_PATH.
- GNAT User’s Guide: Building Executable Programs with GNAT — AdaCore — Dokumentasi switch -gnata, -gnatwa, dan -g pada kompilator GNAT.