PowerAda Multiple Directories Demo

From OC Systems Wiki!
Jump to: navigation, search


This demo uses the Dining Philosophers program to show how PowerAda helps manage projects in multiple directories. For all but the simplest of projects, your source code will be split between many different sub-systems, in many different sublibraries. PowerAda allows you to tell it what sublibraries you are using (with the adalib.imports file) and what files you are going to build into the sublibrary (the adalib.files file). It uses these files to keep track of what needs to be re-built into your project when your source files change.

This demo differs from the others in that it demonstrates how to use the command line for building your projects. In most large projects, a Builds and Controls team will be responsible for producing the baselines against which developers will work. Often these builds will be done automatically (perhaps overnight); scripts will extract source code from the Configuration Management system and then build the executables. PowerAda makes this easy - both from the GUI and the command line. Although this demo is intended to be run from the command line, brief instructions on how to run it from the GUI are also given.

Additionally, you may have an existing project and are migrating it to PowerAda: Using the following methods will probably be the quickest way for you to get your first build done - and give you a baseline against which the developers can start working.

For more information on using adalib.imports and adalib.files, see Chapter 5, "Setting Up the PowerAda Project".

This demo will take about 20 minutes to complete.

Starting Off

Although you will not be using the PowerAda GUI for much of this demo, you will still need to have PowerAda set up correctly. The multi_diners demo includes a setup script that will check your PowerAda environment to make sure things are as they should be.

The first thing to do in the demo is to get the source code into your working directory. Execute the following commands:

cd ~ (or your preferred directory)
$POWERADA/demos/multi_diners/setup

If all is well you will be told that the multi-diners demo has been set up in a multi_diners directory; if you received any errors, see "Basic Troubleshooting". The source code has been placed into three sub-directories:

multi_diners/support
multi_diners/diners
multi_diners/main

Only the source code is there - nothing else to help build it; you'll create all the support files you need in just a couple of minutes!

Creating the Project

The first thing you must do is to make this a project. Since we already have our source code, we are going to tell PowerAda to create a project, keeping the existing files in place. Type the following command:

aprojinit -k multi_diners

(The -k flag is the 'keep' option).

For GUI Users

If you are following along with this from the PowerAda GUI, you can just use your working project from the previous demos. Navigate into the multi_diners directory - you will find the three sub-directories there already.

Sublibrary Hierarchy

If you have used Ada on a large project before, you will know that one of the key elements is telling the compiler how all the code in your directory hierarchy fits together. If a unit which is compiled into one sublibrary, needs to "with" a unit from another sublibrary, the compiler needs to know it should search there. For more information on this, see "Project Libraries and Sublibraries" in Chapter 3.

You are going to create three files to link the directories together. These are called "adalib.imports" and detail the sublibraries that the sublibrary in the current directory needs to have visibility of. Every PowerAda directory which contains a sublibrary must have an adalib.imports file (even if it is blank) for PowerAda to correctly compile your code.

In our simple hierarchy, the code has been split into support packages, the 'real' diners code and the main subprogram (support, diners and main respectively). This is also the "withing" hierarchy: The support packages do not need to have visibility of anything outside of their sublibrary to compile; the diners packages need to be able to see the support sublibrary; and the main subprogram needs to see it all.

We'll start by creating the adalib.imports file for the support packages. Perform the following commands:

cd multi_diners/support<br />
vi adalib.imports (or your preferred editor)

Copy the following lines into the new adalib.imports file (note that you do not need to include comment lines beginning -- so in fact the specs adalib.imports file can be completely blank!):

----- Ada Imports List File -----
-- lines in this file may be:
-- use <real sublib/imports file to use> -- or else
-- include <imports_file_pathname> -- or
-- <project_relative_sublibrary_pathname> -- or
-- <fully_qualified_external_sublibrary_pathname>

-- The support packages do not have to have visibility of anything so we have
-- a blank adalib.imports file (PowerAda implicitly gives a project visibility
-- of the ada95 standard libraries). Note that we do need an
-- adalib.imports file - just to say we don't need visibility of anything else!

Save this file. You have just told PowerAda that the support sublibrary will not need to see any of your other sublibraries. Now you need to tell PowerAda that the diners sublibrary will need to have visibility of the support sublibrary:

cd ../diners
vi adalib.imports (or your preferred editor)

Copy the following lines into the new adalib.imports file (again, you don't need the comment lines if you don't want - just the support/adalib line is enough):

----- Ada Imports List File -----
-- lines in this file may be:
-- use <real sublib/imports file to use> -- or else
-- include <imports_file_pathname> -- or
-- <project_relative_sublibrary_pathname>; -- or
-- <fully_qualified_external_sublibrary_pathname>

--- For the diners packages to have visibility of the support packages, we
-- include the project relative path to the ada library:
support/adalib

Notice that you do not need to specify the full path (in fact, for sublibraries within your project, never specify a full path - it is the easiest way of breaking your build!). Now you're ready to specify the adalib.imports file for the main sublibrary. It should be pretty standard by now: Change into the main directory (../main), edit an adalib.imports file and copy the following lines (again, comments are not important) into it:

----- Ada Imports List File -----
-- lines in this file may be:
-- use <real sublib/imports file to use> -- or else
-- include <imports_file_pathname> -- or
-- <project_relative_sublibrary_pathname> -- or
-- <fully_qualified_external_sublibrary_pathname>

-- For the main sublibrary, we need to have visibility of the support and the
-- diners sublibraries:
support/adalib<br />
diners/adalib

For GUI Users

If you are following along with this from the PowerAda GUI, you can just go into the sublibraries - you'll see that the adalib.imports files have already been set up for you.

Sublibrary Files

You could manually kick off compiles on all of these files and PowerAda would build the executable for you. But, you would need to work out the correct order in which to build the files - much better to let PowerAda do that for you! Additionally, once you have told PowerAda what files are in your project, it can determine all of the compilations needed whenever you change a file.

PowerAda recognizes a special file (called adalib.files) which tells it what files should be built into the sublibrary within the directory. Since all of the source files in the multi_diners project has a '.ada' extension, it is easy to create all of these files in the same way. Perform the following commands:

cd .. (you should now be in the multi_diners directory)
for D in 'find * -type d'; do
ls $D/*.ada > $D/adalib.files
done

This will create an adalib.files file in each of your project sub-directories listing all of the Ada source files within that directory. You can easily modify the above commands to include any variations you may have in naming ada files (*.ads, *.adb, etc.).

Note that the use of the adalib.files file is completely optional. If you give PowerAda a list of files to build, it will always figure out the correct order to build them in. However, using the adalib.files mechanism is highly recommended as it allows PowerAda to check for obsolete files whenever you kick off a build.

For GUI Users

If you are following along with this from the PowerAda GUI, you already have the adalib.files created for you.

Compiling the Source Code

Now you've given PowerAda enough information to compile all of the source code. You've told it what sublibraries each sublibrary relies upon and what files must be built into each sublibrary. You will issue one command to tell PowerAda to compile all of your files:

aprojbuild -vpl

The -v option tells PowerAda to be verbose; -p means use the project you are in to determine the sublibraries; -l means load (and compile) the source files into the sublibraries. PowerAda will first "load" your source files into the project (this does a syntax check) and then compile each file in turn. You should not get any errors if you have followed all of the above steps correctly. If you wanted you could have used 'aprojbuild -vpr' which tells PowerAda just to load the files: When you then issue the bind command in the next step, PowerAda would determine that the sublibraries were not up to date and would compile the source code first.

For GUI Users

If you are following along with this from the PowerAda GUI, use the 'Load Project Files' option on the Build menu.

Bind the Main Program

Now you are ready to issue the bind command. Enter the following commands:

cd main
aprojbuild -b diners

You have told aprojbuild to bind the unit called diners in the current sublibrary (i.e. in main/adalib). By default the executable will be called the same name as the unit (you can change this with the -o flag) and use the current sublibrary (you can specify -L sublib_name to override this). You now have a version of diners which you can execute - just type ./diners.

For GUI Users

If you are following along with this from the PowerAda GUI, it is easy to bind the executable. Navigate into the main directory, select the diners.ada source file and select Bind Main from the Build menu. Click Bind on the dialog that appears. PowerAda will compile all of the source code you previously loaded and create the diners executable.

Baselining the Project

Once you have built your project in this manner, you will want to baseline it. This will allow other users to create working projects against it and use the full facilities of PowerAda to develop changes. To baseline the project, use the aprojbaseline command:

aprojbaseline -v PowerAda will check your project is consistent, build 'cache' files (this allows it to search the baseline efficiently), remove any locks you have and mark the files as read-only. If you want to leave the files editable (not usually recommended) you can use the -w flag. To unbaseline an existing (baselined) project, use the -u flag.

If you want you can edit the POWERADA_BASELINES file to include this project as a baseline. That way, other users will be able to see the baseline when they create a new project or change baselines from within the PowerAda GUI. For this example, create a new POWERADA_BASELINES file and set the environment variable to point to it:

cd ../..      (you should now be one up from your multi-diners directory)
echo "multi_diners_demo 'pwd'/multi_diners"  > /tmp/BASELINES
export POWERADA_BASELINES=/tmp/BASELINES

You can now start the PowerAda GUI (just type powerada). From the No Project dialog which appears, select Create Project. In the top text field (New Project) replace the adaproj with new_multi_diners. Click Find to the right of the baseline text field and the Baselines dialog will appear with your baselined multi_diners project in the list. Select the entry, click OK and the baseline name will appear in the baseline field. Click OK and the new project will be created. Navigate around the project and you will see all your original files shadowed. You can now make changes to the source and PowerAda will build these into your new project.

For GUI Users

If you are following along with this from the PowerAda GUI, use the 'Baseline Project' option on the file menu. PowerAda will baseline your project and prompt you to open a new one since you cannot work within a baselined project. If you bring up the Baselines dialog, you will see your new project in the list. However, this is not written to the POWERADA_BASELINES file - you must do this manually. If you do not, the next time you start PowerAda, the baseline will not appear in the list (although you can select by using the Find Baseline file dialog.

This concludes the multiple directory / command line demo. Working with sublibrary hierarchies and using the baselines correctly are the most important aspect of using PowerAda on large projects and this demo has only shown you a little of the capabilities of the tools. However, by reading Chapter 3, "Basic PowerAda Concepts" and familiarizing yourself with the aprojbuild, aprojinit and aprojbaseline commands, you should be in a good position to tackle migrating your current project to PowerAda.