GtkAda comes with its own project file (appropriately called gtkada.gpr), and we will assume we have already built a project called 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 easily 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, gnatmake 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, the attribute Externally_Built to
"true" can be set, 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.
with clause has several effects. It provides source
visibility between projects during the compilation process. It also guarantees
that the necessary object files from
available when linking
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^.GPR^ extension is found, then
the file is searched for exactly as written in the
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 that order, as soon as a matching file is found, the search stops:
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.
B, which imports
C, the sources of
A may depend on the sources of
C, even if
A does not
C explicitly. However, this is not recommended, because if
B ceases to import
C, some sources in
no longer compile. gprbuild has a switch --no-indirect-imports
that will report such indirect dependencies.
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
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.