ECF Files | ![]() ![]() |
An ECF file contains the description of the Eiffel program to be compiled. ECF stands for Eiffel Configuration File. It tells the compiler:
Here is a simple example for a hello_world program:
It tells the compiler that the name of the system is "hello_world". By default, this will be the name of the executable.<system name="hello_world"> <target name="hello_world"> <root class="HELLO_WORLD" feature="make"/> <setting name="console_application" value="true"/> <library name="free_elks" location="${GOBO}/library/free_elks/library.ecf"/> <cluster name="hello_world" location="./"/> </target> </system>
There is only one target, which means that this ECF file describes only one way to build this system. For some systems, there might be several ways to compile a system, with different settings, different library classes, etc. This might be the case when compiling a system as a console application, or as a GUI application. Or when compiling a system as a single threaded application or as an application taking advantage of concurrency. Even though they have the same name in the example above, the name of the target may be different from the name of the system.
The root class of the system is HELLO_WORLD and the root creation procedure is its creation procedure make.
The system is an console application. Without this setting, the system would be compiled as a GUI application.
Finally, the compiler is told where to find the Eiffel classes. A cluster is a directory containing Eiffel files with the extension .e. A library is a set of classes described by another ECF file. In the example above the library contains the kernel classes, which are classes describing strings, characters, integers, arrays, etc.
The beginning of an ECF file will typically look like that:
The first line indicates to the XML parser which character encoding should be used to read this XML file.<?xml version="1.0" encoding="ISO-8859-1"?> <system xmlns="http://www.eiffel.com/developers/xml/configuration-1-23-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-23-0 http://www.eiffel.com/developers/xml/configuration-1-23-0.xsd" name="system_name" uuid="12345678-1234-1234-1234-123456789ABC" library_target="target_name" >
The lines starting with xmlns= and xsi:schemaLocation specify which version of ECF is used in this file. In this case, it is using version 1.23.0. The XML description of each version can be found in $GOBO/library/tools/config/ecf/.
The line which starts with xmlns:xsi= is for XML schema, and is not relevant for ECF.
The name of the system is used by default as the name of the executable.
The uuid is a way to uniquely identify this ECF file. This is important when the ECF file describes a library whose classes are to be used in other libraries or systems because it uniquely identifies this library as well.
When the ECF file describes a library whose classes are to be used in other libraries or systems, the library_target is the name of the target in the current ECF file which will describe the classes included in this library as well as some settings and options to be applied to these classes. This is important when the ECF file contains several targets.
A system can contain one or more targets.
Targets are defined in systems. In the following example:
we have two targets named debug and release. The second one is an extension of the first one, instructing the compiler that inlining should be turned on when generating C code.<target name="debug"> <root class="HELLO_WORLD" feature="make"/> <setting name="console_application" value="true"/> <library name="free_elks" location="${GOBO}/library/free_elks/library.ecf"/> <cluster name="hello_world" location="./"/> </target> <target name="release" extends="debug"> <setting name="inlining" value="true"/> </target>
A target can be abstract:
which means that it cannot be used to compile a system or as a library_target of a library. The purpose of abstract targets is to be used as parents of other targets.<target name="target_name" abstract="true"> ... </target>
The root class and root creation procedure can be specified in a target using:
When the target describes a library whose classes are to be used in other libraries or systems, the root will look like that:<root class="ROOT_CLASS" feature="root_creation_procedure"/>
<root all_classes="true"/>
Targets can contain clusters, librarys, assemblys, class mappings and file_rules to specify the classes which will be part of the system. They can also contain settings, capabilitys and options to let the compiler know how to compile this system. When the Eiffel code needs to call C functions (or code written in other languages), the compiler will use the information provided in external_includes, external_cflags, external_objects, external_librarys, external_resources and external_linker_flags. Constructs appearing in the ECF file may use variables defined in the target.
Under construction
Under construction
Under construction
Under construction
Under construction
Under construction
Under construction
Under construction
Variables are defined in targets, using the following syntax:
The variables visible from a target are the variables specified in that target, recursively in its parent targets, and environment variables. Variables specified in a target override environment variables with the same name. They also override variables with the same name specified in its parent targets.<variable name="..." value="..."/>
Variables appearing in pathnames are replaced by the corresponding value if there is a variable with that name visible from the target where the pathname has been specified. It is replaced by an empty string otherwise. Note that variables visible from the project target (if different from the target where the pathname is specified) are not taken into account. Also, variables specified in a child of the target where the pathname is specified are not take into account, even if that pathname is used as part of this child target through inheritance. For example:
even when dealing with the target 'child', the pathname of the cluster 'foo' will be expanded to 'gobo/library' and not 'ise/library'.<target name="parent"> <variable name="foo" value="gobo"/> <cluster name="foo" location="${foo}/library"/> </target> <target name="child" extends="parent"> <variable name="foo" value="ise"/> </target>
Variables appearing in the value of other variables:
are not expanded. So the value of the variable 'bar' is '${foo} is great', and not 'gobo is great'.<variable name="foo" value="gobo"/> <variable name="bar" value="${foo} is great"/>
Contrary to variables appearing in pathnames, variables used in 'custom' clauses of conditions, such as 'foo' in the example below:
only take into account values visible from the project target, and not from the target where this condition has been specified (if different from the project target). So here this condition will be satisfied if the variable 'foo' has the value 'gobo' when viewed from the project target, even if this variable has another value in the current target.<condition/> <custom name="foo" value="gobo"/> </condition/>
Class mappings are defined in targets and clusters, using the following syntax:
They are used to create class name aliases. For example if 'old_name' is 'STRING' and 'new_name' is 'STRING_8', it means that whenever the type 'STRING' will be found in the class texts of the given target or cluster, they will be seen as if 'STRING_8' had been written.<mapping old_name="..." new_name="..."/>
Class mappings specified in a target override mappings with the same 'old_name' specified in its parent targets. Likewise, class mappings specified in clusters override mappings with the same 'old_name' in the enclosing target.
If the class name 'A1' is mapped to class 'B1' in a given library L1, and class 'B1' has been declared in this library, then both 'A1' and 'B1' will be visible in other libraries or systems using this library L1. It is also possible to map the class name 'A1' to a class 'B2' in a given library L1 even though class 'B2' has been declared in another library L2 used by L1. In that case 'A1' will not be visible in other libraries or systems using this library L1. These other libraries or systems will also have to use L2 directly and they will have to contain the same mapping declaration from 'A1' to 'B2.
In case of a class mapping appearing in a cluster C1, the class mapping will be seen in the other clusters of the enclosing target only if the 'new_name' is a class declared in the same cluster C1 (and this name is not overriden by a mapping in the other clusters). Otherwise the class mapping is only seen in the class texts of the given cluster C1.
Note that gec and gelint do not support class mappings at the cluster level, only at the target level.
Copyright © 2008-2025, Eric Bezault mailto:ericb@gobosoft.com https://www.gobosoft.com Last Updated: 31 August 2025 |
![]() ![]() ![]() ![]() |