Previous: GPRconfig variable substitution, Up: The GPRconfig knowledge base   [Contents][Index]

3.2.6.5 Configurations

The second type of information stored in the knowledge base are the chunks of gprbuild configuration files.

Each of these chunks is also placed in an XML node that provides optional filters. If all the filters match, then the chunk will be merged with other similar chunks and placed in the final configuration file that is generated by GPRconfig.

For instance, it is possible to indicate that a chunk should only be included if the GNAT compiler with the soft-float runtime is used. Such a chunk can for instance be used to ensure that Ada sources are always compiled with the -msoft-float command line switch.

GPRconfig does not perform sophisticated merging of chunks. It simply groups packages together. For example, if the two chunks are:

chunk1:
   package Language_Processing is
     for Attr1 use ("foo");
   end Language_Processing;
chunk2:
   package Language_Processing is
     for Attr1 use ("bar");
   end Language_Processing;

Then the final configuration file will look like:

package Language_Processing is
  for Attr1 use ("foo");
  for Attr1 use ("bar");
end Language_Processing;

As a result, to avoid conflicts, it is recommended that the chunks be written so that they easily collaborate together. For instance, to obtain something equivalent to

package Language_Processing is
  for Attr1 use ("foo", "bar");
end Language_Processing;

the two chunks above should be written as:

chunk1:
  package Language_Processing is
    for Attr1 use Language_Processing'Attr1 & ("foo");
  end Language_Processing;
chunk2:
  package Language_Processing is
    for Attr1 use Language_Processing'Attr1 & ("bar");
  end Language_Processing;

The chunks are described in a <configuration> XML node. The most important child of such a node is <config>, which contains the chunk itself. For instance, you would write:

<configuration>
  ...  list of filters, see below
  <config>
   package Language_Processing is
      for Attr1 use Language_Processing'Attr1 & ("foo");
   end Language_Processing;
  </config>
</configuration>

If <config> is an empty node (i.e., ‘<config/>’ or ‘<config></config>’) was used, then the combination of selected compilers will be reported as invalid, in the sense that code compiled with these compilers cannot be linked together. As a result, GPRconfig will not create the configuration file.

The special variables (see GPRconfig variable substitution) are also substituted in the chunk. That allows you to compute some attributes of the compiler (its path, the runtime,…), and use them when generating the chunks.

The filters themselves are of course defined through XML tags, and can be any of:

<compilers negate="false">

This filter contains a list of <compiler> children. The <compilers> filter matches if any of its children match. However, you can have several <compilers> filters, in which case they must all match. This can be used to include linker switches chunks. For instance, the following code would be used to describe the linker switches to use when GNAT 5.05 or 5.04 is used in addition to g++ 3.4.1:

<configuration>
  <compilers>
    <compiler name="GNAT" version="5.04" />
    <compiler name="GNAT" version="5.05" />
  </compilers>
  <compilers>
    <compiler name="G++" version="3.4.1" />
  </compilers>
  ...
</configuration>

If the attribute negate is ‘true’, then the meaning of this filter is inverted, and it will match if none of its children matches.

The format of the <compiler> is the following:

<compiler name="name" version="..."
   runtime="..." language="..." />

The name and language attributes, when specified, match the corresponding attributes used in the <compiler_description> children. All other attributes are regular expressions, which are matched against the corresponding selected compilers. When an attribute is not specified, it will always match. Matching is done in a case-insensitive manner.

For instance, to check a GNAT compiler in the 5.x family, use:

<compiler name="GNAT" version="5.\d+" />
<hosts negate="false">

This filter contains a list of <host> children. It matches when any of its children matches. You can specify only one <hosts> node. The format of <host> is a node with a single mandatory attribute name, which is a regexp matched against the architecture on which GPRconfig is running. The name of the architecture was computed by configure when GPRconfig was built. Note that the regexp might match a substring of the host name, so you might want to surround it with "^" and "$" so that it only matches the whole host name (for instance, "elf" would match "powerpc-elf", but "^elf$" would not).

If the negate attribute is ‘true’, then the meaning of this filter is inverted, and it will match when none of its children matches.

For instance, to active a chunk only if the compiler is running on an intel linux machine, use:

<hosts>
  <host name="i.86-.*-linux(-gnu)?" />
</hosts>
<targets negate="false">

This filter contains a list of <target> children. It behaves exactly like <hosts>, but matches against the architecture targeted by the selected compilers. For instance, to activate a chunk only when the code is targeted for linux, use:

If the negate attribute is ‘true’, then the meaning of this filter is inverted, and it will match when none of its children matches.

<targets>
  <target name="i.86-.*-linux(-gnu)?" />
</targets>