Project files have an Ada-like syntax. The minimal project file is:
project Empty is end Empty;
The identifier Empty
is the name of the project. This project name must be present after the reserved word end
at the end of the project file, followed by a semicolon.
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"
).
simple_name ::= identifier name ::= simple_name { . simple_name }
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).
Reserved words are the standard Ada 95 reserved words, plus several others listed below, and cannot be used for identifiers. In particular, the following Ada 95 reserved words are currently used in project files:
abstract all at case end for is limited null others package renames type use when with
The additional project file reserved words are:
extends external external_as_list project
Note that aggregate
and library
are qualifiers that may appear before the keyword project
, but they are not themselves keywords.
To avoid possible compatibility issues in the future, we recommend that the reserved words introduced by Ada 2005 and Ada 2012 not be used as identifiers in project files. Note also that new reserved words may be added to the project file syntax in a later release.
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 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. Alternatively, a project may depend on other projects in various ways:
by importing them through context clauses (with
clauses), or
by extending at most one other project (its base project).
A given project may exhibit either or both of these dependencies; for example:
with "imported_proj.gpr"; project My_Project extends "base_proj.gpr" is end My_Project;
The import dependencies form a directed graph, potentially cyclic when using limited with. The subgraph reflecting the extends relationship is a tree (hierarchy).
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 uniquely identifies 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 variables 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, and may not appear in different context clauses for the same project.
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
clauses in the cycle is a limited with
.
A projectâs 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âs 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.
project ::= context_clause project_declaration context_clause ::= {with_clause} with_clause ::= [ 'limited' ] 'with' path_name { , path_name } ; path_name ::= string_literal project_declaration ::= simple_project_declaration | project_extension simple_project_declaration ::= [ qualifier ] 'project' <project_>name 'is' {declarative_item} 'end' <project_>name ; project_extension ::= [ qualifier ] 'project' <project_>name 'extends' [ 'all' ] <base_project_>name 'is' {declarative_item} 'end' <project_>name ; qualifier ::= 'abstract' | identifier [ identifier ]2.9.2. Qualified Projectsï
Immediately preceding the reserved project
, a qualifier may be specified which identifies the nature of the project. The following qualifiers are allowed:
A standard project is a non-library project with source files. This is the default (implicit) qualifier.
A project with no source files. Such a project must either have no declaration for attributes Source_Dirs
, Source_Files
, Languages
or Source_List_File
, or one of Source_Dirs
, Source_Files
, or Languages
must be declared as empty. If it extends another project, the base project must also be an abstract project.
A project whose sources are aggregated from other project files.
A library whose sources are aggregated from other project or library project files.
A library project must define both of the attributes Library_Name and Library_Dir.
A configuration project cannot be in a project tree. It describes compilers and other tools to gprbuild.
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.
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 ::= 'null' ;
An empty declaration is allowed anywhere a declaration is allowed. It has no effect.
2.9.4. PackagesïA project file may contain packages, which 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 always recognized in project files (See Attributes for the list of attributes that each can contain).
This package specifies characteristics useful when invoking the binder either directly via the gnat driver or when using GPRbuild. See Main Subprograms.
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 Compiler
, Binder
or Linker
packages, but there are some general options that should be defined in this package. See Main Subprograms, and Executable File Names in particular.
This package specifies the options used when cleaning a project or a project tree using the tools gnatclean or gprclean.
This package specifies the compilation options used by the compiler for each language. See Tools Options in Project Files.
This package specifies the options to use when invoking gnatls via the gnat driver.
This package specifies the options used when installing a project with gprinstall. See Package Install Attributes.
This package specifies the options used by the linker. See Main Subprograms.
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. See Naming Schemes.
Other tool-specific packages may be defined by different project-aware tools. Refer to the toolâs documentation for the list of supported attributes and other specifics.
In its simplest form, a package may be empty:
project Simple is package Builder is end Builder; end Simple;
A package may contain attribute declarations, variable declarations and 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 gnat.
Package renaming
A package may be defined by a 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 base or 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 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.
Package extension
A package can also be defined by an extending declaration. This is similar to a renaming declaration, except that it is possible to add or override attributes.
package_declaration ::= package_spec | package_renaming | package_extension package_spec ::= 'package' <package_>simple_name 'is' { simple_declarative_item } 'end' package_identifier ; package_renaming ::= 'package' <package_>simple_name 'renames' <project_>simple_name.package_identifier ; package_extension ::= 'package' <package_>simple_name 'extends' <project_>simple_name.package_identifier 'is' { simple_declarative_item } 'end' package_identifier ;2.9.5. Expressionsï
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 run-time 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:
A literal string, for instance "comm/my_proj.gpr"
The name of a variable that evaluates to a string (see Variables)
The name of an attribute that evaluates to a string (see Attributes)
An external reference (see The function External)
A concatenation of the above, as in "prefix_" & Var
.
A list of strings is one of the following:
A parenthesized comma-separated list of zero or more string expressions, for instance (File_Name, "gnat.adc", File_Name & ".orig")
or ()
.
The name of a variable that evaluates to a list of strings
The name of an attribute that evaluates to a list of strings
A concatenation of a list of strings and a string (as defined above), for instance ("A", "B") & "C"
A concatenation of two lists of strings
The following is the grammar for expressions
string_literal ::= "{string_element}" -- Same as Ada string_expression ::= string_literal | <variable_>name | external_value | attribute_reference | ( string_expression { & string_expression } ) string_list ::= ( string_expression { , string_expression } ) | <string_variable>_name | <string_>attribute_reference term ::= string_expression | string_list expression ::= term { & term } -- Concatenation
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:
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;
Here are some specific examples:
2.9.6. Built-in Functionsï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
Built-in functions may be used in expressions. The names of built-in functions are not reserved words and may also be used as variable names. In an expression, a built-in function is recognized if its name is immediately followed by an open parenthesis (â(â).
2.9.6.1. The functionAlternative
ï
Warning
This is not implemented yet in gprbuild or GNATcoll.Projects-based tools such as GNATstudio.
The function Alternative takes two arguments. It returns the second argument if the first one is not the empty string.
2.9.6.2. The functionAlternative ("", "this is the default value") => "" Alternative ("x86_64-linux-gnu", "linux") => "linux"
Default
ï
Warning
This is not implemented yet in gprbuild or GNATcoll.Projects-based tools such as GNATstudio.
The function Default takes two arguments. It returns the second argument if the first one is the empty string.
2.9.6.3. The functionDefault ("", "this is the default value") => "this is the default value" Default ("One", "this is the default value") => "One"
External
ï
An external value is an expression whose value is obtained from the command that invoked the processing of the current project file (typically a gprbuild command).
The syntax of a single string external value is:
external_value ::= 'external' ( string_literal [, string_literal] )
The first string_literal is the name of the external variable, whose value (a string) may be specified by an environment variable with this name, or on the command line via the -Xname=value
option. The command line takes precedence if the name is defined in both contexts, thus allowing the user to locally override an environment variable. 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. If the value of the external variable is not obtained from an environment variable or the command line, and the invocation of the external
function does not supply a second parameter, then an error is reported.
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.
This construct is typically used to initialize typed variables, which are then used in case constructions to control the value assigned to attributes in various scenarios. Thus such variables are often called scenario variables.
2.9.6.4. The functionExternal_As_List
ï
An external value is an expression whose value is obtained from the command that invoked the processing of the current project file (typically a gprbuild command).
The syntax for a string list external value is:
external_value ::= 'external_as_list' ( string_literal , string_literal )
The first string_literal is the name of the external variable, with the same interpretation as for the external
function; it is looked up first on the command line (as the name in a -Xname=value
option) and, if not so specified, then as an environment variable. If it is not defined by either of these, then the function returns an empty list. The second string_literal is the separator between each component of the string list. An empty list is returned 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.
Note the following differences between External
and External_As_List
:
The External_As_List
function has no default value for the external variable
The External_As_List
function returns an empty list, and does not report an error, when the value of the external variable is undefined.
These differences reflect the different use cases for the two functions. External variables evaluated by the External
function are often used for configuration control, and misspellings should be detected as errors rather than silently returning the empty string. If the user intended an empty string as the result when the external variable was undefined, then this could easily be obtained:
External ("SOME_VAR", "")
In contrast, the External_As_List
function more typically is used for external variables that may or may not have definitions (for example, lists of options or paths) and then the desired result in the undefined case is an empty list, not a reported error.
Here is an example of the External_As_List
function:
External_As_List ("SWITCHES", ",")
If the external value of SWITCHES
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 "-gnatv"
, the result is ("-gnatv")
.
If the external value is ",,"
, the result is (""
).
If the external value is ","
, the result is ()
, the empty string list.
Filter_Out
ï
Warning
This is not implemented yet in gprbuild or GNATcoll.Projects-based tools such as GNATstudio.
The function Filter_Out takes two arguments. The first argument must be a list and the second one a simple string. The second argument is a pattern (regular expression). Elements in the list matching the pattern will be removed from the list.
List := ("value1", "or", "another", "one");
Example removing all values containing the letter âoâ:
Filter_Out (List, ".*o.*") => ("value1")
Example removing all values:
2.9.6.6. The functionFilter_Out (List, ".*") => ()
Item_At
ï
Warning
This is not implemented yet in gprbuild or GNATcoll.Projects-based tools such as GNATstudio.
The function Item_At takes two arguments. The first argument must be a list and the second argument an integer image (simple string). The number represents the index of the item to return from the list. If the number is negative it is an index starting from the end of the list. That is, â-1â is the last list item.
2.9.6.7. The functionList := ("one", "two", "three", "last"); Item_At (List, "2") => "two" Item_At (List, "-1") => "last"
Lower
ï
Warning
This is not implemented yet in gprbuild or GNATcoll.Projects-based tools such as GNATstudio.
Function Lower takes a single argument which can be a simple string or a list. It returns the argument with all strings in lower case.
Example:
Lower ("The Lower Built-In") => "the lower built-in"
Example with a list:
2.9.6.8. The functionList := ("One", "Two"); Lower (List) => ("one", "two")
Match
ï
Warning
This is not implemented yet in gprbuild or GNATcoll.Projects-based tools such as GNATstudio.
Function Match takes two mandatory arguments. The first argument is a simple string or a list. The second argument is the pattern (regular expression) to match. An optional third argument can be given which is the replacement pattern for the matching strings.
Example:
Match ("x86_64-linux-gnu", "linux") => "linux"
Example with a list and a replacement pattern:
List := ("value1", "or", "another", "one"); Match (List, "(.*r)", "r:\1") => ("r:or", "r:another")
In the above example we match all strings in List containing the letter ârâ and the result is formed with âr:â as prefix concatenated with the matching string.
2.9.6.9. The functionRemove_Prefix
ï
Warning
This is not implemented yet in gprbuild or GNATcoll.Projects-based tools such as GNATstudio.
The function Remove_Prefix takes two arguments. The first argument can be a simple string or a list. The second argument is a simple string representing the prefix to remove if present. The prefix is removed from the simple string or from each element of the list.
2.9.6.10. The functionList := ("libone", "two", "libthree") Remove_Prefix (List, "lib") => ("one", "two", "three") Remove_Prefix ("libZ.so", "lib") => "Z.so"
Remove_Suffix
ï
Warning
This is not implemented yet in gprbuild or GNATcoll.Projects-based tools such as GNATstudio.
The function Remove_Suffix takes two arguments. The first argument can be a simple string or a list. The second argument is a simple string representing the suffix to remove if present. The suffix is removed from the simple string or from each element of the list.
2.9.6.11. The functionList := ("libone", "two", "libthree") Remove_Suffix (List, "one") => ("lib", "two", "libthree") Remove_Suffix ("libZ.so", ".so") => "libZ"
Split
ï
Function Split takes two single string parameters and return a string list.
Example:
Split ("-gnatf,-gnatv", ",") => ("-gnatf", "gnatv")
The first string argument is the string to be split. The second argument is the separator. Each occurrence of the separator in the first argument is a place where it is split. If the first argument is an empty string or contains only occurrences of the separator, then the result is an empty string list. If the argument does not contains any occurrence of the separator, then the result is a list with only one string: the first argument. Empty strings are not included in the result.
2.9.6.12. The functionSplit ("-gnatf -gnatv", " ") => ("-gnatf", "gnatv")
Upper
ï
Warning
This is not implemented yet in gprbuild or GNATcoll.Projects-based tools such as GNATstudio.
Function Upper takes a single argument which can be a simple string or a list. It returns the argument with all strings in upper case.
Example:
Upper ("The Upper Built-In") => "THE UPPER BUILT-IN"
Example with a list:
2.9.7. Typed String DeclarationïList := ("One", "Two"); Upper (List) => ("ONE", "TWO")
A 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 type declaration may only appear at the project level, not inside a package.
typed_string_declaration ::= 'type' <typed_string_>simple_name 'is' ( string_literal {, string_literal} );
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:
type OS is ("GNU/Linux", "Unix", "Windows", "VMS");
Variables of a string type are called typed variables; all other variables are called untyped variables. Typed variables are particularly useful in case constructions, to support conditional attribute declarations. (See Case Constructions).
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.
2.9.8. Variablesï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 typed variable can be used as part of a case expression to compute the value, but it can only be declared once in the project file, so that all case constructions 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 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.
typed_variable_declaration ::= <typed_variable_>simple_name : <typed_string_>name := string_expression; variable_declaration ::= <variable_>simple_name := expression;
Here are some examples of variable declarations:
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");
A variable reference may take several forms:
The simple variable name, for a variable in the current package (if any) or in the current project
An expanded name, whose prefix is a context name.
A context may be one of the following:
The name of an existing package in the current project
The name of an imported project of the current project
The name of a direct or indirect base project (i.e., a project extended by the current project, either directly or indirectly)
An expanded name whose prefix is an imported/parent project name, and whose selector is a package name in that project.
A case construction is used in a project file to effect conditional behavior. Through this construction, 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 others choice must appear last in the list of alternatives.
The syntax of a case
construction is based on the Ada case construction (although the null
declaration for empty alternatives is optional).
The case expression must be a string variable, either typed or not, whose value is often given by an external reference (see The function External).
Each alternative starts with the reserved word when
, either a list of literal strings separated by the "|"
character or the reserved word others
, and the "=>"
token. When the case expression is a typed string variable, each literal string must belong to the string type that is the type of the case variable. After each =>
, there are zero or more declarations. The only declarations allowed in a case construction are other case constructions, 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.
case_construction ::= 'case' <variable_>name 'is' {case_item} 'end' 'case' ; case_item ::= 'when' discrete_choice_list => {case_declaration | attribute_declaration | variable_declaration | empty_declaration} discrete_choice_list ::= string_literal {| string_literal} | 'others'
Here is a typical example, with a typed string variable:
project MyProj is type OS_Type is ("GNU/Linux", "Unix", "Windows", "VMS"); OS : OS_Type := external ("OS", "GNU/Linux"); package Compiler is case OS is when "GNU/Linux" | "Unix" => for Switches ("Ada") use ("-gnath"); when "Windows" => for Switches ("Ada") use ("-gnatP"); when others => null; end case; end Compiler; end MyProj;
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4