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:
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;
abstract project Shared is for Source_Files use (); -- no project 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).