Saturday 15 October 2011

Building ASIS

This is a note on building ASIS for GCC 4.6.

"The Ada Semantic Interface Specification (ASIS) is an interface between an Ada environment as defined by ISO/IEC 8652 (the Ada Reference Manual) and any tool requiring information from this environment. An Ada environment includes valuable semantic and syntactic information. ASIS is an open and published callable interface which gives CASE tool and application developers access to this information. ASIS has been designed to be independent of underlying Ada environment implementations, thus supporting portability of software engineering tools while relieving tool developers from having to understand the complexities of an Ada environment's proprietary internal representation."

AdaCore have implemented ASIS for GNAT. The "Ada environment" is a binary record of the compiler's internal state, output on request (the flag -gnatct) in files of type .adt (tree files).

Clearly it's vital that the ASIS library has the same view of the compiler's internal state as the compiler had when the .adt file was generated. This is organised by using consistent versions of the compiler's access mechanisms on both sides.

For unsupported customers, AdaCore release ASIS updates in parallel with the GNAT GPL compiler toolset. The GNAT GPL release schedule (discussed as part of the Debian policy for Ada) doesn't match the FSF schedule, with the result that GNAT GPL 2010 is roughly the same from the Ada point of view as both GCC 4.5 and GCC 4.6.

It was possible to build an adequate ASIS for GCC 4.5 with very little alteration: at the time I wrote
[The internal representation is] determined for a particular compiler release by particular compiler components, Sinfo and Snames, so to make ASIS work you need to include the appropriate files from your compiler.
Sinfo is just the source files sinfo.ads, sinfo.adb.
Snames is created from template files snames.ads-tmpl and snames-adb.tmpl.

As well as this, you'll need to copy gnatvsn.ads from your compiler, and edit gnatvsn.adb to match (for example, GNAT GPL 2010 source includes GNATPro as a build possibility, which isn't allowable in the FSF sources for GCC 4.5.0).

So, to adapt ASIS GPL 2010 for use with GCC 4.5.0, in asis-2010-src/gnat/:
  1. replace sinfo.ad[bs] by gcc-4.5.0/gcc/ada/sinfo.ad[bs]
  2. replace snames.*-tmpl by gcc-4.5.0/gcc/ada/snames.*-tmpl
  3. replace gnatvsn.ads by gcc-4.5.0/gcc/ada/gnatvsn.ads
  4. edit gnatvsn.adb to remove the 'gnatpro' choices, not in the .ads

However, "roughly the same" isn't adequate for GCC 4.6. The recipe above allowed the library to build, but nothing built with it would run (an inconsistency in the tree file format).

Ludovic Brenta, writing on comp.lang.ada, said
Debian solves that problem by introducing libgnatvsn, a library compiled from GCC sources and containing gnatvsn.ads, sinfo.ad[bs], snames.ad[bs] and everything they depend on. libasis is compiled against libgnatvsn.

There's an alternative to creating a libgnatvsn.a or .dylib which merely depends on your having a compiler build tree around!

The way the ASIS GPL source distribution is structured is that the required compiler sources are in a subdirectory gnat/. The approach I've adopted is to replace this with a subdirectory gnatvsn/; I've modified the Makefile to copy the required sources from the compiler build and source trees (the Snames sources are built from templates during the compiler build).

To start with, I copied the same files that AdaCore supplied in gnat/. During the build it turned out that a few more are needed for GCC 4.6 (not surprising, since GNAT GPL 2010 is forked from GCC 4.3). The units are Aspects and Sem_Aux.

After having set up the compiler-derived sources, a couple of problems turned up while compiling ASIS:
  • the compiler doesn't understand Name_Implemented_By_Entry
  • the compiler doesn't understand Is_Overriding_Operation
so I patched these references out (I don't think it's going to affect users much).

This only leaves one problem; the compiler's Gnatvsn unit imports a symbol _version_string, which comes from the compiler's version.c. Unfortunately, this file depends on a lot of macros defined as part of the compiler build; so the easiest way to get the right object is to copy the built version.o from the compiler build tree into libasis.a.

The patches are here. As ever, use patch -p1 to apply.

No comments:

Post a Comment