ada works . it

GNAT Projects

Previous tutorial GNAT Packages

GNAT project files

Large projects can have multiple source directories containing many source files and may also generate multiple executable files. Having a GNAT project file (they end with .gpr) and using the "gprbuild" command (which is a step up from "gnat make" and makes the whole process easier to handle for big projects.

If your just tinkering with Ada you won't really need to use gprbuild and gpr files but if your looking towards some serious projects it can really help. As an example here we will take example 3 from the previous section and do it the gpr way.

YOU MUST COMPLETE Example 3 in the last tutorial before doing Example 4 below!

Install gprbuild

Open the terminal and your linux OS is going to use just one of these two commands, either;

[john@silver ~]$ sudo dnf install gprbuild

or

[john@silver ~]$ sudo apt install gprbuild

Typically dnf is Fedora and apt is Ubuntu (I haven't done this on Ubuntu). Follow through the installation instructions untill you are told the installation is complete!

Example 4: Projects

Open the terminal to create a directory for this example and make sure its the working directory. You type only the text shown in this style;

[john@silver ~]$ cd ~/prog/ada [john@silver ada]$ mkdir exa4 [john@silver ada]$ cd exa4 [john@silver exa4]$

Create directory src in the exa4 directory like this;

[john@silver ~]$ mkdir src

Now place all *.adb and *.ads files from exa3 into exa4/src, you can use the terminal like this;

[john@silver exa4]$ cp ../exa3/*.adb src [john@silver exa4]$ cp ../exa3/*.ads src

Take a look in src to see what is there with;

[john@silver exa4]$ ls src packdemo.adb p_stringy.adb p_stringy.ads

That is all the source code copied from example 3.

Now we need another directory to keep everything tidy;

[john@silver exa4]$ mkdir obj

Take a look to see what is there with;

[john@silver exa4]$ ls obj src

Two directories. src contains all the source code.

It's time to create the project file that will be used with the command gprbuild to make the executable again.

You can call the project file anything you like but it must end in .gpr I will call it "prostringy.gpr" here is the file contents;

project prostringy is for Source_Dirs use ("src/**"); for Object_Dir use "obj"; for Exec_Dir use "."; for Main use ("packdemo"); package Compiler is for Default_Switches ("ada") use ("-gnat12", "-g"); end Compiler; package Builder is for Switches ("ada") use ("-g"); end Builder; package Linker is for Switches ("ada") use ("-g"); end Linker; end prostringy;

You can download it and save typing if you like;

Save this file in your "exa4" directory and then try the gprbuild command as follows (Note the -Pprostringy.gpr is not a mistake). Note it is "gprbuild" not "gnat make" this time;

[john@silver exa4]$ gprbuild -Pprostringy.gpr gprbuild: project files are no longer supported by gprbuild; use gprbuild instead.gpr [john@silver exa4]$

Whoops! On Linux that doesn't work! Oddly enough once you have installed gprbuild you can then use gprbuild in the proper way. Use;

[john@silver exa4]$ sudo dnf install gprbuild

Entering your password and answering yes should do the installation.

Try the gprbuild command again (Note the -Pprostringy.gpr is not a mistake);

[john@silver exa4]$ gprbuild -Pprostringy.gpr Compile [Ada] packdemo.adb [Ada] p_stringy.adb Bind [gprbind] packdemo.bexch [Ada] packdemo.ali Link [link] packdemo.adb [john@silver exa4]$

You should see that the executable packdemo has re-appeared and can be executed as before with the same result.

[john@silver exa4]$ ./packdemo Hello my label is computer, what is your label?############## Hello my name is computer, what is your thingy?############## [john@silver exa4]$

but now all the source files and object files are tidily contained in directories.

Object code, that is in the "obj" directory, is kind of between source code and executable/machine code. The compiler makes the object code files and then the linker (another tool program) joins or links all the object code cross references together to make the executable code which is just one file "packdemo".

About the .gpr file

The .gpr file might seem a little complex but look at the tidiness it created with the object files and source code. To understand the above gpr file let's look at the example file below for a project called my_project with two source directories src1 and src2, an obj directory and three seperate executable files that will be generated. It actually creates three seperate executable program files! Sometimes useful if all depend on a given package.

project my_project is for Source_Dirs use ("src1/**", "src2/**"); for Object_Dir use "obj"; for Exec_Dir use "."; for Main use ("my_executable1","my_executable2","my_executable3"); package Compiler is for Default_Switches ("ada") use ("-gnat12", "-g"); for Local_Configuration_Pragmas use "src/pragmas"; end Compiler; package Builder is for Switches ("ada") use ("-g"); end Builder; package Linker is for Switches ("ada") use ("-g"); end Linker; end my_project;

The -g flag means compile, build and link for debugging. Some other important switches are the (O oh not 0 zero) optimisation switches;

More about the switches can be found here Switches for gcc. also here Switches for gprbuild.

Example 5: Debug and Release Versions

Open the terminal to create a directory for this example and make sure its the working directory. You type only the text shown in this style;

[john@silver ~]$ cd ~/prog/ada [john@silver ada]$ mkdir exa5 [john@silver ada]$ cd exa5 [john@silver exa5]$

Copy directory src and its contents (Recursive copy) from the exa4 directory like this;

[john@silver exa5]$ cp -r ../exa4/src src

Take a look in src to see what is there with;

[john@silver exa5]$ ls src packdemo.adb p_stringy.adb p_stringy.ads

That is all the source code copied from example 4.

On big projects, it is quite possible to create multiple gpr files, perhaps one to make executables for release and one to make executables for debug. Its certainly a neat way to do it. But it is also possible to use a single gpr file to serve for both.

Before making/downloading the new gpr file we need to create separate directories for release and debug versions;

[john@silver exa5]$ mkdir debug [john@silver exa5]$ mkdir debug/obj [john@silver exa5]$ mkdir release [john@silver exa5]$ mkdir release/obj

Now you can download this gpr file;

Save this file in your "exa5" directory and then try the gprbuild command as follows (Note the -Pprostringy.gpr is not a mistake). Note it is "gprbuild" not "gnat make" this time;

which looks like this;

project prostringy is type Mode_Type is ("debug", "release"); -- all possible values Mode : Mode_Type := external ("mode", "debug"); -- a typed variable for Source_Dirs use ("src/**"); case Mode is when "debug" => for Object_Dir use "debug/obj"; when "release" => for Object_Dir use "release/obj"; end case; case Mode is when "debug" => for Exec_Dir use "debug"; when "release" => for Exec_Dir use "release"; end case; for Main use ("packdemo"); package Compiler is case Mode is when "debug" => for Default_Switches ("ada") use ("-gnat12", "-g"); when "release" => for Switches ("Ada") use ("-O2"); end case; for Local_Configuration_Pragmas use "src/pragmas"; end Compiler; package Builder is case Mode is when "debug" => for Default_Switches ("ada") use ("-gnat12", "-g"); when "release" => for Switches ("Ada") use ("-O2"); end case; end Builder; package Linker is case Mode is when "debug" => for Default_Switches ("ada") use ("-gnat12", "-g"); when "release" => for Switches ("Ada") use ("-O2"); end case; end Linker; end prostringy;

Once this file is in place you can compile a release version of the code with;

[john@silver exa5]$ gprbuild -Pprostringy.gpr -Xmode=release Compile [Ada] packdemo.adb [Ada] p_stringy.adb Bind [gprbind] packdemo.bexch [Ada] packdemo.ali Link [link] packdemo.adb [john@gprbuild exa5]$

after this you should see that a release executable of packdemo has appeared in the release directory. You can execute it with;

[john@silver exa5]$ ./release/packdemo Hello my label is computer, what is your label?################# Hello my name is computer, what is your thingy?################# [john@silver exa3]$

You can compile a debug version of the code with;

[john@silver exa5]$ gprbuild -Pprostringy.gpr -Xmode=debug Compile [Ada] packdemo.adb [Ada] p_stringy.adb Bind [gprbind] packdemo.bexch [Ada] packdemo.ali Linkgprbuild -Pprostringy.gpr -Xmode=debug [link] packdemo.adb [john@silver exa5]$

after this you should see that a debug executable of packdemo has appeared in the debug directory. You can execute it with;

[john@silver exa5]$ ./debug/packdemo Hello my label is computer, what is your label?################# Hello my name is computer, what is your thingy?################# [john@silver exa3]$

You now have all you need to organise really large programs but still it is essential to have a debugger.

I will introduce you to that and Geany, a very nice Intergrated Development Environment (IDE) in the next tutorial

Next tutorial GNAT with Geany IDE