Project Extension
Most project kinds may extend another project using the extends clause.
The extending project inherits sources and settings from the base and may
selectively override them. An extending project can also import other projects
alongside its base.
Aggregate projects and aggregate library projects may extend abstract projects to inherit their attributes and package settings.
project Patched extends "original/original.gpr" is
-- Source files here shadow those in original.gpr.
-- All other sources and settings are inherited.
end Patched;
Simple Extension
What is inherited
Source files - All source files from the base are implicitly present. A source file in the extending project whose basename matches one from the base shadows the base version. See Source Resolution for the full shadowing rules.
Attribute values - Project-level attributes not declared in the extending project are inherited from the base.
Packages - Any package not declared in the extending project is inherited in full from the base. A package that is declared in the extending project replaces the entire base package; there is no per-attribute inheritance within a package. Use package extension (
package Compiler extends Base.Compiler is ...) to inherit a base package and add or override individual attributes.
Exception: Linker'Linker_Options is never inherited.
Excluding inherited sources
To remove an inherited source without providing a replacement, list its
file name in Excluded_Source_Files:
project Work extends "../base/base.gpr" is
for Source_Files use ("pack.ads");
-- New spec does not require a body
for Excluded_Source_Files use ("pack.adb");
end Work;
Excluded_Source_List_File accepts the same information as a path to a
text file with one file name per line.
Extension Hierarchies
Extension may be chained: an extending project may itself be extended
further. The extends relationship forms a linear chain (each project
has at most one direct base). A project that extends another may also import
additional projects normally.
Import redirection
When loading a project tree, the build system automatically redirects imports to their extending versions. If:
project A extends B and imports C, and
C extends D, and
B imports D,
then in A’s context, B’s import of D is transparently replaced by an import of C. Any reference to D anywhere in the base hierarchy is similarly redirected, ensuring that the entire tree consistently uses C instead of D.
This redirection applies transitively: if the base hierarchy has further imports of D through intermediate projects, those are all replaced by C as well.
extends all
When working with a large project hierarchy, replacing sources in a single
constituent project normally requires extending every project along the import
path up to the root (so that import redirection keeps the tree consistent).
extends all eliminates this overhead: it implicitly extends every project
in the import closure of the named base, with import redirection applied
throughout, so the whole subtree is immediately available for targeted
amendment.
project Full_Override extends all "original/original.gpr" is
end Full_Override;
To replace a specific constituent - for example to substitute instrumented
sources for a particular library - import an explicit extending project for
that constituent from within the extends all project. The explicit
extension replaces the corresponding implicit one, and import redirection
ensures all other projects in the closure consistently reference the new
version instead of the original.
Restriction
A project may not import, directly or indirectly, both an extending project P and any project that P extends (directly or indirectly). Without this restriction, two import paths could reach different versions of the same source file.
The standard solution is to introduce an empty intermediate extension so that all import paths go through the extending project:
-- b_ext.gpr - bridges the gap so no path reaches the original b.gpr
with "a_ext.gpr";
project B_Ext extends "b.gpr" is
end B_Ext;