Auto Configuration

One common need for broadly distributed portable code “packages” is the configuration of various platform-dependent values.

The design intent is for this kind of platform-specific configuration process to be as integrated as possible, and not simply pull from existing C/UNIX-oriented autoconfiguration systems like Autotools, Ninja/CMAKE, gprbuild, etc.

To this end, all AURA auto configuration happens through a special AURA-specific Ada subsystem which contains all AURA subsystem configuration, platform information, and repository configuration, within normal Ada packages.

The AURA Subsystem

All configuration and auto configuration is managed through the packages that constitute the AURA subsystem, located in the project root.

The root package (package AURA) is automatically generated by the AURA implementation, has the aspect Pure, and has no body.

The root package defines the implementation-defined enumeration type Repository_Type that determines the types of repositories supported by the implementation, as well as a standardized set of platform values.

An example root specification from the reference implementation looks something like this:

-- This specification was automatically generated by the AURA CLI
-- DO NOT MODIFY

package AURA with Pure is

    type Repository_Format is (system, local, git);

    Platform_Family       : constant String := "unix";
    Platform_Flavor       : constant String := "darwin";
    Platform_Version      : constant String := "20.5.0";
    Platform_Architecture : constant String := "x86";

end AURA;

Any AURA subsystem can with the AURA root package to gain access to these values, and use these to configure different parts of codebase, based on the platform the subsystem gets built on.

User Configuration

AURA subsystems may optionally include a subsystem manifest package that allows AURA subsystems to self-configure post-checkout and pre-compilation.

Each checked-out subsystem of a project has a configuration package installed as part of the check-out process, unless the configuration package is already present. If the configuration is not present at check-out, it is generated from the manifest. The configuration package is a standard Ada package that is a first child of the AURA package, and has the name of the subsystem. During the check-out of the subsystem, and if the configuration package is subsequently changed, the configuration package is evaluated to resolve any codepaths, which is used to enter the appropriate subsystem program text. That may trigger additional AURA check-outs.

During compilation, a checked-out subsystem has direct access to its own configuration package, which can then communicate configuration state, such as through constants, to the rest of the subsystem’s codebase. The Ada compiler will evaluate these configuration packages as they normally would during the configuration and compilation processes.

By initializing objects in a configuration package or manifest with an expression that depends on values in the root AURA package, subsystems are able to automatically configure themselves to the target platform.

Any user-configured options can also be placed in manifests, to be then set by the user via edits to the configuration package. Since check-out never over-writes an existing configuration package, this mechanism allows for persistent user configuration of AURA subsystems across check-outs, and potentially across different projects.

More detail on manifests is given in the next section.