Project:Ada/DevReference

This is a guide to internal workings of the gnat and gnatbuild eclasses and eselect-gnat module, as well as an authoritative reference to packaging principles of Ada libs and other related packages.

Introduction
Before you start on the internals of the Ada packages you may want to go through the user guide (yet to be written) in case you are not familiar with how to activate the chosen gnat profile and where to look for the important files.

Ada related packages can be divided into three important categories:

The profiles are switched via eselect-gnat module, the usual way. Its internal workings are also discussed in the chapter describing.

General notes
The  has been modelled after the , similarly providing multiple SLOTs tracking the gcc backend variations. One additional "complication" that we have in Ada case is that there are two related, however different compilers available, as mentioned above. These are provided as separate packages, for FSF's Ada and  for the one by AdaCore.

It is possible they change it again to GPL-3 and FSF will likely want to do so as well. Therefore attention needs to be paid to the licenses when these packages are updated.

(both versions) can be considered a "yet another gcc frontend", therefore it is built similarly to other  based languages. There is, however, a significant distinction. It may be argued, that Ada is a "real language", in the sense that it requires an Ada-enabled compiler to build itself. This makes the build procedure significantly different from, e.g.,  or   in that we first need to provide a bootstrap compiler and then setup a bootstrap environment. In practice, the bootstraps need to be created only once, as  (and  ) internally build itself twice (stage1 and stage2) and then build the final binary and libs with stage2. Plus, so far, all the new versions of gcc could be built with the oldest at that time backend of gnat - 3.4. If, however, a version of  is released that cannot be built with an old bootstrap (for example, the transition from 2.8 to the later versions was problemmatic), a new one may need to be issued.

If you take a look at the, you will notice that all the code dealing with running   and   is preceded by the block setting many env vars. Such as (here and everywhere you can refere to the appropriate eclass or ebuild in portage to see all of the code):

These settings serve the purpose of letting the gnat build scripts find the bootstrap compiler, so that we do not have to depend on having some version of Ada-enabled  already installed on the system. While pretty plain, this part may get somewhat tricky. What vars you need to set or avoid depends on the version of toolchain the build host has active. The most "abusive" package in the toolchain was traditionally. In fact there were many bugs reporting build failures with  complaining that   is unable to find   or some other part of the bootstrap compiler. The most common cause of these bugs was related to having an old version of  installed on user's computer. Correspondingly, it was necessary to force gnat to depend on a appropriately recent version of. Fortunately, it seems that toolschain has largerly stabilized in the last year or so, as this has not been necessary for quite a while.

Partitioning of the src_* functions.
Lets take a look at some other  internals. One can notice, that all the  functions are partitioned in semi-independent sections. For example the  has the following form:

This allows the subsections to be called independently from within overriding function, such as would be an ebuild's  in this case. For example  has the following in its  :

and  are partitioned in a similar way, allowing easy modifications to be performed at every step. Although, as compilers from both FSF and ACT are becoming more unified, this is rarely necessary in later versions.

SLOTs and virtuals.
Gentoo has long had support for parallel istallation of different major package versions. Yes, I am talking about the famous SLOT mechanism. As here we are dealing with multiple compiler variants that are supposed to be code-compatible, it only makes sense to make a good use of this mechanism. It only needed to be modified to accept multiple package names in our case. As all the SLOT "inner workings" are done right in the eclass/ebuild code, there is nothing special about it. All what was necessary to do, was to extend SLOT logic to accept proper package names.

The important part of getting SLOTs right is to use suitable naming conventon. After much discussion in some long-forgotten bug the following naming scheme was adopted:  (may be followed by the usual -rX for Gentoo specific revisions). Here

Let's consider two possible examples of fully qualified package names.

As with , the code produced by compiler is only binary compatible within the same major version (SLOT). While theoretically one can try combining object files produced by  to those produced by   having identical backend version, such combinations are not supported. One must also be aware of potential differences in the produced  files. As such, both  components are defining the "operational SLOT" or profile specification. Moreover, a fully qualified profile name will contain an additional component -  to allow for the possibility of crosscompilation. However the description of this is left to the section dealing with  internals.

As is often the case with packages providing similar functionality, we provide a virtual that tracks various  versions:. This is a "new style" (that is, resembpling a regular package) virtual that tracks the  backend versions, the ,   and   are provided as of now. Also, as Ada-2005 standard has been recently approved, some packages are starting to require and Ada-2005 capable compiler (of which only  can be considered to be providing a reasonably complete subset of Ada-2005 functionality at this moment). It becomes necessary to provide another vortual:  that may be populated with ,   and  , provdiding dependencies on appropriate versions of.

Install locations
The installation procedure mimics (again) that of. The only principal difference (at the time of this writing) is that  compilers have been already transitioned to make use of   where proper, while   has not done so yet. The following global vars are defined to manage the install locations:

Lets go over these locations in more detail.

eselect-gnat workings
was modelled after the  module, that was supposed to supersede the   script at the time of development. Of course that got shot down and now we are "stuck" with  using the "more modern" tool, while   is still handled by legacy   script. Nonetheless,  works well with the way Ada support is setup in Gentoo, and below I describe its inner workings.

Inheriting all the general features of , the run-time behavior of   can be extensively regulated by env vars. As such, the approach that was adopted consists of the compiler producing the "specs" file tat contains all the principal locations during its build, and  using this generated file to create an appropriate entry under the. There are no additional "hidden entries", everything rotates around the way env settings are managed in Gentoo. Thus, ,   and   actions directly operate on the env entry (re)creating a new or deleting an existing one. This env file has the name of the form  with   currently set to   and   having a usial form of , such as   for example. The generation of the original specs file for each compiler is performed by the  function in the   part of the   function in. And the specs file location is defined near the op of  as:

The  serves as the top directory where all the information necessary for the   is stored. Every gnat installs a single file that has a name/SLOT specific name, thus overwriting the one for older version within the same grouping but avoiding collision with a different compiler or SLOT. Every installed library created a subdir under  that, in turn, contains library spec files for every gnat profile it was compiled with. More on the libs below, in the corresponding section. The location for  has been purposedly chosen outside normally config-protected locations, so that spec files are removed when the corresponding version of compiler is unmerged. The same goes for the libs. Therefore, figuring out what variants of gnat are installed is a simple matter of scanning  for the specs files and then splitting them into the ,   and   components. Right now every lib is supposed to create a separate directory for itself and every regular file under  is expected to be a specs file for some compiler variant.

provides common actions, such as  and   as well as   and. As all the relevant information for all gnat profiles is concentrated under, determination of The   accepts the name of the gnat profile to activate as an argument and update simply rege

Overview
As was described above, in Gentoo we provide multiple SLOTted versions of  compilers that users can have installed in parallel. Unlike with many other languages, Ada compilers tend to follows the standard rather tightly. Therefore most, if not all, the common libs are expected to compile cleanly with any compiler, provided it implements the necessary version of Ada standard. Therefore it was decided to provide users with the ability to have libs compiled for all the installed gnat variants and to make eselect to switch to an appropriate lib image when a certain  profile is activated.

The libs are managed by , which automates their handling. The principal action happens in the  function. All the installed gnat profiles are geting activated in turn and the lib gets compiled multiple times for every profile. The  function then collects the compiled parts and installs them in appropriate locations. The detailed workings of the eclass will be considered below. Here I will just note again, that  is designed to be used with the "common Ada libs" and thus should be used only where appropriate. It makes no sense to use it to build some directly executable application for example.

Detailed sequence of multi-build
As was already mentioned, the principal "magic" happens in. Here we have to: and cycle through these steps untill we go through all the installed  compilers. The following code fragment is responsible for doing just this.
 * 1) copy the source directory, so that the build does not poison the original,
 * 2) activate the next compiler profile,
 * 3) call the   callback, which now holds stuff that normally happens in   of a normal ebuild.
 * 4) call the   callback. This function is supposed to be similar to the normal   except that it only needs to concern itself with installing the gnat-profile specific stuff. The compiled   or   files or config scrits are the most common "ingredients" that are processed by it.

{{CodeBox|title=fragment of gnat_src_compile function|lang=bash|1= gnat_src_compile { ...	compilers=( $(find_compilers ) ) if -n ${compilers[@]}  ; then local i		for (( i = 0 ; i < ${#compilers[@]} ; i = i + 1 )) ; do		# copy sources mkdir ${DL} cp -dpR "${S}" ${SL} # setup environment generate_envFile ${compilers[${i}]} ${BuildEnv} && \ expand_BuildEnv ${BuildEnv} && \ . ${BuildEnv} || die "failed to switch to ${compilers[${i}]}" ...			# call compilation callback cd ${SL} gnat_filter_flags ${compilers[${i}]} lib_compile ${compilers[${i}]} || die "failed compiling for ${compilers[${i}]}"

# call install callback cd ${SL} lib_install ${compilers[${i}]} || die "failed installing profile-specific part for ${compiler			# move installed and cleanup			mv ${DL} ${DL}-${compilers[${i}]}			rm -rf ${SL}		done	else		die "please make sure you have at least one gnat compiler installed!"	fi } }}

Next, the  function. Here, we need to

Acknowledgements
We would like to thank the following authors and editors for their contributions to this guide:


 * George Shapovalov