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. 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. It is an error to have any of these (and such an error prevents the proper loading of the aggregate project).
Three new attributes have been created, which can only be used in the context of aggregate projects:
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 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
with
statements.
When you specify a project in Project_Files
say "x/y/a.gpr"
), and this projects 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 (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 Project_Path attribute, then the directories from the GPR_PROJECT_PATH and ADA_PROJECT_PATH env. variables, 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. In 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.
Here are a few valid examples:
for Project_Path use ("/usr/local/gpr", "gpr/");
external
statement
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 aggreate projects, and in the aggregated projects.
The exact value of external a variable comes from one of three sources (each level overrides the previous levels):
for External ("BUILD_MODE") use "DEBUG"
;
These override the value given by the attribute, so that users can override the value set in the (presumably shared with others in his team) aggregate project.
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 or natmake), 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 build 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.