We now have a project file that fully describes our environment, and can be
used to build the application with a simple `gprbuild' command as seen
in the previous section. In fact, the empty project we showed immediately at
the beginning (with no attribute at all) could already fulfill that need if it
was put in the
Of course, we might want more control. This section shows you how to specify the compilation switches that the various tools involved in the building of the executable should use.
Since source names and locations are described in the project file, it is not necessary to use switches on the command line for this purpose (switches such as -I for gcc). This removes a major source of command line length overflow. Clearly, the builders will have to communicate this information one way or another to the underlying compilers and tools they call but they usually use response files for this and thus are not subject to command line overflows.
Several tools participate to the creation of an executable: the compiler produces object files from the source files; the binder (in the Ada case) creates a "source" file that takes care, among other things, of elaboration issues and global variable initialization; and the linker gathers everything into a single executable that users can execute. All these tools are known to the project manager and will be called with user defined switches from the project files. However, we need to introduce a new project file concept to express the switches to be used for any of the tools involved in the build.
A project file is subdivided into zero or more `packages', each of which contains the attributes specific to one tool (or one set of tools). Project files use an Ada-like syntax for packages. Package names permitted in project files are restricted to a predefined set (see Packages), and the contents of packages are limited to a small set of constructs and attributes (see Attributes).
Our example project file can be extended with the following empty packages. At this stage, they could all be omitted since they are empty, but they show which packages would be involved in the build process.
project Build is for Source_Dirs use ("common"); for Object_Dir use "obj"; for Exec_Dir use "."; for Main use ("proc.adb"); package Builder is --<<< for gprbuild end Builder; package Compiler is --<<< for the compiler end Compiler; package Binder is --<<< for the binder end Binder; package Linker is --<<< for the linker end Linker; end Build;
Let's first examine the compiler switches. As stated in the initial description of the example, we want to compile all files with `-O2'. This is a compiler switch, although it is usual, on the command line, to pass it to the builder which then passes it to the compiler. It is recommended to use directly the right package, which will make the setup easier to understand for other people.
Several attributes can be used to specify the switches:
This is the first mention in this manual of an `indexed attribute'. When this attribute is defined, one must supply an `index' in the form of a literal string. In the case of `Default_Switches', the index is the name of the language to which the switches apply (since a different compiler will likely be used for each language, and each compiler has its own set of switches). The value of the attribute is a list of switches.
In this example, we want to compile all Ada source files with the switch `-O2', and the resulting project file is as follows (only the Compiler package is shown):package Compiler is for Default_Switches ("Ada") use ("-O2"); end Compiler;
In some cases, we might want to use specific switches for one or more files. For instance, compiling
proc.adbmight not be possible at high level of optimization because of a compiler issue. In such a case, the `Switches' attribute (indexed on the file name) can be used and will override the switches defined by `Default_Switches'. Our project file would become:package Compiler is for Default_Switches ("Ada") use ("-O2"); for Switches ("proc.adb") use ("-O0"); end Compiler;
Switches may take a pattern as an index, such as in:package Compiler is for Default_Switches ("Ada") use ("-O2"); for Switches ("pkg*") use ("-O0"); end Compiler;
pkg-child.adbwould be compiled with -O0, not -O2.
Switches can also be given a language name as index instead of a file name in which case it has the same semantics as `Default_Switches'. However, indexes with wild cards are never valid for language name.
This attribute may specify the path of a file containing configuration pragmas for use by the Ada compiler, such as pragma Restrictions (No_Tasking). These pragmas will be used for all the sources of the project.
The switches for the other tools are defined in a similar manner through the `Default_Switches' and `Switches' attributes, respectively in the `Builder' package (for `gprbuild'), the `Binder' package (binding Ada executables) and the `Linker' package (for linking executables).