Next: , Previous: Performance improvements in builder, Up: Aggregate Projects


11.7.5 Syntax of 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:

Project_Files:
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 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
     

Project_Path:
This attribute can be used to specify a list of directories in which to look for project files in 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:
This attribute can be used to set the value of environment variables as retrieved through the 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):

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.