When building an application, it is common to have similar needs in several of the projects corresponding to the subsystems under construction. For instance, they will all have the same compilation switches.
As seen before (see Tools Options in Project Files), setting compilation
switches for all sources of a subsystem is simple: it is just a matter of
Compiler.Default_Switches attribute to each project files with
the same value. Of course, that means duplication of data, and both places need
to be changed in order to recompile the whole application with different
switches. It can become a real problem if there are many subsystems and thus
many project files to edit.
There are two main approaches to avoiding this duplication:
project Logging is package Compiler is for ^Switches^Switches^ ("Ada") use ("^-O2^-O2^"); end Compiler; package Binder is for ^Switches^Switches^ ("Ada") use ("-E"); end Binder; end Logging; with "logging.gpr"; project Build is package Compiler renames Logging.Compiler; package Binder is for ^Switches^Switches^ ("Ada") use Logging.Binder'Switches ("Ada"); end Binder; end Build;
The solution used for
Compiler gets the same value for all
attributes of the package, but you cannot modify anything from the
package (adding extra switches or some exceptions). The second
version is more flexible, but more verbose.
If you need to refer to the value of a variable in an imported project, rather than an attribute, the syntax is similar but uses a "." rather than an apostrophe. For instance:
with "imported"; project Main is Var1 := Imported.Var; end Main;
abstract project Shared is for Source_Files use (); -- no sources package Compiler is for ^Switches^Switches^ ("Ada") use ("^-O2^-O2^"); end Compiler; end Shared; with "shared.gpr"; project Logging is package Compiler renames Shared.Compiler; end Logging; with "shared.gpr"; project Build is package Compiler renames Shared.Compiler; end Build;
As for the first example, we could have chosen to set the attributes
one by one rather than to rename a package. The reason we explicitly
Shared has no sources is so that it can be created
in any directory and we are sure it shares no sources with
Logging, which of course would be invalid.
Note the additional use of the abstract qualifier in shared.gpr. This qualifier is optional, but helps convey the message that we do not intend this project to have sources (see Qualified Projects for more qualifiers).