Next: , Up: Organizing Projects into Subsystems

11.3.1 Project Dependencies

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.

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^.GPR^ extension is found, then the file is searched for exactly as written in the with clause, that is with no extension.

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:

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.

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.