GtkAda comes with its own project file (appropriately called
gtkada.gpr), and we will assume we have already built a project
logging.gpr for the logging module. With the information provided
so far in
build.gpr, building the application would fail with an error
indicating that the gtkada and logging units that are relied upon by the sources
of this project cannot be found.
This is solved by adding the following `with' clauses at the beginning of our project:
with "gtkada.gpr"; with "a/b/logging.gpr"; project Build is ... -- as before end Build;
When such a project is compiled, `gprbuild' will automatically check the other projects and recompile their sources when needed. It will also recompile the sources from Build when needed, and finally create the executable. In some cases, the implementation units needed to recompile a project are not available, or come from some third party and you do not want to recompile it yourself. In this case, set the attribute `Externally_Built' to "true", indicating to the builder that this project can be assumed to be up-to-date, and should not be considered for recompilation. In Ada, if the sources of this externally built project were compiled with another version of the compiler or with incompatible options, the binder will issue an error.
The project's `with' clause has several effects. It provides source visibility between projects during the compilation process. It also guarantees that the necessary object files from Logging and GtkAda are available when linking Build.
As can be seen in this example, the syntax for importing projects is similar to the syntax for importing compilation units in Ada. However, project files use literal strings instead of names, and the `with' clause identifies project files rather than packages.
Each literal string after `with' is the path
(absolute or relative) to a project file. The .gpr extension is
optional, although we recommend adding it. If no extension is specified,
and no project file with the
.gpr extension is found, then
the file is searched for exactly as written in the `with' clause,
that is with no extension.
As mentioned above, the path after a `with' has to be a literal string, and you cannot use concatenation, or lookup the value of external variables to change the directories from which a project is loaded. A solution if you need something like this is to use aggregate projects (see Aggregate Projects).
When a relative path or a base name is used, the project files are searched relative to each of the directories in the `project path'. This path includes all the directories found with the following algorithm, in this order; the first matching file is used:
<prefix>/<target>/lib/gnat(for `gnatmake' in all cases, and for `gprbuild' if option `–target' is specified)
<prefix>/<target>/share/gpr(for `gnatmake' in all cases, and for `gprbuild' if option `–target' is specified)
<prefix>/share/gpr/(for `gnatmake' and `gprbuild')
<prefix>/lib/gnat/(for `gnatmake' and `gprbuild')
In our example,
gtkada.gpr is found in the predefined directory if
it was installed at the same root as GNAT.
Some tools also support extending the project path from the command line, generally through the `-aP'. You can see the value of the project path by using the `gnatls -v' command.
Any symbolic link will be fully resolved in the directory of the importing project file before the imported project file is examined.
Any source file in the imported project can be used by the sources of the importing project, transitively. Thus if A imports B, which imports C, the sources of A may depend on the sources of C, even if A does not import C explicitly. However, this is not recommended, because if and when B ceases to import C, some sources in A will no longer compile. `gprbuild' has a switch `–no-indirect-imports' that will report such indirect dependencies.
Note: One very important aspect of a project hierarchy is that `a given source can only belong to one project' (otherwise the project manager would not know which settings apply to it and when to recompile it). It means that different project files do not usually share source directories or when they do, they need to specify precisely which project owns which sources using attribute Source_Files or equivalent. By contrast, 2 projects can each own a source with the same base file name as long as they live in different directories. The latter is not true for Ada Sources because of the correlation between source files and Ada units.