Next: package Builder in aggregate projects, Previous: Performance improvements in builder, Up: Aggregate Projects
An aggregate project follows the general syntax of project files. The
recommended extension is still .gpr
. However, a special
aggregate qualifier must be put before the keyword
project.
An aggregate project cannot `with' any other project (standard or aggregate), except an abstract project which can be used to share attribute values. Also, aggregate projects cannot be extended or imported though a `with' clause by any other project. Building other aggregate projects from an aggregate project is done through the Project_Files attribute (see below).
An aggregate project does not have any source files directly (only through other standard projects). Therefore a number of the standard attributes and packages are forbidden in an aggregate project. Here is the (non exhaustive) list:
The only package that is authorized (albeit optional) is Builder. Other packages (in particular Compiler, Binder and Linker) are forbidden.
The following three attributes can be used only in an aggregate project:
This attribute is compulsory (or else we are not aggregating any project, and thus not doing anything). It specifies a list of
.gpr
files that are grouped in the aggregate. The list may be empty. The project files can be either other aggregate projects, or standard projects. When grouping standard projects, you can have both the root of a project tree (and you do not need to specify all its imported projects), and any project within the tree.Basically, the idea is to specify all those projects that have main programs you want to build and link, or libraries you want to build. You can even specify projects that do not use the Main attribute nor the Library_* attributes, and the result will be to build all their source files (not just the ones needed by other projects).
The file can include paths (absolute or relative). Paths are relative to the location of the aggregate project file itself (if you use a base name, we expect to find the .gpr file in the same directory as the aggregate project file). The environment variables ADA_PROJECT_PATH, GPR_PROJECT_PATH and GPR_PROJECT_PATH_FILE are not used to find the project files. The extension
.gpr
is mandatory, since this attribute contains file names, not project names.Paths can also include the "*" and "**" globbing patterns. The latter indicates that any subdirectory (recursively) will be searched for matching files. The latter ("**") can only occur at the last position in the directory part (ie "a/**/*.gpr" is supported, but not "**/a/*.gpr"). Starting the pattern with "**" is equivalent to starting with "./**".
For now, the pattern "*" is only allowed in the filename part, not in the directory part. This is mostly for efficiency reasons to limit the number of system calls that are needed.
Here are a few valid examples:
for Project_Files use ("a.gpr", "subdir/b.gpr"); -- two specific projects relative to the directory of agg.gpr for Project_Files use ("/.gpr"); -- all projects recursively
This attribute can be used to specify a list of directories in which to look for project files in `with' declarations.
When you specify a project in Project_Files (say x/y/a.gpr), and a.gpr imports a project b.gpr, only b.gpr is searched in the project path. a.gpr must be exactly at <dir of the aggregate>/x/y/a.gpr.
This attribute, however, does not affect the search for the aggregated project files specified with Project_Files.
Each aggregate project has its own Project_Path (that is if agg1.gpr includes agg2.gpr, they can potentially both have a different Project_Path).
This project path is defined as the concatenation, in that order, of:
- the current directory;
- followed by the command line -aP switches;
- then the directories from the GPR_PROJECT_PATH and ADA_PROJECT_PATH environment variables;
- then the directories from the Project_Path attribute;
- and finally the predefined directories.
In the example above, agg2.gpr's project path is not influenced by the attribute agg1'Project_Path, nor is agg1 influenced by agg2'Project_Path.
This can potentially lead to errors. Consider the following example:
-- -- +---------------+ +----------------+ -- | Agg1.gpr |-=--includes--=-->| Agg2.gpr | -- | 'project_path| | 'project_path | -- | | | | -- +---------------+ +----------------+ -- : : -- includes includes -- : : -- v v -- +-------+ +---------+ -- | P.gpr |<---------- withs --------| Q.gpr | -- +-------+---------\ +---------+ -- | | -- withs | -- | | -- v v -- +-------+ +---------+ -- | R.gpr | | R'.gpr | -- +-------+ +---------+When looking for p.gpr, both aggregates find the same physical file on the disk. However, it might happen that with their different project paths, both aggregate projects would in fact find a different r.gpr. Since we have a common project (p.gpr) "with"ing two different r.gpr, this will be reported as an error by the builder.
Directories are relative to the location of the aggregate project file.
Example:
for Project_Path use ("/usr/local/gpr", "gpr/");
This attribute can be used to set the value of environment variables as retrieved through the external function in projects. It does not affect the environment variables themselves (so for instance you cannot use it to change the value of your PATH as seen from the spawned compiler).
This attribute affects the external values as seen in the rest of the aggregate project, and in the aggregated projects.
The exact value of external a variable comes from one of three sources (each level overrides the previous levels):
- An External attribute in aggregate project, for instance for External ("BUILD_MODE") use "DEBUG";
- Environment variables. These override the value given by the attribute, so that users can override the value set in the (presumably shared with others team members) aggregate project.
- The -X command line switch to `gprbuild'. This always takes precedence.
This attribute is only taken into account in the main aggregate project (i.e. the one specified on the command line to `gprbuild'), and ignored in other aggregate projects. It is invalid in standard projects. The goal is to have a consistent value in all projects that are built through the aggregate, which would not be the case in the diamond case: A groups the aggregate projects B and C, which both (either directly or indirectly) build the project P. If B and C could set different values for the environment variables, we would have two different views of P, which in particular might impact the list of source files in P.