Next: Global Attributes, Previous: Cyclic Project Dependencies, Up: Organizing Projects into Subsystems
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 adding a 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:
build.gpr
imports logging.gpr
, we could change it
to reference the attribute in Logging, either through a package renaming,
or by referencing the attribute. The following example shows both cases:
project Logging is package Compiler is for Switches ("Ada") use ("-O2"); end Compiler; package Binder is for Switches ("Ada") use ("-E"); end Binder; end Logging; with "logging.gpr"; project Build is package Compiler renames Logging.Compiler; package Binder is for 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;
shared.gpr
.
abstract project Shared is for Source_Files use (); -- no sources package Compiler is for Switches ("Ada") use ("-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 indicate that Shared has no sources is so that it can be created in any directory and we are sure it shares no sources with Build or 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).