From 554fd8c5195424bdbcabf5de30fdc183aba391bd Mon Sep 17 00:00:00 2001 From: upstream source tree Date: Sun, 15 Mar 2015 20:14:05 -0400 Subject: obtained gcc-4.6.4.tar.bz2 from upstream website; verified gcc-4.6.4.tar.bz2.sig; imported gcc-4.6.4 source tree from verified upstream tarball. downloading a git-generated archive based on the 'upstream' tag should provide you with a source tree that is binary identical to the one extracted from the above tarball. if you have obtained the source via the command 'git clone', however, do note that line-endings of files in your working directory might differ from line-endings of the respective files in the upstream repository. --- gcc/ada/projects.texi | 3969 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 3969 insertions(+) create mode 100644 gcc/ada/projects.texi (limited to 'gcc/ada/projects.texi') diff --git a/gcc/ada/projects.texi b/gcc/ada/projects.texi new file mode 100644 index 000000000..36c915ffe --- /dev/null +++ b/gcc/ada/projects.texi @@ -0,0 +1,3969 @@ +@set gprconfig GPRconfig + +@c ------ projects.texi +@c This file is shared between the GNAT user's guide and gprbuild. It is not +@c compilable on its own, you should instead compile the other two manuals. +@c For that reason, there is no toplevel @menu + +@c --------------------------------------------- +@node GNAT Project Manager +@chapter GNAT Project Manager +@c --------------------------------------------- + +@noindent +@menu +* Introduction:: +* Building With Projects:: +* Organizing Projects into Subsystems:: +* Scenarios in Projects:: +* Library Projects:: +* Project Extension:: +* Project File Reference:: +@end menu + +@c --------------------------------------------- +@node Introduction +@section Introduction +@c --------------------------------------------- + +@noindent +This chapter describes GNAT's @emph{Project Manager}, a facility that allows +you to manage complex builds involving a number of source files, directories, +and options for different system configurations. In particular, +project files allow you to specify: + +@itemize @bullet +@item The directory or set of directories containing the source files, and/or the + names of the specific source files themselves +@item The directory in which the compiler's output + (@file{ALI} files, object files, tree files, etc.) is to be placed +@item The directory in which the executable programs are to be placed +@item Switch settings for any of the project-enabled tools; + you can apply these settings either globally or to individual compilation units. +@item The source files containing the main subprogram(s) to be built +@item The source programming language(s) +@item Source file naming conventions; you can specify these either globally or for + individual compilation units (@pxref{Naming Schemes}). +@item Change any of the above settings depending on external values, thus enabling + the reuse of the projects in various @b{scenarios} (@pxref{Scenarios in Projects}). +@item Automatically build libraries as part of the build process + (@pxref{Library Projects}). + +@end itemize + +@noindent +Project files are written in a syntax close to that of Ada, using familiar +notions such as packages, context clauses, declarations, default values, +assignments, and inheritance (@pxref{Project File Reference}). + +Project files can be built hierarchically from other project files, simplifying +complex system integration and project reuse (@pxref{Organizing Projects into +Subsystems}). + +@itemize @bullet +@item One project can import other projects containing needed source files. + More generally, the Project Manager lets you structure large development + efforts into hierarchical subsystems, where build decisions are delegated + to the subsystem level, and thus different compilation environments + (switch settings) used for different subsystems. +@item You can organize GNAT projects in a hierarchy: a child project + can extend a parent project, inheriting the parent's source files and + optionally overriding any of them with alternative versions + (@pxref{Project Extension}). + +@end itemize + +@noindent +Several tools support project files, generally in addition to specifying +the information on the command line itself). They share common switches +to control the loading of the project (in particular +@option{^-P^/PROJECT_FILE=^@emph{projectfile}} and +@option{^-X^/EXTERNAL_REFERENCE=^@emph{vbl}=@emph{value}}). +@xref{Switches Related to Project Files}. + +The Project Manager supports a wide range of development strategies, +for systems of all sizes. Here are some typical practices that are +easily handled: + +@itemize @bullet +@item Using a common set of source files and generating object files in different + directories via different switch settings. It can be used for instance, for + generating separate sets of object files for debugging and for production. +@item Using a mostly-shared set of source files with different versions of + some units or subunits. It can be used for instance, for grouping and hiding +@end itemize + +@noindent +all OS dependencies in a small number of implementation units. + +Project files can be used to achieve some of the effects of a source +versioning system (for example, defining separate projects for +the different sets of sources that comprise different releases) but the +Project Manager is independent of any source configuration management tool +that might be used by the developers. + +The various sections below introduce the different concepts related to +projects. Each section starts with examples and use cases, and then goes into +the details of related project file capabilities. + +@c --------------------------------------------- +@node Building With Projects +@section Building With Projects +@c --------------------------------------------- + +@noindent +In its simplest form, a unique project is used to build a single executable. +This section concentrates on such a simple setup. Later sections will extend +this basic model to more complex setups. + +The following concepts are the foundation of project files, and will be further +detailed later in this documentation. They are summarized here as a reference. + +@table @asis +@item @b{Project file}: + A text file using an Ada-like syntax, generally using the @file{.gpr} + extension. It defines build-related characteristics of an application. + The characteristics include the list of sources, the location of those + sources, the location for the generated object files, the name of + the main program, and the options for the various tools involved in the + build process. + +@item @b{Project attribute}: + A specific project characteristic is defined by an attribute clause. Its + value is a string or a sequence of strings. All settings in a project + are defined through a list of predefined attributes with precise + semantics. @xref{Attributes}. + +@item @b{Package in a project}: + Global attributes are defined at the top level of a project. + Attributes affecting specific tools are grouped in a + package whose name is related to tool's function. The most common + packages are @code{Builder}, @code{Compiler}, @code{Binder}, + and @code{Linker}. @xref{Packages}. + +@item @b{Project variables}: + In addition to attributes, a project can use variables to store intermediate + values and avoid duplication in complex expressions. It can be initialized + with a value coming from the environment. + A frequent use of variables is to define scenarios. + @xref{External Values}, @xref{Scenarios in Projects}, and @xref{Variables}. + +@item @b{Source files} and @b{source directories}: + A source file is associated with a language through a naming convention. For + instance, @code{foo.c} is typically the name of a C source file; + @code{bar.ads} or @code{bar.1.ada} are two common naming conventions for a + file containing an Ada spec. A compilation unit is often composed of a main + source file and potentially several auxiliary ones, such as header files in C. + The naming conventions can be user defined @xref{Naming Schemes}, and will + drive the builder to call the appropriate compiler for the given source file. + Source files are searched for in the source directories associated with the + project through the @b{Source_Dirs} attribute. By default, all the files (in + these source directories) following the naming conventions associated with the + declared languages are considered to be part of the project. It is also + possible to limit the list of source files using the @b{Source_Files} or + @b{Source_List_File} attributes. Note that those last two attributes only + accept basenames with no directory information. + +@item @b{Object files} and @b{object directory}: + An object file is an intermediate file produced by the compiler from a + compilation unit. It is used by post-compilation tools to produce + final executables or libraries. Object files produced in the context of + a given project are stored in a single directory that can be specified by the + @b{Object_Dir} attribute. In order to store objects in + two or more object directories, the system must be split into + distinct subsystems with their own project file. + +@end table + +The following subsections introduce gradually all the attributes of interest +for simple build needs. Here is the simple setup that will be used in the +following examples. + +The Ada source files @file{pack.ads}, @file{pack.adb}, and @file{proc.adb} are in +the @file{common/} directory. The file @file{proc.adb} contains an Ada main +subprogram @code{Proc} that @code{with}s package @code{Pack}. We want to compile +these source files with the switch @option{-O2}, and put the resulting files in +the directory @file{obj/}. + +@smallexample +@group +^common/^[COMMON]^ + pack.ads + pack.adb + proc.adb +@end group +@group +^common/release/^[COMMON.RELEASE]^ + proc.ali, proc.o pack.ali, pack.o +@end group +@end smallexample + +@noindent +Our project is to be called @emph{Build}. The name of the +file is the name of the project (case-insensitive) with the +@file{.gpr} extension, therefore the project file name is @file{build.gpr}. This +is not mandatory, but a warning is issued when this convention is not followed. + +This is a very simple example, and as stated above, a single project +file is enough for it. We will thus create a new file, that for now +should contain the following code: + +@smallexample +@b{project} Build @b{is} +@b{end} Build; +@end smallexample + +@menu +* Source Files and Directories:: +* Object and Exec Directory:: +* Main Subprograms:: +* Tools Options in Project Files:: +* Compiling with Project Files:: +* Executable File Names:: +* Avoid Duplication With Variables:: +* Naming Schemes:: +@end menu + +@c --------------------------------------------- +@node Source Files and Directories +@subsection Source Files and Directories +@c --------------------------------------------- + +@noindent +When you create a new project, the first thing to describe is how to find the +corresponding source files. This is the only settings that are needed by all +the tools that will use this project (builder, compiler, binder and linker for +the compilation, IDEs to edit the source files,@dots{}). + +@cindex Source directories +First step is to declare the source directories, which are the directories +to be searched to find source files. In the case of the example, +the @file{common} directory is the only source directory. + +@cindex @code{Source_Dirs} +There are several ways of defining source directories: + +@itemize @bullet +@item When the attribute @b{Source_Dirs} is not used, a project contains a + single source directory which is the one where the project file itself + resides. In our example, if @file{build.gpr} is placed in the @file{common} + directory, the project has the needed implicit source directory. + +@item The attribute @b{Source_Dirs} can be set to a list of path names, one + for each of the source directories. Such paths can either be absolute + names (for instance @file{"/usr/local/common/"} on UNIX), or relative to the + directory in which the project file resides (for instance "." if + @file{build.gpr} is inside @file{common/}, or "common" if it is one level up). + Each of the source directories must exist and be readable. + +@cindex portability + The syntax for directories is platform specific. For portability, however, + the project manager will always properly translate UNIX-like path names to + the native format of specific platform. For instance, when the same project + file is to be used both on Unix and Windows, "/" should be used as the + directory separator rather than "\". + +@item The attribute @b{Source_Dirs} can automatically include subdirectories + using a special syntax inspired by some UNIX shells. If any of the path in + the list ends with @emph{"/**"}, then that path and all its subdirectories + (recursively) are included in the list of source directories. For instance, + @file{./**} represent the complete directory tree rooted at ".". +@cindex Source directories, recursive + +@cindex @code{Excluded_Source_Dirs} + When using that construct, it can sometimes be convenient to also use the + attribute @b{Excluded_Source_Dirs}, which is also a list of paths. Each entry + specifies a directory whose immediate content, not including subdirs, is to + be excluded. It is also possible to exclude a complete directory subtree + using the "/**" notation. + +@cindex @code{Ignore_Source_Sub_Dirs} + It is often desirable to remove, from the source directories, directory + subtrees rooted at some subdirectories. An example is the subdirectories + created by a Version Control System such as Subversion that creates directory + subtrees .svn/**. To do that, attribute @b{Ignore_Source_Sub_Dirs} can be + used. It specifies the list of simple file names for the root of these + undesirable directory subtrees. + +@end itemize + +@noindent +When applied to the simple example, and because we generally prefer to have +the project file at the toplevel directory rather than mixed with the sources, +we will create the following file + +@smallexample + build.gpr + @b{project} Build @b{is} + @b{for} Source_Dirs @b{use} ("common"); -- <<<< + @b{end} Build; +@end smallexample + +@noindent +Once source directories have been specified, one may need to indicate +source files of interest. By default, all source files present in the source +directories are considered by the project manager. When this is not desired, +it is possible to specify the list of sources to consider explicitly. +In such a case, only source file base names are indicated and not +their absolute or relative path names. The project manager is in charge of +locating the specified source files in the specified source directories. + +@itemize @bullet +@item By default, the project manager search for all source files of all + specified languages in all the source directories. + + Since the project manager was initially developed for Ada environments, the + default language is usually Ada and the above project file is complete: it + defines without ambiguity the sources composing the project: that is to say, + all the sources in subdirectory "common" for the default language (Ada) using + the default naming convention. + +@cindex @code{Languages} + However, when compiling a multi-language application, or a pure C + application, the project manager must be told which languages are of + interest, which is done by setting the @b{Languages} attribute to a list of + strings, each of which is the name of a language. Tools like + @command{gnatmake} only know about Ada, while other tools like + @command{gprbuild} know about many more languages such as C, C++, Fortran, + assembly and others can be added dynamically. + +@cindex Naming scheme + Even when using only Ada, the default naming might not be suitable. Indeed, + how does the project manager recognizes an "Ada file" from any other + file? Project files can describe the naming scheme used for source files, + and override the default (@pxref{Naming Schemes}). The default is the + standard GNAT extension (@file{.adb} for bodies and @file{.ads} for + specs), which is what is used in our example, explaining why no naming scheme + is explicitly specified. + @xref{Naming Schemes}. + +@item @code{Source Files} + @cindex @code{Source_Files} + In some cases, source directories might contain files that should not be + included in a project. One can specify the explicit list of file names to + be considered through the @b{Source_Files} attribute. + When this attribute is defined, instead of looking at every file in the + source directories, the project manager takes only those names into + consideration reports errors if they cannot be found in the source + directories or does not correspond to the naming scheme. + +@item For various reasons, it is sometimes useful to have a project with no + sources (most of the time because the attributes defined in the project + file will be reused in other projects, as explained in + @pxref{Organizing Projects into Subsystems}. To do this, the attribute + @emph{Source_Files} is set to the empty list, i.e. @code{()}. Alternatively, + @emph{Source_Dirs} can be set to the empty list, with the same + result. + +@item @code{Source_List_File} +@cindex @code{Source_List_File} + If there is a great number of files, it might be more convenient to use + the attribute @b{Source_List_File}, which specifies the full path of a file. + This file must contain a list of source file names (one per line, no + directory information) that are searched as if they had been defined + through @emph{Source_Files}. Such a file can easily be created through + external tools. + + A warning is issued if both attributes @code{Source_Files} and + @code{Source_List_File} are given explicit values. In this case, the + attribute @code{Source_Files} prevails. + +@item @code{Excluded_Source_Files} +@cindex @code{Excluded_Source_Files} +@cindex @code{Locally_Removed_Files} +@cindex @code{Excluded_Source_List_File} + Specifying an explicit list of files is not always convenient.It might be + more convenient to use the default search rules with specific exceptions. + This can be done thanks to the attribute @b{Excluded_Source_Files} + (or its synonym @b{Locally_Removed_Files}). + Its value is the list of file names that should not be taken into account. + This attribute is often used when extending a project, + @xref{Project Extension}. A similar attribute + @b{Excluded_Source_List_File} plays the same + role but takes the name of file containing file names similarly to + @code{Source_List_File}. + +@end itemize + +@noindent +In most simple cases, such as the above example, the default source file search +behavior provides the expected result, and we do not need to add anything after +setting @code{Source_Dirs}. The project manager automatically finds +@file{pack.ads}, @file{pack.adb} and @file{proc.adb} as source files of the +project. + +Note that it is considered an error for a project file to have no sources +attached to it unless explicitly declared as mentioned above. + +If the order of the source directories is known statically, that is if +@code{"/**"} is not used in the string list @code{Source_Dirs}, then there may +be several files with the same source file name sitting in different +directories of the project. In this case, only the file in the first directory +is considered as a source of the project and the others are hidden. If +@code{"/**"} is not used in the string list @code{Source_Dirs}, it is an error +to have several files with the same source file name in the same directory +@code{"/**"} subtree, since there would be an ambiguity as to which one should +be used. However, two files with the same source file name may in two single +directories or directory subtrees. In this case, the one in the first directory +or directory subtree is a source of the project. + +@c --------------------------------------------- +@node Object and Exec Directory +@subsection Object and Exec Directory +@c --------------------------------------------- + +@noindent +The next step when writing a project is to indicate where the compiler should +put the object files. In fact, the compiler and other tools might create +several different kind of files (for GNAT, there is the object file and the ALI +file for instance). One of the important concepts in projects is that most +tools may consider source directories as read-only and do not attempt to create +new or temporary files there. Instead, all files are created in the object +directory. It is of course not true for project-aware IDEs, whose purpose it is +to create the source files. + +@cindex @code{Object_Dir} +The object directory is specified through the @b{Object_Dir} attribute. +Its value is the path to the object directory, either absolute or +relative to the directory containing the project file. This +directory must already exist and be readable and writable, although +some tools have a switch to create the directory if needed (See +the switch @code{-p} for @command{gnatmake} and @command{gprbuild}). + +If the attribute @code{Object_Dir} is not specified, it defaults to +the project directory, that is the directory containing the project file. + +For our example, we can specify the object dir in this way: + +@smallexample + @b{project} Build @b{is} + @b{for} Source_Dirs @b{use} ("common"); + @b{for} Object_Dir @b{use} "obj"; -- <<<< + @b{end} Build; +@end smallexample + +@noindent +As mentioned earlier, there is a single object directory per project. As a +result, if you have an existing system where the object files are spread in +several directories, you can either move all of them into the same directory if +you want to build it with a single project file, or study the section on +subsystems (@pxref{Organizing Projects into Subsystems}) to see how each +separate object directory can be associated with one of the subsystem +constituting the application. + +When the @command{linker} is called, it usually creates an executable. By +default, this executable is placed in the object directory of the project. It +might be convenient to store it in its own directory. + +@cindex @code{Exec_Dir} +This can be done through the @code{Exec_Dir} attribute, which, like +@emph{Object_Dir} contains a single absolute or relative path and must point to +an existing and writable directory, unless you ask the tool to create it on +your behalf. When not specified, It defaults to the object directory and +therefore to the project file's directory if neither @emph{Object_Dir} nor +@emph{Exec_Dir} was specified. + +In the case of the example, let's place the executable in the root +of the hierarchy, ie the same directory as @file{build.gpr}. Hence +the project file is now + +@smallexample + @b{project} Build @b{is} + @b{for} Source_Dirs @b{use} ("common"); + @b{for} Object_Dir @b{use} "obj"; + @b{for} Exec_Dir @b{use} "."; -- <<<< + @b{end} Build; +@end smallexample + +@c --------------------------------------------- +@node Main Subprograms +@subsection Main Subprograms +@c --------------------------------------------- + +@noindent +In the previous section, executables were mentioned. The project manager needs +to be taught what they are. In a project file, an executable is indicated by +pointing to source file of the main subprogram. In C this is the file that +contains the @code{main} function, and in Ada the file that contains the main +unit. + +There can be any number of such main files within a given project, and thus +several executables can be built in the context of a single project file. Of +course, one given executable might not (and in fact will not) need all the +source files referenced by the project. As opposed to other build environments +such as @command{makefile}, one does not need to specify the list of +dependencies of each executable, the project-aware builders knows enough of the +semantics of the languages to build ands link only the necessary elements. + +@cindex @code{Main} +The list of main files is specified via the @b{Main} attribute. It contains +a list of file names (no directories). If a project defines this +attribute, it is not necessary to identify main files on the +command line when invoking a builder, and editors like +@command{GPS} will be able to create extra menus to spawn or debug the +corresponding executables. + +@smallexample + @b{project} Build @b{is} + @b{for} Source_Dirs @b{use} ("common"); + @b{for} Object_Dir @b{use} "obj"; + @b{for} Exec_Dir @b{use} "."; + @b{for} Main @b{use} ("proc.adb"); -- <<<< + @b{end} Build; +@end smallexample + +@noindent +If this attribute is defined in the project, then spawning the builder +with a command such as + +@smallexample + gnatmake ^-Pbuild^/PROJECT_FILE=build^ +@end smallexample + +@noindent +automatically builds all the executables corresponding to the files +listed in the @emph{Main} attribute. It is possible to specify one +or more executables on the command line to build a subset of them. + +@c --------------------------------------------- +@node Tools Options in Project Files +@subsection Tools Options in Project Files +@c --------------------------------------------- + +@noindent +We now have a project file that fully describes our environment, and can be +used to build the application with a simple @command{gnatmake} 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 @file{common} directory. + +Of course, we always want more control. This section will show you how to +specify the compilation switches that the various tools involved in the +building of the executable should use. + +@cindex command line length +Since source names and locations are described into 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 should not be subject to command line +overflows. + +Several tools are participating to the creation of an executable: the compiler +produces object files from the source files; the binder (in the Ada case) +creates an source file that takes care, among other things, of elaboration +issues and global variables initialization; and the linker gathers everything +into a single executable that users can execute. All these tools are known by +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 which switches to be used for any of the tools involved in the build. + +@cindex project file packages +A project file is subdivided into zero or more @b{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 (@pxref{Packages}), and the contents +of packages are limited to a small set of constructs and attributes +(@pxref{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. + +@smallexample + @b{project} Build @b{is} + @b{for} Source_Dirs @b{use} ("common"); + @b{for} Object_Dir @b{use} "obj"; + @b{for} Exec_Dir @b{use} "."; + @b{for} Main @b{use} ("proc.adb"); + @b{end} Build; + + @b{package} Builder @b{is} --<<< for gnatmake and gprbuild + @b{end} Builder; + + @b{package} Compiler @b{is} --<<< for the compiler + @b{end} Compiler; + + @b{package} Binder @b{is} --<<< for the binder + @b{end} Binder; + + @b{package} Linker @b{is} --<<< for the linker + @b{end} Linker; +@end smallexample + +@noindent +Let's first examine the compiler switches. As stated in the initial description +of the example, we want to compile all files with @option{-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: + +@table @asis +@item @b{Default_Switches}: +@cindex @code{Default_Switches} + This is the first mention in this manual of an @b{indexed attribute}. When + this attribute is defined, one must supply an @emph{index} in the form of a + literal string. + In the case of @emph{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 + @option{-O2} switch, and the resulting project file is as follows + (only the @code{Compiler} package is shown): + + @smallexample + @b{package} Compiler @b{is} + @b{for} Default_Switches ("Ada") @b{use} ("-O2"); + @b{end} Compiler; + @end smallexample + +@item @b{Switches}: +@cindex @code{Switches} + in some cases, we might want to use specific switches + for one or more files. For instance, compiling @file{proc.adb} might not be + possible at high level of optimization because of a compiler issue. + In such a case, the @emph{Switches} + attribute (indexed on the file name) can be used and will override the + switches defined by @emph{Default_Switches}. Our project file would + become: + + @smallexample + @b{package} Compiler @b{is} + @b{for} Default_Switches ("Ada") @b{use} ("-O2"); + @b{for} Switches ("proc.adb") @b{use} ("-O0"); + @b{end} Compiler; + @end smallexample + + @noindent + @code{Switches} may take a pattern as an index, such as in: + + @smallexample + @b{package} Compiler @b{is} + @b{for} Default_Switches ("Ada") @b{use} ("-O2"); + @b{for} Switches ("pkg*") @b{use} ("-O0"); + @b{end} Compiler; + @end smallexample + + @noindent + Sources @file{pkg.adb} and @file{pkg-child.adb} would be compiled with -O0, + not -O2. + + @noindent + @code{Switches} can also be given a language name as index instead of a file + name in which case it has the same semantics as @emph{Default_Switches}. + However, indexes with wild cards are never valid for language name. + +@item @b{Local_Configuration_Pragmas}: +@cindex @code{Local_Configuration_Pragmas} + this attribute may specify the path + of a file containing configuration pragmas for use by the Ada compiler, + such as @code{pragma Restrictions (No_Tasking)}. These pragmas will be + used for all the sources of the project. + +@end table + +The switches for the other tools are defined in a similar manner through the +@b{Default_Switches} and @b{Switches} attributes, respectively in the +@emph{Builder} package (for @command{gnatmake} and @command{gprbuild}), +the @emph{Binder} package (binding Ada executables) and the @emph{Linker} +package (for linking executables). + +@c --------------------------------------------- +@node Compiling with Project Files +@subsection Compiling with Project Files +@c --------------------------------------------- + +@noindent +Now that our project files are written, let's build our executable. +Here is the command we would use from the command line: + +@smallexample + gnatmake ^-Pbuild^/PROJECT_FILE=build^ +@end smallexample + +@noindent +This will automatically build the executables specified through the +@emph{Main} attribute: for each, it will compile or recompile the +sources for which the object file does not exist or is not up-to-date; it +will then run the binder; and finally run the linker to create the +executable itself. + +@command{gnatmake} only knows how to handle Ada files. By using +@command{gprbuild} as a builder, you could automatically manage C files the +same way: create the file @file{utils.c} in the @file{common} directory, +set the attribute @emph{Languages} to @code{"(Ada, C)"}, and run + +@smallexample + gprbuild ^-Pbuild^/PROJECT_FILE=build^ +@end smallexample + +@noindent +Gprbuild knows how to recompile the C files and will +recompile them only if one of their dependencies has changed. No direct +indication on how to build the various elements is given in the +project file, which describes the project properties rather than a +set of actions to be executed. Here is the invocation of +@command{gprbuild} when building a multi-language program: + +@smallexample +$ gprbuild -Pbuild +gcc -c proc.adb +gcc -c pack.adb +gcc -c utils.c +gprbind proc +... +gcc proc.o -o proc +@end smallexample + +@noindent +Notice the three steps described earlier: + +@itemize @bullet +@item The first three gcc commands correspond to the compilation phase. +@item The gprbind command corresponds to the post-compilation phase. +@item The last gcc command corresponds to the final link. + +@end itemize + +@noindent +@cindex @option{-v} option (for GPRbuild) +The default output of GPRbuild's execution is kept reasonably simple and easy +to understand. In particular, some of the less frequently used commands are not +shown, and some parameters are abbreviated. So it is not possible to rerun the +effect of the gprbuild command by cut-and-pasting its output. GPRbuild's option +@code{-v} provides a much more verbose output which includes, among other +information, more complete compilation, post-compilation and link commands. + +@c --------------------------------------------- +@node Executable File Names +@subsection Executable File Names +@c --------------------------------------------- + +@noindent +@cindex @code{Executable} +By default, the executable name corresponding to a main file is +computed from the main source file name. Through the attribute +@b{Builder.Executable}, it is possible to change this default. + +For instance, instead of building @command{proc} (or @command{proc.exe} +on Windows), we could configure our project file to build "proc1" +(resp proc1.exe) with the following addition: + +@smallexample @c projectfile + project Build is + ... -- same as before + package Builder is + for Executable ("proc.adb") use "proc1"; + end Builder + end Build; +@end smallexample + +@noindent +@cindex @code{Executable_Suffix} +Attribute @b{Executable_Suffix}, when specified, may change the suffix +of the executable files, when no attribute @code{Executable} applies: +its value replace the platform-specific executable suffix. +The default executable suffix is empty on UNIX and ".exe" on Windows. + +It is also possible to change the name of the produced executable by using the +command line switch @option{-o}. When several mains are defined in the project, +it is not possible to use the @option{-o} switch and the only way to change the +names of the executable is provided by Attributes @code{Executable} and +@code{Executable_Suffix}. + +@c --------------------------------------------- +@node Avoid Duplication With Variables +@subsection Avoid Duplication With Variables +@c --------------------------------------------- + +@noindent +To illustrate some other project capabilities, here is a slightly more complex +project using similar sources and a main program in C: + +@smallexample @c projectfile +project C_Main is + for Languages use ("Ada", "C"); + for Source_Dirs use ("common"); + for Object_Dir use "obj"; + for Main use ("main.c"); + package Compiler is + C_Switches := ("-pedantic"); + for Default_Switches ("C") use C_Switches; + for Default_Switches ("Ada") use ("-gnaty"); + for Switches ("main.c") use C_Switches & ("-g"); + end Compiler; +end C_Main; +@end smallexample + +@noindent +This project has many similarities with the previous one. +As expected, its @code{Main} attribute now refers to a C source. +The attribute @emph{Exec_Dir} is now omitted, thus the resulting +executable will be put in the directory @file{obj}. + +The most noticeable difference is the use of a variable in the +@emph{Compiler} package to store settings used in several attributes. +This avoids text duplication, and eases maintenance (a single place to +modify if we want to add new switches for C files). We will revisit +the use of variables in the context of scenarios (@pxref{Scenarios in +Projects}). + +In this example, we see how the file @file{main.c} can be compiled with +the switches used for all the other C files, plus @option{-g}. +In this specific situation the use of a variable could have been +replaced by a reference to the @code{Default_Switches} attribute: + +@smallexample @c projectfile + for Switches ("c_main.c") use Compiler'Default_Switches ("C") & ("-g"); +@end smallexample + +@noindent +Note the tick (@emph{'}) used to refer to attributes defined in a package. + +Here is the output of the GPRbuild command using this project: + +@smallexample +$gprbuild -Pc_main +gcc -c -pedantic -g main.c +gcc -c -gnaty proc.adb +gcc -c -gnaty pack.adb +gcc -c -pedantic utils.c +gprbind main.bexch +... +gcc main.o -o main +@end smallexample + +@noindent +The default switches for Ada sources, +the default switches for C sources (in the compilation of @file{lib.c}), +and the specific switches for @file{main.c} have all been taken into +account. + +@c --------------------------------------------- +@node Naming Schemes +@subsection Naming Schemes +@c --------------------------------------------- + +@noindent +Sometimes an Ada software system is ported from one compilation environment to +another (say GNAT), and the file are not named using the default GNAT +conventions. Instead of changing all the file names, which for a variety of +reasons might not be possible, you can define the relevant file naming scheme +in the @b{Naming} package of your project file. + +The naming scheme has two distinct goals for the project manager: it +allows finding of source files when searching in the source +directories, and given a source file name it makes it possible to guess +the associated language, and thus the compiler to use. + +Note that the use by the Ada compiler of pragmas Source_File_Name is not +supported when using project files. You must use the features described in this +paragraph. You can however specify other configuration pragmas +(@pxref{Specifying Configuration Pragmas}). + +The following attributes can be defined in package @code{Naming}: + +@table @asis +@item @b{Casing}: +@cindex @code{Casing} + Its value must be one of @code{"lowercase"} (the default if + unspecified), @code{"uppercase"} or @code{"mixedcase"}. It describes the + casing of file names with regards to the Ada unit name. Given an Ada unit + My_Unit, the file name will respectively be @file{my_unit.adb} (lowercase), + @file{MY_UNIT.ADB} (uppercase) or @file{My_Unit.adb} (mixedcase). + On Windows, file names are case insensitive, so this attribute is + irrelevant. + +@item @b{Dot_Replacement}: +@cindex @code{Dot_Replacement} + This attribute specifies the string that should replace the "." in unit + names. Its default value is @code{"-"} so that a unit + @code{Parent.Child} is expected to be found in the file + @file{parent-child.adb}. The replacement string must satisfy the following + requirements to avoid ambiguities in the naming scheme: + + @itemize - + @item It must not be empty + @item It cannot start or end with an alphanumeric character + @item It cannot be a single underscore + @item It cannot start with an underscore followed by an alphanumeric + @item It cannot contain a dot @code{'.'} except if the entire string + is @code{"."} + + @end itemize + +@item @b{Spec_Suffix} and @b{Specification_Suffix}: +@cindex @code{Spec_Suffix} +@cindex @code{Specification_Suffix} + For Ada, these attributes give the suffix used in file names that contain + specifications. For other languages, they give the extension for files + that contain declaration (header files in C for instance). The attribute + is indexed on the language. + The two attributes are equivalent, but the latter is obsolescent. + If @code{Spec_Suffix ("Ada")} is not specified, then the default is + @code{"^.ads^.ADS^"}. + The value must satisfy the following requirements: + + @itemize - + @item It must not be empty + @item It cannot start with an alphanumeric character + @item It cannot start with an underscore followed by an alphanumeric character + @item It must include at least one dot + + @end itemize + +@item @b{Body_Suffix} and @b{Implementation_Suffix}: +@cindex @code{Body_Suffix} +@cindex @code{Implementation_Suffix} + These attributes give the extension used for file names that contain + code (bodies in Ada). They are indexed on the language. The second + version is obsolescent and fully replaced by the first attribute. + + These attributes must satisfy the same requirements as @code{Spec_Suffix}. + In addition, they must be different from any of the values in + @code{Spec_Suffix}. + If @code{Body_Suffix ("Ada")} is not specified, then the default is + @code{"^.adb^.ADB^"}. + + If @code{Body_Suffix ("Ada")} and @code{Spec_Suffix ("Ada")} end with the + same string, then a file name that ends with the longest of these two + suffixes will be a body if the longest suffix is @code{Body_Suffix ("Ada")} + or a spec if the longest suffix is @code{Spec_Suffix ("Ada")}. + + If the suffix does not start with a '.', a file with a name exactly equal + to the suffix will also be part of the project (for instance if you define + the suffix as @code{Makefile}, a file called @file{Makefile} will be part + of the project. This capability is usually not interesting when building. + However, it might become useful when a project is also used to + find the list of source files in an editor, like the GNAT Programming System + (GPS). + +@item @b{Separate_Suffix}: +@cindex @code{Separate_Suffix} + This attribute is specific to Ada. It denotes the suffix used in file names + that contain separate bodies. If it is not specified, then it defaults to + same value as @code{Body_Suffix ("Ada")}. The same rules apply as for the + @code{Body_Suffix} attribute. The only accepted index is "Ada". + +@item @b{Spec} or @b{Specification}: +@cindex @code{Spec} +@cindex @code{Specification} + This attribute @code{Spec} can be used to define the source file name for a + given Ada compilation unit's spec. The index is the literal name of the Ada + unit (case insensitive). The value is the literal base name of the file that + contains this unit's spec (case sensitive or insensitive depending on the + operating system). This attribute allows the definition of exceptions to the + general naming scheme, in case some files do not follow the usual + convention. + + When a source file contains several units, the relative position of the unit + can be indicated. The first unit in the file is at position 1 + + @smallexample @c projectfile + for Spec ("MyPack.MyChild") use "mypack.mychild.spec"; + for Spec ("top") use "foo.a" at 1; + for Spec ("foo") use "foo.a" at 2; + @end smallexample + +@item @b{Body} or @b{Implementation}: +@cindex @code{Body} +@cindex @code{Implementation} + These attribute play the same role as @emph{Spec} for Ada bodies. + +@item @b{Specification_Exceptions} and @b{Implementation_Exceptions}: +@cindex @code{Specification_Exceptions} +@cindex @code{Implementation_Exceptions} + These attributes define exceptions to the naming scheme for languages + other than Ada. They are indexed on the language name, and contain + a list of file names respectively for headers and source code. + + +@end table + +@ifclear vms +For example, the following package models the Apex file naming rules: + +@smallexample @c projectfile +@group + package Naming is + for Casing use "lowercase"; + for Dot_Replacement use "."; + for Spec_Suffix ("Ada") use ".1.ada"; + for Body_Suffix ("Ada") use ".2.ada"; + end Naming; +@end group +@end smallexample +@end ifclear + +@ifset vms +For example, the following package models the DEC Ada file naming rules: + +@smallexample @c projectfile +@group + package Naming is + for Casing use "lowercase"; + for Dot_Replacement use "__"; + for Spec_Suffix ("Ada") use "_.ada"; + for Body_Suffix ("Ada") use ".ada"; + end Naming; +@end group +@end smallexample + +@noindent +(Note that @code{Casing} is @code{"lowercase"} because GNAT gets the file +names in lower case) +@end ifset + +@c --------------------------------------------- +@node Organizing Projects into Subsystems +@section Organizing Projects into Subsystems +@c --------------------------------------------- + +@noindent +A @b{subsystem} is a coherent part of the complete system to be built. It is +represented by a set of sources and one single object directory. A system can +be composed of a single subsystem when it is simple as we have seen in the +first section. Complex systems are usually composed of several interdependent +subsystems. A subsystem is dependent on another subsystem if knowledge of the +other one is required to build it, and in particular if visibility on some of +the sources of this other subsystem is required. Each subsystem is usually +represented by its own project file. + +In this section, the previous example is being extended. Let's assume some +sources of our @code{Build} project depend on other sources. +For instance, when building a graphical interface, it is usual to depend upon +a graphical library toolkit such as GtkAda. Furthermore, we also need +sources from a logging module we had previously written. + +@menu +* Project Dependencies:: +* Cyclic Project Dependencies:: +* Sharing Between Projects:: +* Global Attributes:: +@end menu + +@c --------------------------------------------- +@node Project Dependencies +@subsection Project Dependencies +@c --------------------------------------------- + +@noindent +GtkAda comes with its own project file (appropriately called +@file{gtkada.gpr}), and we will assume we have already built a project +called @file{logging.gpr} for the logging module. With the information provided +so far in @file{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 @b{with} clauses at the beginning +of our project: + +@smallexample @c projectfile + with "gtkada.gpr"; + with "a/b/logging.gpr"; + project Build is + ... -- as before + end Build; +@end smallexample + +@noindent +@cindex @code{Externally_Built} +When such a project is compiled, @command{gnatmake} will automatically +check the other projects and recompile their sources when needed. It will also +recompile the sources from @code{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 @b{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 @code{with} clause has several effects. It provides source +visibility between projects during the compilation process. It also guarantees +that the necessary object files from @code{Logging} and @code{GtkAda} are +available when linking @code{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 @code{with} clause identifies +project files rather than packages. + +Each literal string after @code{with} is the path +(absolute or relative) to a project file. The @code{.gpr} extension is +optional, although we recommend adding it. If no extension is specified, +and no project file with the @file{^.gpr^.GPR^} extension is found, then +the file is searched for exactly as written in the @code{with} clause, +that is with no extension. + +@cindex project path +When a relative path or a base name is used, the +project files are searched relative to each of the directories in the +@b{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: + +@itemize @bullet +@item First, the file is searched relative to the directory that contains the + current project file. +@item +@cindex @code{ADA_PROJECT_PATH} +@cindex @code{GPR_PROJECT_PATH} + Then it is searched relative to all the directories specified in the + ^environment variables^logical names^ @b{GPR_PROJECT_PATH} and + @b{ADA_PROJECT_PATH} (in that order) if they exist. The former is + recommended, the latter is kept for backward compatibility. +@item Finally, it is searched relative to the default project directories. + Such directories depends on the tool used. For @command{gnatmake}, there is + one default project directory: @file{/lib/gnat/}. In our example, + @file{gtkada.gpr} is found in the predefined directory if it was installed at + the same root as GNAT. + +@end itemize + +@noindent +Some tools also support extending the project path from the command line, +generally through the @option{-aP}. You can see the value of the project +path by using the @command{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 @code{A} imports @code{B}, which imports @code{C}, the sources of +@code{A} may depend on the sources of @code{C}, even if @code{A} does not +import @code{C} explicitly. However, this is not recommended, because if +and when @code{B} ceases to import @code{C}, some sources in @code{A} will +no longer compile. @command{gprbuild} has a switch @option{--no-indirect-imports} +that will report such indirect dependencies. + +One very important aspect of a project hierarchy is that +@b{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 @code{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. + +@c --------------------------------------------- +@node Cyclic Project Dependencies +@subsection Cyclic Project Dependencies +@c --------------------------------------------- + +@noindent +Cyclic dependencies are mostly forbidden: +if @code{A} imports @code{B} (directly or indirectly) then @code{B} +is not allowed to import @code{A}. However, there are cases when cyclic +dependencies would be beneficial. For these cases, another form of import +between projects exists: the @b{limited with}. A project @code{A} that +imports a project @code{B} with a straight @code{with} may also be imported, +directly or indirectly, by @code{B} through a @code{limited with}. + +The difference between straight @code{with} and @code{limited with} is that +the name of a project imported with a @code{limited with} cannot be used in the +project importing it. In particular, its packages cannot be renamed and +its variables cannot be referred to. + +@smallexample @c 0projectfile +with "b.gpr"; +with "c.gpr"; +project A is + For Exec_Dir use B'Exec_Dir; -- ok +end A; + +limited with "a.gpr"; -- Cyclic dependency: A -> B -> A +project B is + For Exec_Dir use A'Exec_Dir; -- not ok +end B; + +with "d.gpr"; +project C is +end C; + +limited with "a.gpr"; -- Cyclic dependency: A -> C -> D -> A +project D is + For Exec_Dir use A'Exec_Dir; -- not ok +end D; +@end smallexample + +@c --------------------------------------------- +@node Sharing Between Projects +@subsection Sharing Between Projects +@c --------------------------------------------- + +@noindent +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 (@pxref{Tools Options in Project Files}), setting compilation +switches for all sources of a subsystem is simple: it is just a matter of +adding a @code{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: + +@itemize @bullet +@item Since @file{build.gpr} imports @file{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: + + @smallexample @c projectfile + 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; + @end smallexample + + @noindent + The solution used for @code{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: + + @smallexample @c projectfile + with "imported"; + project Main is + Var1 := Imported.Var; + end Main; + @end smallexample + +@item The second approach is to define the switches in a third project. + That project is setup without any sources (so that, as opposed to + the first example, none of the project plays a special role), and + will only be used to define the attributes. Such a project is + typically called @file{shared.gpr}. + + @smallexample @c projectfile + 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; + @end smallexample + + @noindent + 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 @code{Shared} has no sources is so that it can be created + in any directory and we are sure it shares no sources with @code{Build} + or @code{Logging}, which of course would be invalid. + +@cindex project qualifier + Note the additional use of the @b{abstract} qualifier in @file{shared.gpr}. + This qualifier is optional, but helps convey the message that we do not + intend this project to have sources (@pxref{Qualified Projects} for + more qualifiers). +@end itemize + + +@c --------------------------------------------- +@node Global Attributes +@subsection Global Attributes +@c --------------------------------------------- + +@noindent +We have already seen many examples of attributes used to specify a special +option of one of the tools involved in the build process. Most of those +attributes are project specific. That it to say, they only affect the invocation +of tools on the sources of the project where they are defined. + +There are a few additional attributes that apply to all projects in a +hierarchy as long as they are defined on the "main" project. +The main project is the project explicitly mentioned on the command-line. +The project hierarchy is the "with"-closure of the main project. + +Here is a list of commonly used global attributes: + +@table @asis +@item @b{Builder.Global_Configuration_Pragmas}: +@cindex @code{Global_Configuration_Pragmas} + This attribute points to a file that contains configuration pragmas + to use when building executables. These pragmas apply for all + executables build from this project hierarchy. As we have seen before, + additional pragmas can be specified on a per-project basis by setting the + @code{Compiler.Local_Configuration_Pragmas} attribute. + +@item @b{Builder.Global_Compilation_Switches}: +@cindex @code{Global_Compilation_Switches} + This attribute is a list of compiler switches to use when compiling any + source file in the project hierarchy. These switches are used in addition + to the ones defined in the @code{Compiler} package, which only apply to + the sources of the corresponding project. This attribute is indexed on + the name of the language. + +@end table + +Using such global capabilities is convenient. It can also lead to unexpected +behavior. Especially when several subsystems are shared among different main +projects and the different global attributes are not +compatible. Note that using aggregate projects can be a safer and more powerful +replacement to global attributes. + +@c --------------------------------------------- +@node Scenarios in Projects +@section Scenarios in Projects +@c --------------------------------------------- + +@noindent +Various aspects of the projects can be modified based on @b{scenarios}. These +are user-defined modes that change the behavior of a project. Typical +examples are the setup of platform-specific compiler options, or the use of +a debug and a release mode (the former would activate the generation of debug +information, when the second will focus on improving code optimization). + +Let's enhance our example to support a debug and a release modes.The issue is to +let the user choose what kind of system he is building: +use @option{-g} as compiler switches in debug mode and @option{-O2} +in release mode. We will also setup the projects so that we do not share the +same object directory in both modes, otherwise switching from one to the other +might trigger more recompilations than needed or mix objects from the 2 modes. + +One naive approach is to create two different project files, say +@file{build_debug.gpr} and @file{build_release.gpr}, that set the appropriate +attributes as explained in previous sections. This solution does not scale well, +because in presence of multiple projects depending on each other, +you will also have to duplicate the complete hierarchy and adapt the project +files to point to the right copies. + +@cindex scenarios +Instead, project files support the notion of scenarios controlled +by external values. Such values can come from several sources (in decreasing +order of priority): + +@table @asis +@item @b{Command line}: +@cindex @option{-X} + When launching @command{gnatmake} or @command{gprbuild}, the user can pass + extra @option{-X} switches to define the external value. In + our case, the command line might look like + + @smallexample + gnatmake -Pbuild.gpr -Xmode=debug + or gnatmake -Pbuild.gpr -Xmode=release + @end smallexample + +@item @b{^Environment variables^Logical names^}: + When the external value does not come from the command line, it can come from + the value of ^environment variables^logical names^ of the appropriate name. + In our case, if ^an environment variable^a logical name^ called "mode" + exist, its value will be taken into account. + +@item @b{External function second parameter} + +@end table + +@cindex @code{external} +We now need to get that value in the project. The general form is to use +the predefined function @b{external} which returns the current value of +the external. For instance, we could setup the object directory to point to +either @file{obj/debug} or @file{obj/release} by changing our project to + +@smallexample @c projectfile + project Build is + for Object_Dir use "obj/" & external ("mode", "debug"); + ... -- as before + end Build; +@end smallexample + +@noindent +The second parameter to @code{external} is optional, and is the default +value to use if "mode" is not set from the command line or the environment. + +In order to set the switches according to the different scenarios, other +constructs have to be introduced such as typed variables and case statements. + +@cindex typed variable +@cindex case statement +A @b{typed variable} is a variable that +can take only a limited number of values, similar to an enumeration in Ada. +Such a variable can then be used in a @b{case statement} and create conditional +sections in the project. The following example shows how this can be done: + +@smallexample @c projectfile + project Build is + type Mode_Type is ("debug", "release"); -- all possible values + Mode : Mode_Type := external ("mode", "debug"); -- a typed variable + + package Compiler is + case Mode is + when "debug" => + for Switches ("Ada") use ("-g"); + when "release" => + for Switches ("Ada") use ("-O2"); + end case; + end Compiler; + end Build; +@end smallexample + +@noindent +The project has suddenly grown in size, but has become much more flexible. +@code{Mode_Type} defines the only valid values for the @code{mode} variable. If +any other value is read from the environment, an error is reported and the +project is considered as invalid. + +The @code{Mode} variable is initialized with an external value +defaulting to @code{"debug"}. This default could be omitted and that would +force the user to define the value. Finally, we can use a case statement to set the +switches depending on the scenario the user has chosen. + +Most aspects of the projects can depend on scenarios. The notable exception +are project dependencies (@code{with} clauses), which may not depend on a scenario. + +Scenarios work the same way with @b{project hierarchies}: you can either +duplicate a variable similar to @code{Mode} in each of the project (as long +as the first argument to @code{external} is always the same and the type is +the same), or simply set the variable in the @file{shared.gpr} project +(@pxref{Sharing Between Projects}). + +@c --------------------------------------------- +@node Library Projects +@section Library Projects +@c --------------------------------------------- + +@noindent +So far, we have seen examples of projects that create executables. However, +it is also possible to create libraries instead. A @b{library} is a specific +type of subsystem where, for convenience, objects are grouped together +using system-specific means such as archives or windows DLLs. + +Library projects provide a system- and language-independent way of building both @b{static} +and @b{dynamic} libraries. They also support the concept of @b{standalone +libraries} (SAL) which offers two significant properties: the elaboration +(e.g. initialization) of the library is either automatic or very simple; +a change in the +implementation part of the library implies minimal post-compilation actions on +the complete system and potentially no action at all for the rest of the +system in the case of dynamic SALs. + +The GNAT Project Manager takes complete care of the library build, rebuild and +installation tasks, including recompilation of the source files for which +objects do not exist or are not up to date, assembly of the library archive, and +installation of the library (i.e., copying associated source, object and +@file{ALI} files to the specified location). + +@menu +* Building Libraries:: +* Using Library Projects:: +* Stand-alone Library Projects:: +* Installing a library with project files:: +@end menu + +@c --------------------------------------------- +@node Building Libraries +@subsection Building Libraries +@c --------------------------------------------- + +@noindent +Let's enhance our example and transform the @code{logging} subsystem into a +library. In order to do so, a few changes need to be made to @file{logging.gpr}. +A number of specific attributes needs to be defined: at least @code{Library_Name} +and @code{Library_Dir}; in addition, a number of other attributes can be used +to specify specific aspects of the library. For readability, it is also +recommended (although not mandatory), to use the qualifier @code{library} in +front of the @code{project} keyword. + +@table @asis +@item @b{Library_Name}: +@cindex @code{Library_Name} + This attribute is the name of the library to be built. There is no + restriction on the name of a library imposed by the project manager; + however, there may be system specific restrictions on the name. + In general, it is recommended to stick to alphanumeric characters + (and possibly underscores) to help portability. + +@item @b{Library_Dir}: +@cindex @code{Library_Dir} + This attribute is the path (absolute or relative) of the directory where + the library is to be installed. In the process of building a library, + the sources are compiled, the object files end up in the explicit or + implicit @code{Object_Dir} directory. When all sources of a library + are compiled, some of the compilation artifacts, including the library itself, + are copied to the library_dir directory. This directory must exists and be + writable. It must also be different from the object directory so that cleanup + activities in the Library_Dir do not affect recompilation needs. + +@end table + +Here is the new version of @file{logging.gpr} that makes it a library: + +@smallexample @c projectfile +library project Logging is -- "library" is optional + for Library_Name use "logging"; -- will create "liblogging.a" on Unix + for Object_Dir use "obj"; + for Library_Dir use "lib"; -- different from object_dir +end Logging; +@end smallexample + +@noindent +Once the above two attributes are defined, the library project is valid and +is enough for building a library with default characteristics. +Other library-related attributes can be used to change the defaults: + +@table @asis +@item @b{Library_Kind}: +@cindex @code{Library_Kind} + The value of this attribute must be either @code{"static"}, @code{"dynamic"} or + @code{"relocatable"} (the latter is a synonym for dynamic). It indicates + which kind of library should be build (the default is to build a + static library, that is an archive of object files that can potentially + be linked into a static executable). When the library is set to be dynamic, + a separate image is created that will be loaded independently, usually + at the start of the main program execution. Support for dynamic libraries is + very platform specific, for instance on Windows it takes the form of a DLL + while on GNU/Linux, it is a dynamic elf image whose suffix is usually + @file{.so}. Library project files, on the other hand, can be written in + a platform independent way so that the same project file can be used to build + a library on different operating systems. + + If you need to build both a static and a dynamic library, it is recommended + use two different object directories, since in some cases some extra code + needs to be generated for the latter. For such cases, one can + either define two different project files, or a single one which uses scenarios + to indicate at the various kinds of library to be build and their + corresponding object_dir. + +@cindex @code{Library_ALI_Dir} +@item @b{Library_ALI_Dir}: + This attribute may be specified to indicate the directory where the ALI + files of the library are installed. By default, they are copied into the + @code{Library_Dir} directory, but as for the executables where we have a + separate @code{Exec_Dir} attribute, you might want to put them in a separate + directory since there can be hundreds of them. The same restrictions as for + the @code{Library_Dir} attribute apply. + +@cindex @code{Library_Version} +@item @b{Library_Version}: + This attribute is platform dependent, and has no effect on VMS and Windows. + On Unix, it is used only for dynamic libraries as the internal + name of the library (the @code{"soname"}). If the library file name (built + from the @code{Library_Name}) is different from the @code{Library_Version}, + then the library file will be a symbolic link to the actual file whose name + will be @code{Library_Version}. This follows the usual installation schemes + for dynamic libraries on many Unix systems. + +@smallexample @c projectfile +@group + project Logging is + Version := "1"; + for Library_Dir use "lib"; + for Library_Name use "logging"; + for Library_Kind use "dynamic"; + for Library_Version use "liblogging.so." & Version; + end Logging; +@end group +@end smallexample + + @noindent + After the compilation, the directory @file{lib} will contain both a + @file{libdummy.so.1} library and a symbolic link to it called + @file{libdummy.so}. + +@cindex @code{Library_GCC} +@item @b{Library_GCC}: + This attribute is the name of the tool to use instead of "gcc" to link shared + libraries. A common use of this attribute is to define a wrapper script that + accomplishes specific actions before calling gcc (which itself is calling the + linker to build the library image). + +@item @b{Library_Options}: +@cindex @code{Library_Options} + This attribute may be used to specified additional switches (last switches) + when linking a shared library. + +@item @b{Leading_Library_Options}: +@cindex @code{Leading_Library_Options} + This attribute, that is taken into account only by @command{gprbuild}, may be + used to specified leading options (first switches) when linking a shared + library. + +@cindex @code{Linker_Options} +@item @b{Linker.Linker_Options}: + This attribute specifies additional switches to be given to the linker when + linking an executable. It is ignored when defined in the main project and + taken into account in all other projects that are imported directly or + indirectly. These switches complement the @code{Linker.Switches} + defined in the main project. This is useful when a particular subsystem + depends on an external library: adding this dependency as a + @code{Linker_Options} in the project of the subsystem is more convenient than + adding it to all the @code{Linker.Switches} of the main projects that depend + upon this subsystem. +@end table + + +@c --------------------------------------------- +@node Using Library Projects +@subsection Using Library Projects +@c --------------------------------------------- + +@noindent +When the builder detects that a project file is a library project file, it +recompiles all sources of the project that need recompilation and rebuild the +library if any of the sources have been recompiled. It then groups all object +files into a single file, which is a shared or a static library. This library +can later on be linked with multiple executables. Note that the use +of shard libraries reduces the size of the final executable and can also reduce +the memory footprint at execution time when the library is shared among several +executables. + +It is also possible to build @b{multi-language libraries}. When using +@command{gprbuild} as a builder, multi-language library projects allow naturally +the creation of multi-language libraries . @command{gnatmake}, does not try to +compile non Ada sources. However, when the project is multi-language, it will +automatically link all object files found in the object directory, whether or +not they were compiled from an Ada source file. This specific behavior does not +apply to Ada-only projects which only take into account the objects +corresponding to the sources of the project. + +A non-library project can import a library project. When the builder is invoked +on the former, the library of the latter is only rebuilt when absolutely +necessary. For instance, if a unit of the +library is not up-to-date but non of the executables need this unit, then the +unit is not recompiled and the library is not reassembled. +For instance, let's assume in our example that logging has the following +sources: @file{log1.ads}, @file{log1.adb}, @file{log2.ads} and +@file{log2.adb}. If @file{log1.adb} has been modified, then the library +@file{liblogging} will be rebuilt when compiling all the sources of +@code{Build} only if @file{proc.ads}, @file{pack.ads} or @file{pack.adb} +include a @code{"with Log1"}. + +To ensure that all the sources in the @code{Logging} library are +up to date, and that all the sources of @code{Build} are also up to date, +the following two commands needs to be used: + +@smallexample +gnatmake -Plogging.gpr +gnatmake -Pbuild.gpr +@end smallexample + +@noindent +All @file{ALI} files will also be copied from the object directory to the +library directory. To build executables, @command{gnatmake} will use the +library rather than the individual object files. + +@ifclear vms +Library projects can also be useful to describe a library that need to be used +but, for some reason, cannot be rebuilt. For instance, it is the case when some +of the library sources are not available. Such library projects need simply to +use the @code{Externally_Built} attribute as in the example below: + +@smallexample @c projectfile +library project Extern_Lib is + for Languages use ("Ada", "C"); + for Source_Dirs use ("lib_src"); + for Library_Dir use "lib2"; + for Library_Kind use "dynamic"; + for Library_Name use "l2"; + for Externally_Built use "true"; -- <<<< +end Extern_Lib; +@end smallexample + +@noindent +In the case of externally built libraries, the @code{Object_Dir} +attribute does not need to be specified because it will never be +used. + +The main effect of using such an externally built library project is mostly to +affect the linker command in order to reference the desired library. It can +also be achieved by using @code{Linker.Linker_Options} or @code{Linker.Switches} +in the project corresponding to the subsystem needing this external library. +This latter method is more straightforward in simple cases but when several +subsystems depend upon the same external library, finding the proper place +for the @code{Linker.Linker_Options} might not be easy and if it is +not placed properly, the final link command is likely to present ordering issues. +In such a situation, it is better to use the externally built library project +so that all other subsystems depending on it can declare this dependency thanks +to a project @code{with} clause, which in turn will trigger the builder to find +the proper order of libraries in the final link command. +@end ifclear + +@c --------------------------------------------- +@node Stand-alone Library Projects +@subsection Stand-alone Library Projects +@c --------------------------------------------- + +@noindent +@cindex standalone libraries +A @b{stand-alone library} is a library that contains the necessary code to +elaborate the Ada units that are included in the library. A stand-alone +library is a convenient way to add an Ada subsystem to a more global system +whose main is not in Ada since it makes the elaboration of the Ada part mostly +transparent. However, stand-alone libraries are also useful when the main is in +Ada: they provide a means for minimizing relinking & redeployment of complex +systems when localized changes are made. + +The most prominent characteristic of a stand-alone library is that it offers a +distinction between interface units and implementation units. Only the former +are visible to units outside the library. A stand-alone library project is thus +characterised by a third attribute, @b{Library_Interface}, in addition to the +two attributes that make a project a Library Project (@code{Library_Name} and +@code{Library_Dir}). + +@table @asis +@item @b{Library_Interface}: +@cindex @code{Library_Interface} + This attribute defines an explicit subset of the units of the project. + Projects importing this library project may only "with" units whose sources + are listed in the @code{Library_Interface}. Other sources are considered + implementation units. + +@smallexample @c projectfile +@group + for Library_Dir use "lib"; + for Library_Name use "loggin"; + for Library_Interface use ("lib1", "lib2"); -- unit names +@end group +@end smallexample + +@end table + +In order to include the elaboration code in the stand-alone library, the binder +is invoked on the closure of the library units creating a package whose name +depends on the library name (^b~logging.ads/b^B$LOGGING.ADS/B^ in the example). +This binder-generated package includes @b{initialization} and @b{finalization} +procedures whose names depend on the library name (@code{logginginit} and +@code{loggingfinal} in the example). The object corresponding to this package is +included in the library. + +@table @asis +@item @b{Library_Auto_Init}: +@cindex @code{Library_Auto_Init} + A dynamic stand-alone Library is automatically initialized + if automatic initialization of Stand-alone Libraries is supported on the + platform and if attribute @b{Library_Auto_Init} is not specified or + is specified with the value "true". A static Stand-alone Library is never + automatically initialized. Specifying "false" for this attribute + prevent automatic initialization. + + When a non-automatically initialized stand-alone library is used in an + executable, its initialization procedure must be called before any service of + the library is used. When the main subprogram is in Ada, it may mean that the + initialization procedure has to be called during elaboration of another + package. + +@item @b{Library_Dir}: +@cindex @code{Library_Dir} + For a stand-alone library, only the @file{ALI} files of the interface units + (those that are listed in attribute @code{Library_Interface}) are copied to + the library directory. As a consequence, only the interface units may be + imported from Ada units outside of the library. If other units are imported, + the binding phase will fail. + +@item @b{Binder.Default_Switches}: + When a stand-alone library is bound, the switches that are specified in + the attribute @b{Binder.Default_Switches ("Ada")} are + used in the call to @command{gnatbind}. + +@item @b{Library_Src_Dir}: +@cindex @code{Library_Src_Dir} + This attribute defines the location (absolute or relative to the project + directory) where the sources of the interface units are copied at + installation time. + These sources includes the specs of the interface units along with the closure + of sources necessary to compile them successfully. That may include bodies and + subunits, when pragmas @code{Inline} are used, or when there is a generic + units in the spec. This directory cannot point to the object directory or + one of the source directories, but it can point to the library directory, + which is the default value for this attribute. + +@item @b{Library_Symbol_Policy}: +@cindex @code{Library_Symbol_Policy} + This attribute controls the export of symbols and, on some platforms (like + VMS) that have the notions of major and minor IDs built in the library + files, it controls the setting of these IDs. It is not supported on all + platforms (where it will just have no effect). It may have one of the + following values: + + @itemize - + @item @code{"autonomous"} or @code{"default"}: exported symbols are not controlled + @item @code{"compliant"}: if attribute @b{Library_Reference_Symbol_File} + is not defined, then it is equivalent to policy "autonomous". If there + are exported symbols in the reference symbol file that are not in the + object files of the interfaces, the major ID of the library is increased. + If there are symbols in the object files of the interfaces that are not + in the reference symbol file, these symbols are put at the end of the list + in the newly created symbol file and the minor ID is increased. + @item @code{"controlled"}: the attribute @b{Library_Reference_Symbol_File} must be + defined. The library will fail to build if the exported symbols in the + object files of the interfaces do not match exactly the symbol in the + symbol file. + @item @code{"restricted"}: The attribute @b{Library_Symbol_File} must be defined. + The library will fail to build if there are symbols in the symbol file that + are not in the exported symbols of the object files of the interfaces. + Additional symbols in the object files are not added to the symbol file. + @item @code{"direct"}: The attribute @b{Library_Symbol_File} must be defined and + must designate an existing file in the object directory. This symbol file + is passed directly to the underlying linker without any symbol processing. + + @end itemize + +@item @b{Library_Reference_Symbol_File} +@cindex @code{Library_Reference_Symbol_File} + This attribute may define the path name of a reference symbol file that is + read when the symbol policy is either "compliant" or "controlled", on + platforms that support symbol control, such as VMS, when building a + stand-alone library. The path may be an absolute path or a path relative + to the project directory. + +@item @b{Library_Symbol_File} +@cindex @code{Library_Symbol_File} + This attribute may define the name of the symbol file to be created when + building a stand-alone library when the symbol policy is either "compliant", + "controlled" or "restricted", on platforms that support symbol control, + such as VMS. When symbol policy is "direct", then a file with this name + must exist in the object directory. +@end table + + +@c --------------------------------------------- +@node Installing a library with project files +@subsection Installing a library with project files +@c --------------------------------------------- + +@noindent +When using project files, library installation is part of the library build +process. Thus no further action is needed in order to make use of the +libraries that are built as part of the general application build. A usable +version of the library is installed in the directory specified by the +@code{Library_Dir} attribute of the library project file. + +You may want to install a library in a context different from where the library +is built. This situation arises with third party suppliers, who may want +to distribute a library in binary form where the user is not expected to be +able to recompile the library. The simplest option in this case is to provide +a project file slightly different from the one used to build the library, by +using the @code{externally_built} attribute. @ref{Using Library Projects} + +@c --------------------------------------------- +@node Project Extension +@section Project Extension +@c --------------------------------------------- + +@noindent +During development of a large system, it is sometimes necessary to use +modified versions of some of the source files, without changing the original +sources. This can be achieved through the @b{project extension} facility. + +Suppose for instance that our example @code{Build} project is build every night +for the whole team, in some shared directory. A developer usually need to work +on a small part of the system, and might not want to have a copy of all the +sources and all the object files (mostly because that would require too much +disk space, time to recompile everything). He prefers to be able to override +some of the source files in his directory, while taking advantage of all the +object files generated at night. + +Another example can be taken from large software systems, where it is common to have +multiple implementations of a common interface; in Ada terms, multiple +versions of a package body for the same spec. For example, one implementation +might be safe for use in tasking programs, while another might only be used +in sequential applications. This can be modeled in GNAT using the concept +of @emph{project extension}. If one project (the ``child'') @emph{extends} +another project (the ``parent'') then by default all source files of the +parent project are inherited by the child, but the child project can +override any of the parent's source files with new versions, and can also +add new files or remove unnecessary ones. +This facility is the project analog of a type extension in +object-oriented programming. Project hierarchies are permitted (an extending +project may itself be extended), and a project that +extends a project can also import other projects. + +A third example is that of using project extensions to provide different +versions of the same system. For instance, assume that a @code{Common} +project is used by two development branches. One of the branches has now +been frozen, and no further change can be done to it or to @code{Common}. +However, the other development branch still needs evolution of @code{Common}. +Project extensions provide a flexible solution to create a new version +of a subsystem while sharing and reusing as much as possible from the original +one. + +A project extension inherits implicitly all the sources and objects from the +project it extends. It is possible to create a new version of some of the +sources in one of the additional source dirs of the extending project. Those new +versions hide the original versions. Adding new sources or removing existing +ones is also possible. Here is an example on how to extend the project +@code{Build} from previous examples: + +@smallexample @c projectfile + project Work extends "../bld/build.gpr" is + end Work; +@end smallexample + +@noindent +The project after @b{extends} is the one being extended. As usual, it can be +specified using an absolute path, or a path relative to any of the directories +in the project path (@pxref{Project Dependencies}). This project does not +specify source or object directories, so the default value for these attribute +will be used that is to say the current directory (where project @code{Work} is +placed). We can already compile that project with + +@smallexample + gnatmake -Pwork +@end smallexample + +@noindent +If no sources have been placed in the current directory, this command +won't do anything, since this project does not change the +sources it inherited from @code{Build}, therefore all the object files +in @code{Build} and its dependencies are still valid and are reused +automatically. + +Suppose we now want to supply an alternate version of @file{pack.adb} +but use the existing versions of @file{pack.ads} and @file{proc.adb}. +We can create the new file Work's current directory (likely +by copying the one from the @code{Build} project and making changes to +it. If new packages are needed at the same time, we simply create +new files in the source directory of the extending project. + +When we recompile, @command{gnatmake} will now automatically recompile +this file (thus creating @file{pack.o} in the current directory) and +any file that depends on it (thus creating @file{proc.o}). Finally, the +executable is also linked locally. + +Note that we could have obtained the desired behavior using project import +rather than project inheritance. A @code{base} project would contain the +sources for @file{pack.ads} and @file{proc.adb}, and @code{Work} would +import @code{base} and add @file{pack.adb}. In this scenario, @code{base} +cannot contain the original version of @file{pack.adb} otherwise there would be +2 versions of the same unit in the closure of the project and this is not +allowed. Generally speaking, it is not recommended to put the spec and the +body of a unit in different projects since this affects their autonomy and +reusability. + +In a project file that extends another project, it is possible to +indicate that an inherited source is @b{not part} of the sources of the +extending project. This is necessary sometimes when a package spec has +been overridden and no longer requires a body: in this case, it is +necessary to indicate that the inherited body is not part of the sources +of the project, otherwise there will be a compilation error +when compiling the spec. + +@cindex @code{Excluded_Source_Files} +@cindex @code{Excluded_Source_List_File} +For that purpose, the attribute @b{Excluded_Source_Files} is used. +Its value is a list of file names. +It is also possible to use attribute @code{Excluded_Source_List_File}. +Its value is the path of a text file containing one file name per +line. + +@smallexample @c @projectfile +project Work extends "../bld/build.gpr" is + for Source_Files use ("pack.ads"); + -- New spec of Pkg does not need a completion + for Excluded_Source_Files use ("pack.adb"); +end Work; +@end smallexample + +@noindent +An extending project retains all the switches specified in the +extended project. + +@menu +* Project Hierarchy Extension:: +@end menu + +@c --------------------------------------------- +@node Project Hierarchy Extension +@subsection Project Hierarchy Extension +@c --------------------------------------------- + +@noindent +One of the fundamental restrictions in project extension is the following: +@b{A project is not allowed to import directly or indirectly at the same time an +extending project and one of its ancestors}. + +By means of example, consider the following hierarchy of projects. + +@smallexample + a.gpr contains package A1 + b.gpr, imports a.gpr and contains B1, which depends on A1 + c.gpr, imports b.gpr and contains C1, which depends on B1 +@end smallexample + +@noindent +If we want to locally extend the packages @code{A1} and @code{C1}, we need to +create several extending projects: + +@smallexample + a_ext.gpr which extends a.gpr, and overrides A1 + b_ext.gpr which extends b.gpr and imports a_ext.gpr + c_ext.gpr which extends c.gpr, imports b_ext.gpr and overrides C1 +@end smallexample + +@noindent +@smallexample @c projectfile + project A_Ext extends "a.gpr" is + for Source_Files use ("a1.adb", "a1.ads"); + end A_Ext; + + with "a_ext.gpr"; + project B_Ext extends "b.gpr" is + end B_Ext; + + with "b_ext.gpr"; + project C_Ext extends "c.gpr" is + for Source_Files use ("c1.adb"); + end C_Ext; +@end smallexample + +@noindent +The extension @file{b_ext.gpr} is required, even though we are not overriding +any of the sources of @file{b.gpr} because otherwise @file{c_expr.gpr} would +import @file{b.gpr} which itself knows nothing about @file{a_ext.gpr}. + +@cindex extends all +When extending a large system spanning multiple projects, it is often +inconvenient to extend every project in the hierarchy that is impacted by a +small change introduced in a low layer. In such cases, it is possible to create +an @b{implicit extension} of entire hierarchy using @b{extends all} +relationship. + +When the project is extended using @code{extends all} inheritance, all projects +that are imported by it, both directly and indirectly, are considered virtually +extended. That is, the project manager creates implicit projects +that extend every project in the hierarchy; all these implicit projects do not +control sources on their own and use the object directory of +the "extending all" project. + +It is possible to explicitly extend one or more projects in the hierarchy +in order to modify the sources. These extending projects must be imported by +the "extending all" project, which will replace the corresponding virtual +projects with the explicit ones. + +When building such a project hierarchy extension, the project manager will +ensure that both modified sources and sources in implicit extending projects +that depend on them, are recompiled. + +Thus, in our example we could create the following projects instead: + +@smallexample + a_ext.gpr, extends a.gpr and overrides A1 + c_ext.gpr, "extends all" c.gpr, imports a_ext.gpr and overrides C1 + +@end smallexample + +@noindent +@smallexample @c projectfile + project A_Ext extends "a.gpr" is + for Source_Files use ("a1.adb", "a1.ads"); + end A_Ext; + + with "a_ext.gpr"; + project C_Ext extends all "c.gpr" is + for Source_Files use ("c1.adb"); + end C_Ext; +@end smallexample + +@noindent +When building project @file{c_ext.gpr}, the entire modified project space is +considered for recompilation, including the sources of @file{b.gpr} that are +impacted by the changes in @code{A1} and @code{C1}. + +@c --------------------------------------------- +@node Project File Reference +@section Project File Reference +@c --------------------------------------------- + +@noindent +This section describes the syntactic structure of project files, the various +constructs that can be used. Finally, it ends with a summary of all available +attributes. + +@menu +* Project Declaration:: +* Qualified Projects:: +* Declarations:: +* Packages:: +* Expressions:: +* External Values:: +* Typed String Declaration:: +* Variables:: +* Attributes:: +* Case Statements:: +@end menu + +@c --------------------------------------------- +@node Project Declaration +@subsection Project Declaration +@c --------------------------------------------- + +@noindent +Project files have an Ada-like syntax. The minimal project file is: + +@smallexample @c projectfile +@group +project Empty is +end Empty; +@end group +@end smallexample + +@noindent +The identifier @code{Empty} is the name of the project. +This project name must be present after the reserved +word @code{end} at the end of the project file, followed by a semi-colon. + +@b{Identifiers} (i.e.@: the user-defined names such as project or variable names) +have the same syntax as Ada identifiers: they must start with a letter, +and be followed by zero or more letters, digits or underscore characters; +it is also illegal to have two underscores next to each other. Identifiers +are always case-insensitive ("Name" is the same as "name"). + +@smallexample +simple_name ::= identifier +name ::= simple_name @{ . simple_name @} +@end smallexample + +@noindent +@b{Strings} are used for values of attributes or as indexes for these +attributes. They are in general case sensitive, except when noted +otherwise (in particular, strings representing file names will be case +insensitive on some systems, so that "file.adb" and "File.adb" both +represent the same file). + +@b{Reserved words} are the same as for standard Ada 95, and cannot +be used for identifiers. In particular, the following words are currently +used in project files, but others could be added later on. In bold are the +extra reserved words in project files: @code{all, at, case, end, for, is, +limited, null, others, package, renames, type, use, when, with, @b{extends}, +@b{external}, @b{project}}. + +@b{Comments} in project files have the same syntax as in Ada, two consecutive +hyphens through the end of the line. + +A project may be an @b{independent project}, entirely defined by a single +project file. Any source file in an independent project depends only +on the predefined library and other source files in the same project. +But a project may also depend on other projects, either by importing them +through @b{with clauses}, or by @b{extending} at most one other project. Both +types of dependency can be used in the same project. + +A path name denotes a project file. It can be absolute or relative. +An absolute path name includes a sequence of directories, in the syntax of +the host operating system, that identifies uniquely the project file in the +file system. A relative path name identifies the project file, relative +to the directory that contains the current project, or relative to a +directory listed in the environment variables ADA_PROJECT_PATH and +GPR_PROJECT_PATH. Path names are case sensitive if file names in the host +operating system are case sensitive. As a special case, the directory +separator can always be "/" even on Windows systems, so that project files +can be made portable across architectures. +The syntax of the environment variable ADA_PROJECT_PATH and +GPR_PROJECT_PATH is a list of directory names separated by colons on UNIX and +semicolons on Windows. + +A given project name can appear only once in a context clause. + +It is illegal for a project imported by a context clause to refer, directly +or indirectly, to the project in which this context clause appears (the +dependency graph cannot contain cycles), except when one of the with clause +in the cycle is a @b{limited with}. +@c ??? Need more details here + +@smallexample @c projectfile +with "other_project.gpr"; +project My_Project extends "extended.gpr" is +end My_Project; +@end smallexample + +@noindent +These dependencies form a @b{directed graph}, potentially cyclic when using +@b{limited with}. The subprogram reflecting the @b{extends} relations is a +tree. + +A project's @b{immediate sources} are the source files directly defined by +that project, either implicitly by residing in the project source directories, +or explicitly through any of the source-related attributes. +More generally, a project sources are the immediate sources of the project +together with the immediate sources (unless overridden) of any +project on which it depends directly or indirectly. + +A @b{project hierarchy} can be created, where projects are children of +other projects. The name of such a child project must be @code{Parent.Child}, +where @code{Parent} is the name of the parent project. In particular, this +makes all @code{with} clauses of the parent project automatically visible +in the child project. + +@smallexample +project ::= context_clause project_declaration + +context_clause ::= @{with_clause@} +with_clause ::= @i{with} path_name @{ , path_name @} ; +path_name ::= string_literal + +project_declaration ::= simple_project_declaration | project_extension +simple_project_declaration ::= + @i{project} @i{}name @i{is} + @{declarative_item@} + @i{end} simple_name; +@end smallexample + +@c --------------------------------------------- +@node Qualified Projects +@subsection Qualified Projects +@c --------------------------------------------- + +@noindent +Before the reserved @code{project}, there may be one or two @b{qualifiers}, that +is identifiers or reserved words, to qualify the project. +The current list of qualifiers is: + +@table @asis +@item @b{abstract}: qualifies a project with no sources. Such a + project must either have no declaration of attributes @code{Source_Dirs}, + @code{Source_Files}, @code{Languages} or @code{Source_List_File}, or one of + @code{Source_Dirs}, @code{Source_Files}, or @code{Languages} must be declared + as empty. If it extends another project, the project it extends must also be a + qualified abstract project. +@item @b{standard}: a standard project is a non library project with sources. + This is the default (implicit) qualifier. +@item @b{aggregate}: for future extension +@item @b{aggregate library}: for future extension +@item @b{library}: a library project must declare both attributes + @code{Library_Name} and @code{Library_Dir}. +@item @b{configuration}: a configuration project cannot be in a project tree. + It describes compilers and other tools to @code{gprbuild}. +@end table + + +@c --------------------------------------------- +@node Declarations +@subsection Declarations +@c --------------------------------------------- + +@noindent +Declarations introduce new entities that denote types, variables, attributes, +and packages. Some declarations can only appear immediately within a project +declaration. Others can appear within a project or within a package. + +@smallexample +declarative_item ::= simple_declarative_item + | typed_string_declaration + | package_declaration + +simple_declarative_item ::= variable_declaration + | typed_variable_declaration + | attribute_declaration + | case_construction + | empty_declaration + +empty_declaration ::= @i{null} ; +@end smallexample + +@noindent +An empty declaration is allowed anywhere a declaration is allowed. It has +no effect. + +@c --------------------------------------------- +@node Packages +@subsection Packages +@c --------------------------------------------- + +@noindent +A project file may contain @b{packages}, that group attributes (typically +all the attributes that are used by one of the GNAT tools). + +A package with a given name may only appear once in a project file. +The following packages are currently supported in project files +(See @pxref{Attributes} for the list of attributes that each can contain). + +@table @code +@item Binder + This package specifies characteristics useful when invoking the binder either + directly via the @command{gnat} driver or when using a builder such as + @command{gnatmake} or @command{gprbuild}. @xref{Main Subprograms}. +@item Builder + This package specifies the compilation options used when building an + executable or a library for a project. Most of the options should be + set in one of @code{Compiler}, @code{Binder} or @code{Linker} packages, + but there are some general options that should be defined in this + package. @xref{Main Subprograms}, and @pxref{Executable File Names} in + particular. +@item Check + This package specifies the options used when calling the checking tool + @command{gnatcheck} via the @command{gnat} driver. Its attribute + @b{Default_Switches} has the same semantics as for the package + @code{Builder}. The first string should always be @code{-rules} to specify + that all the other options belong to the @code{-rules} section of the + parameters to @command{gnatcheck}. +@item Compiler + This package specifies the compilation options used by the compiler for + each languages. @xref{Tools Options in Project Files}. +@item Cross_Reference + This package specifies the options used when calling the library tool + @command{gnatxref} via the @command{gnat} driver. Its attributes + @b{Default_Switches} and @b{Switches} have the same semantics as for the + package @code{Builder}. +@item Eliminate + This package specifies the options used when calling the tool + @command{gnatelim} via the @command{gnat} driver. Its attributes + @b{Default_Switches} and @b{Switches} have the same semantics as for the + package @code{Builder}. +@item Finder + This package specifies the options used when calling the search tool + @command{gnatfind} via the @command{gnat} driver. Its attributes + @b{Default_Switches} and @b{Switches} have the same semantics as for the + package @code{Builder}. +@item Gnatls + This package the options to use when invoking @command{gnatls} via the + @command{gnat} driver. +@item Gnatstub + This package specifies the options used when calling the tool + @command{gnatstub} via the @command{gnat} driver. Its attributes + @b{Default_Switches} and @b{Switches} have the same semantics as for the + package @code{Builder}. +@item IDE + This package specifies the options used when starting an integrated + development environment, for instance @command{GPS} or @command{Gnatbench}. + @xref{The Development Environments}. +@item Linker + This package specifies the options used by the linker. + @xref{Main Subprograms}. +@item Metrics + This package specifies the options used when calling the tool + @command{gnatmetric} via the @command{gnat} driver. Its attributes + @b{Default_Switches} and @b{Switches} have the same semantics as for the + package @code{Builder}. +@item Naming + This package specifies the naming conventions that apply + to the source files in a project. In particular, these conventions are + used to automatically find all source files in the source directories, + or given a file name to find out its language for proper processing. + @xref{Naming Schemes}. +@item Pretty_Printer + This package specifies the options used when calling the formatting tool + @command{gnatpp} via the @command{gnat} driver. Its attributes + @b{Default_Switches} and @b{Switches} have the same semantics as for the + package @code{Builder}. +@item Stack + This package specifies the options used when calling the tool + @command{gnatstack} via the @command{gnat} driver. Its attributes + @b{Default_Switches} and @b{Switches} have the same semantics as for the + package @code{Builder}. +@item Synchronize + This package specifies the options used when calling the tool + @command{gnatsync} via the @command{gnat} driver. + +@end table + +In its simplest form, a package may be empty: + +@smallexample @c projectfile +@group +project Simple is + package Builder is + end Builder; +end Simple; +@end group +@end smallexample + +@noindent +A package may contain @b{attribute declarations}, +@b{variable declarations} and @b{case constructions}, as will be +described below. + +When there is ambiguity between a project name and a package name, +the name always designates the project. To avoid possible confusion, it is +always a good idea to avoid naming a project with one of the +names allowed for packages or any name that starts with @code{gnat}. + +A package can also be defined by a @b{renaming declaration}. The new package +renames a package declared in a different project file, and has the same +attributes as the package it renames. The name of the renamed package +must be the same as the name of the renaming package. The project must +contain a package declaration with this name, and the project +must appear in the context clause of the current project, or be its parent +project. It is not possible to add or override attributes to the renaming +project. If you need to do so, you should use an @b{extending declaration} +(see below). + +Packages that are renamed in other project files often come from project files +that have no sources: they are just used as templates. Any modification in the +template will be reflected automatically in all the project files that rename +a package from the template. This is a very common way to share settings +between projects. + +Finally, a package can also be defined by an @b{extending declaration}. This is +similar to a @b{renaming declaration}, except that it is possible to add or +override attributes. + +@smallexample +package_declaration ::= package_spec | package_renaming | package_extension +package_spec ::= + @i{package} @i{}simple_name @i{is} + @{simple_declarative_item@} + @i{end} package_identifier ; +package_renaming ::== + @i{package} @i{}simple_name @i{renames} @i{}simple_name.package_identifier ; +package_extension ::== + @i{package} @i{}simple_name @i{extends} @i{}simple_name.package_identifier @i{is} + @{simple_declarative_item@} + @i{end} package_identifier ; +@end smallexample + +@c --------------------------------------------- +@node Expressions +@subsection Expressions +@c --------------------------------------------- + +@noindent +An expression is any value that can be assigned to an attribute or a +variable. It is either a literal value, or a construct requiring runtime +computation by the project manager. In a project file, the computed value of +an expression is either a string or a list of strings. + +A string value is one of: +@itemize @bullet +@item A literal string, for instance @code{"comm/my_proj.gpr"} +@item The name of a variable that evaluates to a string (@pxref{Variables}) +@item The name of an attribute that evaluates to a string (@pxref{Attributes}) +@item An external reference (@pxref{External Values}) +@item A concatenation of the above, as in @code{"prefix_" & Var}. + +@end itemize + +@noindent +A list of strings is one of the following: + +@itemize @bullet +@item A parenthesized comma-separated list of zero or more string expressions, for + instance @code{(File_Name, "gnat.adc", File_Name & ".orig")} or @code{()}. +@item The name of a variable that evaluates to a list of strings +@item The name of an attribute that evaluates to a list of strings +@item A concatenation of a list of strings and a string (as defined above), for + instance @code{("A", "B") & "C"} +@item A concatenation of two lists of strings + +@end itemize + +@noindent +The following is the grammar for expressions + +@smallexample +string_literal ::= "@{string_element@}" -- Same as Ada +string_expression ::= string_literal + | @i{variable_}name + | external_value + | attribute_reference + | ( string_expression @{ & string_expression @} ) +string_list ::= ( string_expression @{ , string_expression @} ) + | @i{string_variable}_name + | @i{string_}attribute_reference +term ::= string_expression | string_list +expression ::= term @{ & term @} -- Concatenation +@end smallexample + +@noindent +Concatenation involves strings and list of strings. As soon as a list of +strings is involved, the result of the concatenation is a list of strings. The +following Ada declarations show the existing operators: + +@smallexample @c ada + function "&" (X : String; Y : String) return String; + function "&" (X : String_List; Y : String) return String_List; + function "&" (X : String_List; Y : String_List) return String_List; +@end smallexample + +@noindent +Here are some specific examples: + +@smallexample @c projectfile +@group + List := () & File_Name; -- One string in this list + List2 := List & (File_Name & ".orig"); -- Two strings + Big_List := List & Lists2; -- Three strings + Illegal := "gnat.adc" & List2; -- Illegal, must start with list +@end group +@end smallexample + +@c --------------------------------------------- +@node External Values +@subsection External Values +@c --------------------------------------------- + +@noindent +An external value is an expression whose value is obtained from the command +that invoked the processing of the current project file (typically a +gnatmake or gprbuild command). + +There are two kinds of external values, one that returns a single string, and +one that returns a string list. + +The syntax of a single string external value is: + +@smallexample +external_value ::= @i{external} ( string_literal [, string_literal] ) +@end smallexample + +@noindent +The first string_literal is the string to be used on the command line or +in the environment to specify the external value. The second string_literal, +if present, is the default to use if there is no specification for this +external value either on the command line or in the environment. + +Typically, the external value will either exist in the +^environment variables^logical name^ +or be specified on the command line through the +@option{^-X^/EXTERNAL_REFERENCE=^@emph{vbl}=@emph{value}} switch. If both +are specified, then the command line value is used, so that a user can more +easily override the value. + +The function @code{external} always returns a string. It is an error if the +value was not found in the environment and no default was specified in the +call to @code{external}. + +An external reference may be part of a string expression or of a string +list expression, and can therefore appear in a variable declaration or +an attribute declaration. + +Most of the time, this construct is used to initialize typed variables, which +are then used in @b{case} statements to control the value assigned to +attributes in various scenarios. Thus such variables are often called +@b{scenario variables}. + +The syntax for a string list external value is: + +@smallexample +external_value ::= @i{external_as_list} ( string_literal , string_literal ) +@end smallexample + +@noindent +The first string_literal is the string to be used on the command line or +in the environment to specify the external value. The second string_literal is +the separator between each component of the string list. + +If the external value does not exist in the environment or on the command line, +the result is an empty list. This is also the case, if the separator is an +empty string or if the external value is only one separator. + +Any separator at the beginning or at the end of the external value is +discarded. Then, if there is no separator in the external value, the result is +a string list with only one string. Otherwise, any string between the beginning +and the first separator, between two consecutive separators and between the +last separator and the end are components of the string list. + +@smallexample + @i{external_as_list} ("SWITCHES", ",") +@end smallexample + +@noindent +If the external value is "-O2,-g", the result is ("-O2", "-g"). + +If the external value is ",-O2,-g,", the result is also ("-O2", "-g"). + +if the external value is "-gnav", the result is ("-gnatv"). + +If the external value is ",,", the result is (""). + +If the external value is ",", the result is (), the empty string list. + +@c --------------------------------------------- +@node Typed String Declaration +@subsection Typed String Declaration +@c --------------------------------------------- + +@noindent +A @b{type declaration} introduces a discrete set of string literals. +If a string variable is declared to have this type, its value +is restricted to the given set of literals. These are the only named +types in project files. A string type may only be declared at the project +level, not inside a package. + +@smallexample +typed_string_declaration ::= + @i{type} @i{}_simple_name @i{is} ( string_literal @{, string_literal@} ); +@end smallexample + +@noindent +The string literals in the list are case sensitive and must all be different. +They may include any graphic characters allowed in Ada, including spaces. +Here is an example of a string type declaration: + +@smallexample @c projectfile + type OS is ("NT", "nt", "Unix", "GNU/Linux", "other OS"); +@end smallexample + +@noindent +Variables of a string type are called @b{typed variables}; all other +variables are called @b{untyped variables}. Typed variables are +particularly useful in @code{case} constructions, to support conditional +attribute declarations. (@pxref{Case Statements}). + +A string type may be referenced by its name if it has been declared in the same +project file, or by an expanded name whose prefix is the name of the project +in which it is declared. + +@c --------------------------------------------- +@node Variables +@subsection Variables +@c --------------------------------------------- + +@noindent +@b{Variables} store values (strings or list of strings) and can appear +as part of an expression. The declaration of a variable creates the +variable and assigns the value of the expression to it. The name of the +variable is available immediately after the assignment symbol, if you +need to reuse its old value to compute the new value. Before the completion +of its first declaration, the value of a variable defaults to the empty +string (""). + +A @b{typed} variable can be used as part of a @b{case} expression to +compute the value, but it can only be declared once in the project file, +so that all case statements see the same value for the variable. This +provides more consistency and makes the project easier to understand. +The syntax for its declaration is identical to the Ada syntax for an +object declaration. In effect, a typed variable acts as a constant. + +An @b{untyped} variable can be declared and overridden multiple times +within the same project. It is declared implicitly through an Ada +assignment. The first declaration establishes the kind of the variable +(string or list of strings) and successive declarations must respect +the initial kind. Assignments are executed in the order in which they +appear, so the new value replaces the old one and any subsequent reference +to the variable uses the new value. + +A variable may be declared at the project file level, or within a package. + +@smallexample +typed_variable_declaration ::= + @i{}simple_name : @i{}name := string_expression; +variable_declaration ::= @i{}simple_name := expression; +@end smallexample + +@noindent +Here are some examples of variable declarations: + +@smallexample @c projectfile +@group + This_OS : OS := external ("OS"); -- a typed variable declaration + That_OS := "GNU/Linux"; -- an untyped variable declaration + + Name := "readme.txt"; + Save_Name := Name & ".saved"; + + Empty_List := (); + List_With_One_Element := ("-gnaty"); + List_With_Two_Elements := List_With_One_Element & "-gnatg"; + Long_List := ("main.ada", "pack1_.ada", "pack1.ada", "pack2_.ada"); +@end group +@end smallexample + +@noindent +A @b{variable reference} may take several forms: + +@itemize @bullet +@item The simple variable name, for a variable in the current package (if any) + or in the current project +@item An expanded name, whose prefix is a context name. + +@end itemize + +@noindent +A @b{context} may be one of the following: + +@itemize @bullet +@item The name of an existing package in the current project +@item The name of an imported project of the current project +@item The name of an ancestor project (i.e., a project extended by the current + project, either directly or indirectly) +@item An expanded name whose prefix is an imported/parent project name, and + whose selector is a package name in that project. +@end itemize + + +@c --------------------------------------------- +@node Attributes +@subsection Attributes +@c --------------------------------------------- + +@noindent +A project (and its packages) may have @b{attributes} that define +the project's properties. Some attributes have values that are strings; +others have values that are string lists. + +@smallexample +attribute_declaration ::= + simple_attribute_declaration | indexed_attribute_declaration +simple_attribute_declaration ::= @i{for} attribute_designator @i{use} expression ; +indexed_attribute_declaration ::= + @i{for} @i{}simple_name ( string_literal) @i{use} expression ; +attribute_designator ::= + @i{}simple_name + | @i{}simple_name ( string_literal ) +@end smallexample + +@noindent +There are two categories of attributes: @b{simple attributes} +and @b{indexed attributes}. +Each simple attribute has a default value: the empty string (for string +attributes) and the empty list (for string list attributes). +An attribute declaration defines a new value for an attribute, and overrides +the previous value. The syntax of a simple attribute declaration is similar to +that of an attribute definition clause in Ada. + +Some attributes are indexed. These attributes are mappings whose +domain is a set of strings. They are declared one association +at a time, by specifying a point in the domain and the corresponding image +of the attribute. +Like untyped variables and simple attributes, indexed attributes +may be declared several times. Each declaration supplies a new value for the +attribute, and replaces the previous setting. + +Here are some examples of attribute declarations: + +@smallexample @c projectfile + -- simple attributes + for Object_Dir use "objects"; + for Source_Dirs use ("units", "test/drivers"); + + -- indexed attributes + for Body ("main") use "Main.ada"; + for Switches ("main.ada") use ("-v", "-gnatv"); + for Switches ("main.ada") use Builder'Switches ("main.ada") & "-g"; + + -- indexed attributes copy (from package Builder in project Default) + -- The package name must always be specified, even if it is the current + -- package. + for Default_Switches use Default.Builder'Default_Switches; +@end smallexample + +@noindent +Attributes references may be appear anywhere in expressions, and are used +to retrieve the value previously assigned to the attribute. If an attribute +has not been set in a given package or project, its value defaults to the +empty string or the empty list. + +@smallexample +attribute_reference ::= attribute_prefix ' @i{_}simple_name [ (string_literal) ] +attribute_prefix ::= @i{project} + | @i{}simple_name + | package_identifier + | @i{}simple_name . package_identifier +@end smallexample + +@noindent +Examples are: + +@smallexample @c projectfile + project'Object_Dir + Naming'Dot_Replacement + Imported_Project'Source_Dirs + Imported_Project.Naming'Casing + Builder'Default_Switches ("Ada") +@end smallexample + +@noindent +The prefix of an attribute may be: + +@itemize @bullet +@item @code{project} for an attribute of the current project +@item The name of an existing package of the current project +@item The name of an imported project +@item The name of a parent project that is extended by the current project +@item An expanded name whose prefix is imported/parent project name, + and whose selector is a package name + +@end itemize + +@noindent +Legal attribute names are listed below, including the package in +which they must be declared. These names are case-insensitive. The +semantics for the attributes is explained in great details in other sections. + +The column @emph{index} indicates whether the attribute is an indexed attribute, +and when it is whether its index is case sensitive (sensitive) or not (insensitive), or if case sensitivity depends is the same as file names sensitivity on the +system (file). The text is between brackets ([]) if the index is optional. + +@multitable @columnfractions .3 .1 .2 .4 +@headitem Attribute Name @tab Value @tab Package @tab Index +@headitem General attributes @tab @tab @tab @pxref{Building With Projects} +@item Name @tab string @tab - @tab (Read-only, name of project) +@item Project_Dir @tab string @tab - @tab (Read-only, directory of project) +@item Source_Files @tab list @tab - @tab - +@item Source_Dirs @tab list @tab - @tab - +@item Source_List_File @tab string @tab - @tab - +@item Locally_Removed_Files @tab list @tab - @tab - +@item Excluded_Source_Files @tab list @tab - @tab - +@item Object_Dir @tab string @tab - @tab - +@item Exec_Dir @tab string @tab - @tab - +@item Excluded_Source_Dirs @tab list @tab - @tab - +@item Excluded_Source_Files @tab list @tab - @tab - +@item Excluded_Source_List_File @tab list @tab - @tab - +@item Inherit_Source_Path @tab list @tab - @tab insensitive +@item Languages @tab list @tab - @tab - +@item Main @tab list @tab - @tab - +@item Main_Language @tab string @tab - @tab - +@item Externally_Built @tab string @tab - @tab - +@item Roots @tab list @tab - @tab file +@headitem + Library-related attributes @tab @tab @tab @pxref{Library Projects} +@item Library_Dir @tab string @tab - @tab - +@item Library_Name @tab string @tab - @tab - +@item Library_Kind @tab string @tab - @tab - +@item Library_Version @tab string @tab - @tab - +@item Library_Interface @tab string @tab - @tab - +@item Library_Auto_Init @tab string @tab - @tab - +@item Library_Options @tab list @tab - @tab - +@item Leading_Library_Options @tab list @tab - @tab - +@item Library_Src_Dir @tab string @tab - @tab - +@item Library_ALI_Dir @tab string @tab - @tab - +@item Library_GCC @tab string @tab - @tab - +@item Library_Symbol_File @tab string @tab - @tab - +@item Library_Symbol_Policy @tab string @tab - @tab - +@item Library_Reference_Symbol_File @tab string @tab - @tab - +@item Interfaces @tab list @tab - @tab - +@headitem + Naming @tab @tab @tab @pxref{Naming Schemes} +@item Spec_Suffix @tab string @tab Naming @tab insensitive (language) +@item Body_Suffix @tab string @tab Naming @tab insensitive (language) +@item Separate_Suffix @tab string @tab Naming @tab - +@item Casing @tab string @tab Naming @tab - +@item Dot_Replacement @tab string @tab Naming @tab - +@item Spec @tab string @tab Naming @tab insensitive (Ada unit) +@item Body @tab string @tab Naming @tab insensitive (Ada unit) +@item Specification_Exceptions @tab list @tab Naming @tab insensitive (language) +@item Implementation_Exceptions @tab list @tab Naming @tab insensitive (language) +@headitem + Building @tab @tab @tab @pxref{Switches and Project Files} +@item Default_Switches @tab list @tab Builder, Compiler, Binder, Linker, Cross_Reference, Finder, Pretty_Printer, gnatstub, Check, Synchronize, Eliminate, Metrics, IDE @tab insensitive (language name) +@item Switches @tab list @tab Builder, Compiler, Binder, Linker, Cross_Reference, Finder, gnatls, Pretty_Printer, gnatstub, Check, Synchronize, Eliminate, Metrics, Stack @tab [file] (file name) +@item Local_Configuration_Pragmas @tab string @tab Compiler @tab - +@item Local_Config_File @tab string @tab insensitive @tab - +@item Global_Configuration_Pragmas @tab list @tab Builder @tab - +@item Global_Compilation_Switches @tab list @tab Builder @tab language +@item Executable @tab string @tab Builder @tab [file] +@item Executable_Suffix @tab string @tab Builder @tab - +@item Global_Config_File @tab string @tab Builder @tab insensitive (language) +@headitem + IDE (used and created by GPS) @tab @tab @tab +@item Remote_Host @tab string @tab IDE @tab - +@item Program_Host @tab string @tab IDE @tab - +@item Communication_Protocol @tab string @tab IDE @tab - +@item Compiler_Command @tab string @tab IDE @tab insensitive (language) +@item Debugger_Command @tab string @tab IDE @tab - +@item Gnatlist @tab string @tab IDE @tab - +@item VCS_Kind @tab string @tab IDE @tab - +@item VCS_File_Check @tab string @tab IDE @tab - +@item VCS_Log_Check @tab string @tab IDE @tab - +@item Documentation_Dir @tab string @tab IDE @tab - +@headitem + Configuration files @tab @tab @tab See gprbuild manual +@item Default_Language @tab string @tab - @tab - +@item Run_Path_Option @tab list @tab - @tab - +@item Run_Path_Origin @tab string @tab - @tab - +@item Separate_Run_Path_Options @tab string @tab - @tab - +@item Toolchain_Version @tab string @tab - @tab insensitive +@item Toolchain_Description @tab string @tab - @tab insensitive +@item Object_Generated @tab string @tab - @tab insensitive +@item Objects_Linked @tab string @tab - @tab insensitive +@item Target @tab string @tab - @tab - +@item Library_Builder @tab string @tab - @tab - +@item Library_Support @tab string @tab - @tab - +@item Archive_Builder @tab list @tab - @tab - +@item Archive_Builder_Append_Option @tab list @tab - @tab - +@item Archive_Indexer @tab list @tab - @tab - +@item Archive_Suffix @tab string @tab - @tab - +@item Library_Partial_Linker @tab list @tab - @tab - +@item Shared_Library_Prefix @tab string @tab - @tab - +@item Shared_Library_Suffix @tab string @tab - @tab - +@item Symbolic_Link_Supported @tab string @tab - @tab - +@item Library_Major_Minor_Id_Supported @tab string @tab - @tab - +@item Library_Auto_Init_Supported @tab string @tab - @tab - +@item Shared_Library_Minimum_Switches @tab list @tab - @tab - +@item Library_Version_Switches @tab list @tab - @tab - +@item Library_Install_Name_Option @tab string @tab - @tab - +@item Runtime_Library_Dir @tab string @tab - @tab insensitive +@item Runtime_Source_Dir @tab string @tab - @tab insensitive +@item Driver @tab string @tab Compiler,Binder,Linker @tab insensitive (language) +@item Required_Switches @tab list @tab Compiler,Binder,Linker @tab insensitive (language) +@item Leading_Required_Switches @tab list @tab Compiler @tab insensitive (language) +@item Trailing_Required_Switches @tab list @tab Compiler @tab insensitive (language) +@item Pic_Options @tab list @tab Compiler @tab insensitive (language) +@item Path_Syntax @tab string @tab Compiler @tab insensitive (language) +@item Object_File_Suffix @tab string @tab Compiler @tab insensitive (language) +@item Object_File_Switches @tab list @tab Compiler @tab insensitive (language) +@item Multi_Unit_Switches @tab list @tab Compiler @tab insensitive (language) +@item Multi_Unit_Object_Separator @tab string @tab Compiler @tab insensitive (language) +@item Mapping_File_Switches @tab list @tab Compiler @tab insensitive (language) +@item Mapping_Spec_Suffix @tab string @tab Compiler @tab insensitive (language) +@item Mapping_body_Suffix @tab string @tab Compiler @tab insensitive (language) +@item Config_File_Switches @tab list @tab Compiler @tab insensitive (language) +@item Config_Body_File_Name @tab string @tab Compiler @tab insensitive (language) +@item Config_Body_File_Name_Index @tab string @tab Compiler @tab insensitive (language) +@item Config_Body_File_Name_Pattern @tab string @tab Compiler @tab insensitive (language) +@item Config_Spec_File_Name @tab string @tab Compiler @tab insensitive (language) +@item Config_Spec_File_Name_Index @tab string @tab Compiler @tab insensitive (language) +@item Config_Spec_File_Name_Pattern @tab string @tab Compiler @tab insensitive (language) +@item Config_File_Unique @tab string @tab Compiler @tab insensitive (language) +@item Dependency_Switches @tab list @tab Compiler @tab insensitive (language) +@item Dependency_Driver @tab list @tab Compiler @tab insensitive (language) +@item Include_Switches @tab list @tab Compiler @tab insensitive (language) +@item Include_Path @tab string @tab Compiler @tab insensitive (language) +@item Include_Path_File @tab string @tab Compiler @tab insensitive (language) +@item Prefix @tab string @tab Binder @tab insensitive (language) +@item Objects_Path @tab string @tab Binder @tab insensitive (language) +@item Objects_Path_File @tab string @tab Binder @tab insensitive (language) +@item Linker_Options @tab list @tab Linker @tab - +@item Leading_Switches @tab list @tab Linker @tab - +@item Map_File_Options @tab string @tab Linker @tab - +@item Executable_Switches @tab list @tab Linker @tab - +@item Lib_Dir_Switch @tab string @tab Linker @tab - +@item Lib_Name_Switch @tab string @tab Linker @tab - +@item Max_Command_Line_Length @tab string @tab Linker @tab - +@item Response_File_Format @tab string @tab Linker @tab - +@item Response_File_Switches @tab list @tab Linker @tab - +@end multitable + +@c --------------------------------------------- +@node Case Statements +@subsection Case Statements +@c --------------------------------------------- + +@noindent +A @b{case} statement is used in a project file to effect conditional +behavior. Through this statement, you can set the value of attributes +and variables depending on the value previously assigned to a typed +variable. + +All choices in a choice list must be distinct. Unlike Ada, the choice +lists of all alternatives do not need to include all values of the type. +An @code{others} choice must appear last in the list of alternatives. + +The syntax of a @code{case} construction is based on the Ada case statement +(although the @code{null} statement for empty alternatives is optional). + +The case expression must be a typed string variable, whose value is often +given by an external reference (@pxref{External Values}). + +Each alternative starts with the reserved word @code{when}, either a list of +literal strings separated by the @code{"|"} character or the reserved word +@code{others}, and the @code{"=>"} token. +Each literal string must belong to the string type that is the type of the +case variable. +After each @code{=>}, there are zero or more statements. The only +statements allowed in a case construction are other case statements, +attribute declarations and variable declarations. String type declarations and +package declarations are not allowed. Variable declarations are restricted to +variables that have already been declared before the case construction. + +@smallexample +case_statement ::= + @i{case} @i{}name @i{is} @{case_item@} @i{end case} ; + +case_item ::= + @i{when} discrete_choice_list => + @{case_statement + | attribute_declaration + | variable_declaration + | empty_declaration@} + +discrete_choice_list ::= string_literal @{| string_literal@} | @i{others} +@end smallexample + +@noindent +Here is a typical example: + +@smallexample @c projectfile +@group +project MyProj is + type OS_Type is ("GNU/Linux", "Unix", "NT", "VMS"); + OS : OS_Type := external ("OS", "GNU/Linux"); + + package Compiler is + case OS is + when "GNU/Linux" | "Unix" => + for Switches ("Ada") use ("-gnath"); + when "NT" => + for Switches ("Ada") use ("-gnatP"); + when others => + null; + end case; + end Compiler; +end MyProj; +@end group +@end smallexample + +@c --------------------------------------------- +@node Tools Supporting Project Files +@chapter Tools Supporting Project Files +@c --------------------------------------------- + +@noindent + + +@menu +* gnatmake and Project Files:: +* The GNAT Driver and Project Files:: +* The Development Environments:: +* Cleaning up with GPRclean:: +@end menu + +@c --------------------------------------------- +@node gnatmake and Project Files +@section gnatmake and Project Files +@c --------------------------------------------- + +@noindent +This section covers several topics related to @command{gnatmake} and +project files: defining ^switches^switches^ for @command{gnatmake} +and for the tools that it invokes; specifying configuration pragmas; +the use of the @code{Main} attribute; building and rebuilding library project +files. + +@menu +* Switches Related to Project Files:: +* Switches and Project Files:: +* Specifying Configuration Pragmas:: +* Project Files and Main Subprograms:: +* Library Project Files:: +@end menu + +@c --------------------------------------------- +@node Switches Related to Project Files +@subsection Switches Related to Project Files +@c --------------------------------------------- + +@noindent +The following switches are used by GNAT tools that support project files: + +@table @option + +@item ^-P^/PROJECT_FILE=^@var{project} +@cindex @option{^-P^/PROJECT_FILE^} (any project-aware tool) +Indicates the name of a project file. This project file will be parsed with +the verbosity indicated by @option{^-vP^MESSAGE_PROJECT_FILES=^@emph{x}}, +if any, and using the external references indicated +by @option{^-X^/EXTERNAL_REFERENCE^} switches, if any. +@ifclear vms +There may zero, one or more spaces between @option{-P} and @var{project}. +@end ifclear + +There must be only one @option{^-P^/PROJECT_FILE^} switch on the command line. + +Since the Project Manager parses the project file only after all the switches +on the command line are checked, the order of the switches +@option{^-P^/PROJECT_FILE^}, +@option{^-vP^/MESSAGES_PROJECT_FILE=^@emph{x}} +or @option{^-X^/EXTERNAL_REFERENCE^} is not significant. + +@item ^-X^/EXTERNAL_REFERENCE=^@var{name=value} +@cindex @option{^-X^/EXTERNAL_REFERENCE^} (any project-aware tool) +Indicates that external variable @var{name} has the value @var{value}. +The Project Manager will use this value for occurrences of +@code{external(name)} when parsing the project file. + +@ifclear vms +If @var{name} or @var{value} includes a space, then @var{name=value} should be +put between quotes. +@smallexample + -XOS=NT + -X"user=John Doe" +@end smallexample +@end ifclear + +Several @option{^-X^/EXTERNAL_REFERENCE^} switches can be used simultaneously. +If several @option{^-X^/EXTERNAL_REFERENCE^} switches specify the same +@var{name}, only the last one is used. + +An external variable specified with a @option{^-X^/EXTERNAL_REFERENCE^} switch +takes precedence over the value of the same name in the environment. + +@item ^-vP^/MESSAGES_PROJECT_FILE=^@emph{x} +@cindex @option{^-vP^/MESSAGES_PROJECT_FILE^} (any project-aware tool) +Indicates the verbosity of the parsing of GNAT project files. + +@ifclear vms +@option{-vP0} means Default; +@option{-vP1} means Medium; +@option{-vP2} means High. +@end ifclear + +@ifset vms +There are three possible options for this qualifier: DEFAULT, MEDIUM and +HIGH. +@end ifset + +The default is ^Default^DEFAULT^: no output for syntactically correct +project files. +If several @option{^-vP^/MESSAGES_PROJECT_FILE=^@emph{x}} switches are present, +only the last one is used. + +@item ^-aP^/ADD_PROJECT_SEARCH_DIR=^ +@cindex @option{^-aP^/ADD_PROJECT_SEARCH_DIR=^} (any project-aware tool) +Add directory at the beginning of the project search path, in order, +after the current working directory. + +@ifclear vms +@item -eL +@cindex @option{-eL} (any project-aware tool) +Follow all symbolic links when processing project files. +@end ifclear + +@item ^--subdirs^/SUBDIRS^= +@cindex @option{^--subdirs^/SUBDIRS^=} (gnatmake and gnatclean) +This switch is recognized by gnatmake and gnatclean. It indicate that the real +directories (except the source directories) are the subdirectories +of the directories specified in the project files. This applies in particular +to object directories, library directories and exec directories. If the +subdirectories do not exist, they are created automatically. + +@end table + +@c --------------------------------------------- +@node Switches and Project Files +@subsection Switches and Project Files +@c --------------------------------------------- + +@noindent +@ifset vms +It is not currently possible to specify VMS style qualifiers in the project +files; only Unix style ^switches^switches^ may be specified. +@end ifset + +For each of the packages @code{Builder}, @code{Compiler}, @code{Binder}, and +@code{Linker}, you can specify a @code{^Default_Switches^Default_Switches^} +attribute, a @code{Switches} attribute, or both; +as their names imply, these ^switch^switch^-related +attributes affect the ^switches^switches^ that are used for each of these GNAT +components when +@command{gnatmake} is invoked. As will be explained below, these +component-specific ^switches^switches^ precede +the ^switches^switches^ provided on the @command{gnatmake} command line. + +The @code{^Default_Switches^Default_Switches^} attribute is an attribute +indexed by language name (case insensitive) whose value is a string list. +For example: + +@smallexample @c projectfile +@group +package Compiler is + for ^Default_Switches^Default_Switches^ ("Ada") + use ("^-gnaty^-gnaty^", + "^-v^-v^"); +end Compiler; +@end group +@end smallexample + +@noindent +The @code{Switches} attribute is indexed on a file name (which may or may +not be case sensitive, depending +on the operating system) whose value is a string list. For example: + +@smallexample @c projectfile +@group +package Builder is + for Switches ("main1.adb") + use ("^-O2^-O2^"); + for Switches ("main2.adb") + use ("^-g^-g^"); +end Builder; +@end group +@end smallexample + +@noindent +For the @code{Builder} package, the file names must designate source files +for main subprograms. For the @code{Binder} and @code{Linker} packages, the +file names must designate @file{ALI} or source files for main subprograms. +In each case just the file name without an explicit extension is acceptable. + +For each tool used in a program build (@command{gnatmake}, the compiler, the +binder, and the linker), the corresponding package @dfn{contributes} a set of +^switches^switches^ for each file on which the tool is invoked, based on the +^switch^switch^-related attributes defined in the package. +In particular, the ^switches^switches^ +that each of these packages contributes for a given file @var{f} comprise: + +@itemize @bullet +@item the value of attribute @code{Switches (@var{f})}, + if it is specified in the package for the given file, +@item otherwise, the value of @code{^Default_Switches^Default_Switches^ ("Ada")}, + if it is specified in the package. + +@end itemize + +@noindent +If neither of these attributes is defined in the package, then the package does +not contribute any ^switches^switches^ for the given file. + +When @command{gnatmake} is invoked on a file, the ^switches^switches^ comprise +two sets, in the following order: those contributed for the file +by the @code{Builder} package; +and the switches passed on the command line. + +When @command{gnatmake} invokes a tool (compiler, binder, linker) on a file, +the ^switches^switches^ passed to the tool comprise three sets, +in the following order: + +@enumerate +@item +the applicable ^switches^switches^ contributed for the file +by the @code{Builder} package in the project file supplied on the command line; + +@item +those contributed for the file by the package (in the relevant project file -- +see below) corresponding to the tool; and + +@item +the applicable switches passed on the command line. +@end enumerate + +The term @emph{applicable ^switches^switches^} reflects the fact that +@command{gnatmake} ^switches^switches^ may or may not be passed to individual +tools, depending on the individual ^switch^switch^. + +@command{gnatmake} may invoke the compiler on source files from different +projects. The Project Manager will use the appropriate project file to +determine the @code{Compiler} package for each source file being compiled. +Likewise for the @code{Binder} and @code{Linker} packages. + +As an example, consider the following package in a project file: + +@smallexample @c projectfile +@group +project Proj1 is + package Compiler is + for ^Default_Switches^Default_Switches^ ("Ada") + use ("^-g^-g^"); + for Switches ("a.adb") + use ("^-O1^-O1^"); + for Switches ("b.adb") + use ("^-O2^-O2^", + "^-gnaty^-gnaty^"); + end Compiler; +end Proj1; +@end group +@end smallexample + +@noindent +If @command{gnatmake} is invoked with this project file, and it needs to +compile, say, the files @file{a.adb}, @file{b.adb}, and @file{c.adb}, then +@file{a.adb} will be compiled with the ^switch^switch^ +@option{^-O1^-O1^}, +@file{b.adb} with ^switches^switches^ +@option{^-O2^-O2^} +and @option{^-gnaty^-gnaty^}, +and @file{c.adb} with @option{^-g^-g^}. + +The following example illustrates the ordering of the ^switches^switches^ +contributed by different packages: + +@smallexample @c projectfile +@group +project Proj2 is + package Builder is + for Switches ("main.adb") + use ("^-g^-g^", + "^-O1^-)1^", + "^-f^-f^"); + end Builder; +@end group + +@group + package Compiler is + for Switches ("main.adb") + use ("^-O2^-O2^"); + end Compiler; +end Proj2; +@end group +@end smallexample + +@noindent +If you issue the command: + +@smallexample + gnatmake ^-Pproj2^/PROJECT_FILE=PROJ2^ -O0 main +@end smallexample + +@noindent +then the compiler will be invoked on @file{main.adb} with the following +sequence of ^switches^switches^ + +@smallexample + ^-g -O1 -O2 -O0^-g -O1 -O2 -O0^ +@end smallexample + +@noindent +with the last @option{^-O^-O^} +^switch^switch^ having precedence over the earlier ones; +several other ^switches^switches^ +(such as @option{^-c^-c^}) are added implicitly. + +The ^switches^switches^ +@option{^-g^-g^} +and @option{^-O1^-O1^} are contributed by package +@code{Builder}, @option{^-O2^-O2^} is contributed +by the package @code{Compiler} +and @option{^-O0^-O0^} comes from the command line. + +The @option{^-g^-g^} +^switch^switch^ will also be passed in the invocation of +@command{Gnatlink.} + +A final example illustrates switch contributions from packages in different +project files: + +@smallexample @c projectfile +@group +project Proj3 is + for Source_Files use ("pack.ads", "pack.adb"); + package Compiler is + for ^Default_Switches^Default_Switches^ ("Ada") + use ("^-gnata^-gnata^"); + end Compiler; +end Proj3; +@end group + +@group +with "Proj3"; +project Proj4 is + for Source_Files use ("foo_main.adb", "bar_main.adb"); + package Builder is + for Switches ("foo_main.adb") + use ("^-s^-s^", + "^-g^-g^"); + end Builder; +end Proj4; +@end group + +@group +-- Ada source file: +with Pack; +procedure Foo_Main is + @dots{} +end Foo_Main; +@end group +@end smallexample + +@noindent +If the command is +@smallexample +gnatmake ^-PProj4^/PROJECT_FILE=PROJ4^ foo_main.adb -cargs -gnato +@end smallexample + +@noindent +then the ^switches^switches^ passed to the compiler for @file{foo_main.adb} are +@option{^-g^-g^} (contributed by the package @code{Proj4.Builder}) and +@option{^-gnato^-gnato^} (passed on the command line). +When the imported package @code{Pack} is compiled, the ^switches^switches^ used +are @option{^-g^-g^} from @code{Proj4.Builder}, +@option{^-gnata^-gnata^} (contributed from package @code{Proj3.Compiler}, +and @option{^-gnato^-gnato^} from the command line. + +When using @command{gnatmake} with project files, some ^switches^switches^ or +arguments may be expressed as relative paths. As the working directory where +compilation occurs may change, these relative paths are converted to absolute +paths. For the ^switches^switches^ found in a project file, the relative paths +are relative to the project file directory, for the switches on the command +line, they are relative to the directory where @command{gnatmake} is invoked. +The ^switches^switches^ for which this occurs are: +^-I^-I^, +^-A^-A^, +^-L^-L^, +^-aO^-aO^, +^-aL^-aL^, +^-aI^-aI^, as well as all arguments that are not switches (arguments to +^switch^switch^ +^-o^-o^, object files specified in package @code{Linker} or after +-largs on the command line). The exception to this rule is the ^switch^switch^ +^--RTS=^--RTS=^ for which a relative path argument is never converted. + +@c --------------------------------------------- +@node Specifying Configuration Pragmas +@subsection Specifying Configuration Pragmas +@c --------------------------------------------- + +@noindent +When using @command{gnatmake} with project files, if there exists a file +@file{gnat.adc} that contains configuration pragmas, this file will be +ignored. + +Configuration pragmas can be defined by means of the following attributes in +project files: @code{Global_Configuration_Pragmas} in package @code{Builder} +and @code{Local_Configuration_Pragmas} in package @code{Compiler}. + +Both these attributes are single string attributes. Their values is the path +name of a file containing configuration pragmas. If a path name is relative, +then it is relative to the project directory of the project file where the +attribute is defined. + +When compiling a source, the configuration pragmas used are, in order, +those listed in the file designated by attribute +@code{Global_Configuration_Pragmas} in package @code{Builder} of the main +project file, if it is specified, and those listed in the file designated by +attribute @code{Local_Configuration_Pragmas} in package @code{Compiler} of +the project file of the source, if it exists. + +@c --------------------------------------------- +@node Project Files and Main Subprograms +@subsection Project Files and Main Subprograms +@c --------------------------------------------- + +@noindent +When using a project file, you can invoke @command{gnatmake} +with one or several main subprograms, by specifying their source files on the +command line. + +@smallexample + gnatmake ^-P^/PROJECT_FILE=^prj main1 main2 main3 +@end smallexample + +@noindent +Each of these needs to be a source file of the same project, except +when the switch ^-u^/UNIQUE^ is used. + +When ^-u^/UNIQUE^ is not used, all the mains need to be sources of the +same project, one of the project in the tree rooted at the project specified +on the command line. The package @code{Builder} of this common project, the +"main project" is the one that is considered by @command{gnatmake}. + +When ^-u^/UNIQUE^ is used, the specified source files may be in projects +imported directly or indirectly by the project specified on the command line. +Note that if such a source file is not part of the project specified on the +command line, the ^switches^switches^ found in package @code{Builder} of the +project specified on the command line, if any, that are transmitted +to the compiler will still be used, not those found in the project file of +the source file. + +When using a project file, you can also invoke @command{gnatmake} without +explicitly specifying any main, and the effect depends on whether you have +defined the @code{Main} attribute. This attribute has a string list value, +where each element in the list is the name of a source file (the file +extension is optional) that contains a unit that can be a main subprogram. + +If the @code{Main} attribute is defined in a project file as a non-empty +string list and the switch @option{^-u^/UNIQUE^} is not used on the command +line, then invoking @command{gnatmake} with this project file but without any +main on the command line is equivalent to invoking @command{gnatmake} with all +the file names in the @code{Main} attribute on the command line. + +Example: +@smallexample @c projectfile +@group + project Prj is + for Main use ("main1", "main2", "main3"); + end Prj; +@end group +@end smallexample + +@noindent +With this project file, @code{"gnatmake ^-Pprj^/PROJECT_FILE=PRJ^"} +is equivalent to +@code{"gnatmake ^-Pprj^/PROJECT_FILE=PRJ^ main1 main2 main3"}. + +When the project attribute @code{Main} is not specified, or is specified +as an empty string list, or when the switch @option{-u} is used on the command +line, then invoking @command{gnatmake} with no main on the command line will +result in all immediate sources of the project file being checked, and +potentially recompiled. Depending on the presence of the switch @option{-u}, +sources from other project files on which the immediate sources of the main +project file depend are also checked and potentially recompiled. In other +words, the @option{-u} switch is applied to all of the immediate sources of the +main project file. + +When no main is specified on the command line and attribute @code{Main} exists +and includes several mains, or when several mains are specified on the +command line, the default ^switches^switches^ in package @code{Builder} will +be used for all mains, even if there are specific ^switches^switches^ +specified for one or several mains. + +But the ^switches^switches^ from package @code{Binder} or @code{Linker} will be +the specific ^switches^switches^ for each main, if they are specified. + +@c --------------------------------------------- +@node Library Project Files +@subsection Library Project Files +@c --------------------------------------------- + +@noindent +When @command{gnatmake} is invoked with a main project file that is a library +project file, it is not allowed to specify one or more mains on the command +line. + +When a library project file is specified, switches ^-b^/ACTION=BIND^ and +^-l^/ACTION=LINK^ have special meanings. + +@itemize @bullet +@item ^-b^/ACTION=BIND^ is only allowed for stand-alone libraries. It indicates + to @command{gnatmake} that @command{gnatbind} should be invoked for the + library. + +@item ^-l^/ACTION=LINK^ may be used for all library projects. It indicates + to @command{gnatmake} that the binder generated file should be compiled + (in the case of a stand-alone library) and that the library should be built. +@end itemize + + +@c --------------------------------------------- +@node The GNAT Driver and Project Files +@section The GNAT Driver and Project Files +@c --------------------------------------------- + +@noindent +A number of GNAT tools, other than @command{^gnatmake^gnatmake^} +can benefit from project files: +(@command{^gnatbind^gnatbind^}, +@command{^gnatcheck^gnatcheck^}, +@command{^gnatclean^gnatclean^}, +@command{^gnatelim^gnatelim^}, +@command{^gnatfind^gnatfind^}, +@command{^gnatlink^gnatlink^}, +@command{^gnatls^gnatls^}, +@command{^gnatmetric^gnatmetric^}, +@command{^gnatpp^gnatpp^}, +@command{^gnatstub^gnatstub^}, +and @command{^gnatxref^gnatxref^}). However, none of these tools can be invoked +directly with a project file switch (@option{^-P^/PROJECT_FILE=^}). +They must be invoked through the @command{gnat} driver. + +The @command{gnat} driver is a wrapper that accepts a number of commands and +calls the corresponding tool. It was designed initially for VMS platforms (to +convert VMS qualifiers to Unix-style switches), but it is now available on all +GNAT platforms. + +On non-VMS platforms, the @command{gnat} driver accepts the following commands +(case insensitive): + +@itemize @bullet +@item BIND to invoke @command{^gnatbind^gnatbind^} +@item CHOP to invoke @command{^gnatchop^gnatchop^} +@item CLEAN to invoke @command{^gnatclean^gnatclean^} +@item COMP or COMPILE to invoke the compiler +@item ELIM to invoke @command{^gnatelim^gnatelim^} +@item FIND to invoke @command{^gnatfind^gnatfind^} +@item KR or KRUNCH to invoke @command{^gnatkr^gnatkr^} +@item LINK to invoke @command{^gnatlink^gnatlink^} +@item LS or LIST to invoke @command{^gnatls^gnatls^} +@item MAKE to invoke @command{^gnatmake^gnatmake^} +@item NAME to invoke @command{^gnatname^gnatname^} +@item PREP or PREPROCESS to invoke @command{^gnatprep^gnatprep^} +@item PP or PRETTY to invoke @command{^gnatpp^gnatpp^} +@item METRIC to invoke @command{^gnatmetric^gnatmetric^} +@item STUB to invoke @command{^gnatstub^gnatstub^} +@item XREF to invoke @command{^gnatxref^gnatxref^} + +@end itemize + +@noindent +(note that the compiler is invoked using the command +@command{^gnatmake -f -u -c^gnatmake -f -u -c^}). + +On non-VMS platforms, between @command{gnat} and the command, two +special switches may be used: + +@itemize @bullet +@item @command{-v} to display the invocation of the tool. +@item @command{-dn} to prevent the @command{gnat} driver from removing + the temporary files it has created. These temporary files are + configuration files and temporary file list files. + +@end itemize + +@noindent +The command may be followed by switches and arguments for the invoked +tool. + +@smallexample + gnat bind -C main.ali + gnat ls -a main + gnat chop foo.txt +@end smallexample + +@noindent +Switches may also be put in text files, one switch per line, and the text +files may be specified with their path name preceded by '@@'. + +@smallexample + gnat bind @@args.txt main.ali +@end smallexample + +@noindent +In addition, for commands BIND, COMP or COMPILE, FIND, ELIM, LS or LIST, LINK, +METRIC, PP or PRETTY, STUB and XREF, the project file related switches +(@option{^-P^/PROJECT_FILE^}, +@option{^-X^/EXTERNAL_REFERENCE^} and +@option{^-vP^/MESSAGES_PROJECT_FILE=^x}) may be used in addition to +the switches of the invoking tool. + +When GNAT PP or GNAT PRETTY is used with a project file, but with no source +specified on the command line, it invokes @command{^gnatpp^gnatpp^} with all +the immediate sources of the specified project file. + +When GNAT METRIC is used with a project file, but with no source +specified on the command line, it invokes @command{^gnatmetric^gnatmetric^} +with all the immediate sources of the specified project file and with +@option{^-d^/DIRECTORY^} with the parameter pointing to the object directory +of the project. + +In addition, when GNAT PP, GNAT PRETTY or GNAT METRIC is used with +a project file, no source is specified on the command line and +switch ^-U^/ALL_PROJECTS^ is specified on the command line, then +the underlying tool (^gnatpp^gnatpp^ or +^gnatmetric^gnatmetric^) is invoked for all sources of all projects, +not only for the immediate sources of the main project. +@ifclear vms +(-U stands for Universal or Union of the project files of the project tree) +@end ifclear + +For each of the following commands, there is optionally a corresponding +package in the main project. + +@itemize @bullet +@item package @code{Binder} for command BIND (invoking @code{^gnatbind^gnatbind^}) + +@item package @code{Check} for command CHECK (invoking + @code{^gnatcheck^gnatcheck^}) + +@item package @code{Compiler} for command COMP or COMPILE (invoking the compiler) + +@item package @code{Cross_Reference} for command XREF (invoking + @code{^gnatxref^gnatxref^}) + +@item package @code{Eliminate} for command ELIM (invoking + @code{^gnatelim^gnatelim^}) + +@item package @code{Finder} for command FIND (invoking @code{^gnatfind^gnatfind^}) + +@item package @code{Gnatls} for command LS or LIST (invoking @code{^gnatls^gnatls^}) + +@item package @code{Gnatstub} for command STUB + (invoking @code{^gnatstub^gnatstub^}) + +@item package @code{Linker} for command LINK (invoking @code{^gnatlink^gnatlink^}) + +@item package @code{Check} for command CHECK + (invoking @code{^gnatcheck^gnatcheck^}) + +@item package @code{Metrics} for command METRIC + (invoking @code{^gnatmetric^gnatmetric^}) + +@item package @code{Pretty_Printer} for command PP or PRETTY + (invoking @code{^gnatpp^gnatpp^}) + +@end itemize + +@noindent +Package @code{Gnatls} has a unique attribute @code{Switches}, +a simple variable with a string list value. It contains ^switches^switches^ +for the invocation of @code{^gnatls^gnatls^}. + +@smallexample @c projectfile +@group +project Proj1 is + package gnatls is + for Switches + use ("^-a^-a^", + "^-v^-v^"); + end gnatls; +end Proj1; +@end group +@end smallexample + +@noindent +All other packages have two attribute @code{Switches} and +@code{^Default_Switches^Default_Switches^}. + +@code{Switches} is an indexed attribute, indexed by the +source file name, that has a string list value: the ^switches^switches^ to be +used when the tool corresponding to the package is invoked for the specific +source file. + +@code{^Default_Switches^Default_Switches^} is an attribute, +indexed by the programming language that has a string list value. +@code{^Default_Switches^Default_Switches^ ("Ada")} contains the +^switches^switches^ for the invocation of the tool corresponding +to the package, except if a specific @code{Switches} attribute +is specified for the source file. + +@smallexample @c projectfile +@group +project Proj is + + for Source_Dirs use ("./**"); + + package gnatls is + for Switches use + ("^-a^-a^", + "^-v^-v^"); + end gnatls; +@end group +@group + + package Compiler is + for ^Default_Switches^Default_Switches^ ("Ada") + use ("^-gnatv^-gnatv^", + "^-gnatwa^-gnatwa^"); + end Binder; +@end group +@group + + package Binder is + for ^Default_Switches^Default_Switches^ ("Ada") + use ("^-C^-C^", + "^-e^-e^"); + end Binder; +@end group +@group + + package Linker is + for ^Default_Switches^Default_Switches^ ("Ada") + use ("^-C^-C^"); + for Switches ("main.adb") + use ("^-C^-C^", + "^-v^-v^", + "^-v^-v^"); + end Linker; +@end group +@group + + package Finder is + for ^Default_Switches^Default_Switches^ ("Ada") + use ("^-a^-a^", + "^-f^-f^"); + end Finder; +@end group +@group + + package Cross_Reference is + for ^Default_Switches^Default_Switches^ ("Ada") + use ("^-a^-a^", + "^-f^-f^", + "^-d^-d^", + "^-u^-u^"); + end Cross_Reference; +end Proj; +@end group +@end smallexample + +@noindent +With the above project file, commands such as + +@smallexample + ^gnat comp -Pproj main^GNAT COMP /PROJECT_FILE=PROJ MAIN^ + ^gnat ls -Pproj main^GNAT LIST /PROJECT_FILE=PROJ MAIN^ + ^gnat xref -Pproj main^GNAT XREF /PROJECT_FILE=PROJ MAIN^ + ^gnat bind -Pproj main.ali^GNAT BIND /PROJECT_FILE=PROJ MAIN.ALI^ + ^gnat link -Pproj main.ali^GNAT LINK /PROJECT_FILE=PROJ MAIN.ALI^ +@end smallexample + +@noindent +will set up the environment properly and invoke the tool with the switches +found in the package corresponding to the tool: +@code{^Default_Switches^Default_Switches^ ("Ada")} for all tools, +except @code{Switches ("main.adb")} +for @code{^gnatlink^gnatlink^}. +It is also possible to invoke some of the tools, +(@code{^gnatcheck^gnatcheck^}, +@code{^gnatmetric^gnatmetric^}, +and @code{^gnatpp^gnatpp^}) +on a set of project units thanks to the combination of the switches +@option{-P}, @option{-U} and possibly the main unit when one is interested +in its closure. For instance, +@smallexample +gnat metric -Pproj +@end smallexample + +@noindent +will compute the metrics for all the immediate units of project +@code{proj}. +@smallexample +gnat metric -Pproj -U +@end smallexample + +@noindent +will compute the metrics for all the units of the closure of projects +rooted at @code{proj}. +@smallexample +gnat metric -Pproj -U main_unit +@end smallexample + +@noindent +will compute the metrics for the closure of units rooted at +@code{main_unit}. This last possibility relies implicitly +on @command{gnatbind}'s option @option{-R}. But if the argument files for the +tool invoked by the @command{gnat} driver are explicitly specified +either directly or through the tool @option{-files} option, then the tool +is called only for these explicitly specified files. + +@c --------------------------------------------- +@node The Development Environments +@section The Development Environments +@c --------------------------------------------- + +@noindent +See the appropriate manuals for more details. These environments will +store a number of settings in the project itself, when they are meant +to be shared by the whole team working on the project. Here are the +attributes defined in the package @b{IDE} in projects. + +@table @code +@item Remote_Host +This is a simple attribute. Its value is a string that designates the remote +host in a cross-compilation environment, to be used for remote compilation and +debugging. This field should not be specified when running on the local +machine. + +@item Program_Host +This is a simple attribute. Its value is a string that specifies the +name of IP address of the embedded target in a cross-compilation environment, +on which the program should execute. + +@item Communication_Protocol +This is a simple string attribute. Its value is the name of the protocol +to use to communicate with the target in a cross-compilation environment, +e.g.@: @code{"wtx"} or @code{"vxworks"}. + +@item Compiler_Command +This is an associative array attribute, whose domain is a language name. Its +value is string that denotes the command to be used to invoke the compiler. +The value of @code{Compiler_Command ("Ada")} is expected to be compatible with +gnatmake, in particular in the handling of switches. + +@item Debugger_Command +This is simple attribute, Its value is a string that specifies the name of +the debugger to be used, such as gdb, powerpc-wrs-vxworks-gdb or gdb-4. + +@item Default_Switches +This is an associative array attribute. Its indexes are the name of the +external tools that the GNAT Programming System (GPS) is supporting. Its +value is a list of switches to use when invoking that tool. + +@item Gnatlist +This is a simple attribute. Its value is a string that specifies the name +of the @command{gnatls} utility to be used to retrieve information about the +predefined path; e.g., @code{"gnatls"}, @code{"powerpc-wrs-vxworks-gnatls"}. +@item VCS_Kind +This is a simple attribute. Its value is a string used to specify the +Version Control System (VCS) to be used for this project, e.g.@: CVS, RCS +ClearCase or Perforce. + +@item VCS_File_Check +This is a simple attribute. Its value is a string that specifies the +command used by the VCS to check the validity of a file, either +when the user explicitly asks for a check, or as a sanity check before +doing the check-in. + +@item VCS_Log_Check +This is a simple attribute. Its value is a string that specifies +the command used by the VCS to check the validity of a log file. + +@item VCS_Repository_Root +The VCS repository root path. This is used to create tags or branches +of the repository. For subversion the value should be the @code{URL} +as specified to check-out the working copy of the repository. + +@item VCS_Patch_Root +The local root directory to use for building patch file. All patch chunks +will be relative to this path. The root project directory is used if +this value is not defined. + +@end table + +@c --------------------------------------------- +@node Cleaning up with GPRclean +@section Cleaning up with GPRclean +@c --------------------------------------------- + +@noindent +The GPRclean tool removes the files created by GPRbuild. +At a minimum, to invoke GPRclean you must specify a main project file +in a command such as @code{gprclean proj.gpr} or @code{gprclean -P proj.gpr}. + +Examples of invocation of GPRclean: + +@smallexample + gprclean -r prj1.gpr + gprclean -c -P prj2.gpr +@end smallexample + +@menu +* Switches for GPRclean:: +@end menu + +@c --------------------------------------------- +@node Switches for GPRclean +@subsection Switches for GPRclean +@c --------------------------------------------- + +@noindent +The switches for GPRclean are: + +@itemize @bullet +@item @option{--config=
} : Specify the + configuration project file name + +@item @option{--autoconf=} + + This specifies a configuration project file name that already exists or will + be created automatically. Option @option{--autoconf=} + cannot be specified more than once. If the configuration project file + specified with @option{--autoconf=} exists, then it is used. Otherwise, + @value{gprconfig} is invoked to create it automatically. + +@item @option{-c} : Only delete compiler-generated files. Do not delete + executables and libraries. + +@item @option{-f} : Force deletions of unwritable files + +@item @option{-F} : Display full project path name in brief error messages + +@item @option{-h} : Display this message + +@item @option{-n} : Do not delete files, only list files to delete + +@item @option{-P} : Use Project File @emph{}. + +@item @option{-q} : Be quiet/terse. There is no output, except to report + problems. + +@item @option{-r} : (recursive) Clean all projects referenced by the main + project directly or indirectly. Without this switch, GPRclean only + cleans the main project. + +@item @option{-v} : Verbose mode + +@item @option{-vPx} : Specify verbosity when parsing Project Files. + x = 0 (default), 1 or 2. + +@item @option{-Xnm=val} : Specify an external reference for Project Files. + +@end itemize + + + -- cgit v1.2.3