<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://dev.eiffel.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zoran</id>
		<title>EiffelStudio: an EiffelSoftware project - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://dev.eiffel.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Zoran"/>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/Special:Contributions/Zoran"/>
		<updated>2026-04-15T11:15:19Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.24.1</generator>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User:Zoran&amp;diff=10296</id>
		<title>User:Zoran</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User:Zoran&amp;diff=10296"/>
				<updated>2008-01-16T02:43:45Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:People]]&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; &lt;br /&gt;
|&lt;br /&gt;
==Zoran Simic==&lt;br /&gt;
*Mail: zoran (at) simicweb.com&lt;br /&gt;
*GMT-8 ([http://www.ci.walnut-creek.ca.us/ Walnut Creek], [http://www.ca.gov/ CA])&lt;br /&gt;
*Skype: catcall&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|&lt;br /&gt;
[[Image:zoran.jpg]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=File:Zoran.jpg&amp;diff=10295</id>
		<title>File:Zoran.jpg</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=File:Zoran.jpg&amp;diff=10295"/>
				<updated>2008-01-16T02:43:07Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User:Zoran&amp;diff=10294</id>
		<title>User:Zoran</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User:Zoran&amp;diff=10294"/>
				<updated>2008-01-16T02:42:27Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:People]]&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; &lt;br /&gt;
|&lt;br /&gt;
==Zoran Simic==&lt;br /&gt;
*Mail: zoran (a-t) simicweb.com&lt;br /&gt;
*GMT-8 ([http://www.ci.walnut-creek.ca.us/ Walnut Creek], [http://www.ca.gov/ CA])&lt;br /&gt;
*Skype: catcall&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|&lt;br /&gt;
[[Image:zoran.jpg]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User:Zoran&amp;diff=10293</id>
		<title>User:Zoran</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User:Zoran&amp;diff=10293"/>
				<updated>2008-01-16T02:39:37Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: /* Zoran Simic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:People]]&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; &lt;br /&gt;
|&lt;br /&gt;
==Zoran Simic==&lt;br /&gt;
*Mail: [mailto:zoran_simic@yahoo.com zoran_simic@yahoo.com]&lt;br /&gt;
*GMT-8 ([http://www.ci.walnut-creek.ca.us/ Walnut Creek], [http://www.ca.gov/ CA])&lt;br /&gt;
*Skype: catcall&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|&lt;br /&gt;
[[Image:http://simicweb.com/z2.jpg]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=User:Zoran&amp;diff=6310</id>
		<title>User:Zoran</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=User:Zoran&amp;diff=6310"/>
				<updated>2006-11-22T00:09:12Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:People]]&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; &lt;br /&gt;
|&lt;br /&gt;
==Zoran Simic==&lt;br /&gt;
*Mail: [mailto:zoran_simic@yahoo.com zoran_simic@yahoo.com]&lt;br /&gt;
*GMT-8 ([http://www.ci.walnut-creek.ca.us/ Walnut Creek], [http://www.ca.gov/ CA])&lt;br /&gt;
*Skype: catcall&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|&lt;br /&gt;
http://simicweb.com/z2.jpg&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=5553</id>
		<title>ProposalProjectFiles</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=5553"/>
				<updated>2006-10-31T10:52:15Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: /* Handling projects being opened several times at once */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Configuration]]&lt;br /&gt;
[[Category:EiffelStudio]]&lt;br /&gt;
[[Category:Compiler]]&lt;br /&gt;
[[Category:Projects]]&lt;br /&gt;
{{cleanup}}&lt;br /&gt;
== Rationale ==&lt;br /&gt;
Currently, 5.7 offers the following status on project files:&lt;br /&gt;
* a .ecf file describes the Eiffel system to compile, without any compiled-project specific info (see [[Configuration]])&lt;br /&gt;
* .ecf files used to be called .acex, but this has been abandoned in favor of the .ecf extension&lt;br /&gt;
* compiled-project specific info is stored in a .user file in the same folder as the .ecf&lt;br /&gt;
* the .user file resides in the same folder as the corresponding .ecf&lt;br /&gt;
* the .user file is a stored object of type USER_OPTIONS&lt;br /&gt;
* [[ConfigurationMigration]] page describes how .ace files are migrated to the new .ecf format, and gives some info on the compiled-project files structure&lt;br /&gt;
* a folder called '''EIFGENs''' holds all the files representing a compiled project&lt;br /&gt;
* the .user file contains the path to the EIFGENs folder&lt;br /&gt;
* it is possible to have the .ecf and .user files in another folder than the one containing the EIFGENs (but it is not possible to share the same .user file for different users and machines)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are some limitations to the current implementation&lt;br /&gt;
* the .ecf file can not be used from a network share (the .user file will contain info relative to the machine that performed the compilation, like a path to the EIFGENs folder that is meaningful only from the machine that created the project)&lt;br /&gt;
* if the .ecf file is not in the same folder as the EIFGENs, the .user file bounds it to that folder anyway, we might as well then fix the location of the EIFGENs folder and have it necessarily be in the same folder as the .ecf&lt;br /&gt;
* the .user file could contain more info allowing a more coherent management of Eiffel projects, the following scenarios are not handled correctly right now:&lt;br /&gt;
** a group of developers wants to share the same .ecf file, but have different compilation folders&lt;br /&gt;
** if a user compiles a project with environment variable GOBO defined for example, then closes the project, reopens it but forgets to define GOBO this time around, the compiler fails with an obscure error stating that &amp;quot;/library/kernel&amp;quot; is missing, the user has to guess that GOBO is not defined...&lt;br /&gt;
** opening the same project several times at once usually leads to project corruption, and there is no way to know whether a project is already open or not&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
* It should be possible to open any project from a file (by double-clicking on the file for example)&lt;br /&gt;
* Opening an already compiled project should restore the environment as it was when project was compiled (as much as possible, for coherence)&lt;br /&gt;
* It should be possible to instruct the compiler to recompile a project from scratch using that same file&lt;br /&gt;
* It should be possible for third party tools (other than estudio compiler itself) to work with that project description file (why not, many people could contribute tools that work with estudio projects)&lt;br /&gt;
* We consider that the situation of opening a project from estudio itself is covered no matter what we choose (estudio will always show an &amp;quot;open project&amp;quot; dialog that will list previously compiled projects and will allow to create a new project using a wizard)&lt;br /&gt;
* The interesting bits are for &amp;quot;batch&amp;quot; or &amp;quot;automated&amp;quot; project creation and compilation&lt;br /&gt;
* It should be possible to have different targets of the same project compiled with different versions of estudio, situations in which this is useful:&lt;br /&gt;
** one wants to compile a 'win32' and 'win64' version of the same project&lt;br /&gt;
** one wants to compile a 'release' and 'experimental' version of the same project using 2 different estudio deliveries&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
* a .ecf file describes an Eiffel system in general (it's equivalent to an Eiffel class)&lt;br /&gt;
* a .ecp file is also generated by the compiler holding all the other project specific info (it's equivalent to an Eiffel object - an instance of a .ecf 'class' mentioned above)&lt;br /&gt;
** the .ecp file contains all the info currently in the .user file, and more&lt;br /&gt;
** the .ecp file can be used to compile a project from scratch etc.&lt;br /&gt;
&lt;br /&gt;
=== Project structure ===&lt;br /&gt;
* .ecf file can be located anywhere, can be shared amongst users, machines, estudio versions etc.&lt;br /&gt;
* .ecp file can be located anywhere (but will reside in the folder containing the EIFGENs most of the time)&lt;br /&gt;
* .ecp file is not supposed to be shared, it's specific to a machine and to a user&lt;br /&gt;
* an EIFGENs folder can be deleted and recreated entirely from the info made available in a .ecp file&lt;br /&gt;
* an EIFGENs folder can be opened in the state it was left after last compilation from the info made available in a .ecp file&lt;br /&gt;
&lt;br /&gt;
=== The configuration file: .ecf ===&lt;br /&gt;
The .ecf file remains as is now, containing the definition of the system to compile,&lt;br /&gt;
with eventually several targets (but no information relative to an actual compilation is stored in there).&lt;br /&gt;
See [[Configuration]]&lt;br /&gt;
&lt;br /&gt;
If a user double-clicks or otherwise tries to open a project given only the .ecf file, then the following happens:&lt;br /&gt;
* in batch mode, an error is issued stating that a project can not be opened from a .ecf file&lt;br /&gt;
* in GUI mode, recently compiled projects corresponding to the .ecf are shown to the user, which has the option of selecting one of them, or browsing to the actual project location)&lt;br /&gt;
&lt;br /&gt;
=== The project file: .ecp ===&lt;br /&gt;
A .ecp file is similar to the .ecf file, but contains only project specific info.&lt;br /&gt;
It is also an XML file serialized from a set of dedicated Eiffel objects.&lt;br /&gt;
&lt;br /&gt;
A project may be opened from a .ecp file easily, since it holds all the needed info.&lt;br /&gt;
&lt;br /&gt;
An .ecp file holds all the info relative to the current compilation, this info is (exhaustively):&lt;br /&gt;
* the path to the .ecf file&lt;br /&gt;
* a list of settings per compilation target&lt;br /&gt;
* the 'last used target' (for convenience)&lt;br /&gt;
* the 'project path' containing the EIFGENs&lt;br /&gt;
* each 'compilation target' contains the following info:&lt;br /&gt;
** the name of the target&lt;br /&gt;
** the version of estudio that compiled the target&lt;br /&gt;
** the name of the machine that build the project&lt;br /&gt;
** the username of the account under which the project was built&lt;br /&gt;
** the working directory that the user chose (by default it's the folder containing the .ecp file)&lt;br /&gt;
** the last command line arguments the project was started with (in debug mode)&lt;br /&gt;
** the list of used command line arguments (for convenience)&lt;br /&gt;
** are command line arguments 'active'&lt;br /&gt;
** all the used environment variables (an environment variable is 'used' if it appears in the .ecf file)&lt;br /&gt;
&lt;br /&gt;
The .ecp file should not be a stored Eiffel object for 2 reasons:&lt;br /&gt;
* it depends on the version of storable used, and presents retrieval problems if the API of the stored object is modified&lt;br /&gt;
* if contributors want to open that storable, they have to have the right Eiffel class in their system&lt;br /&gt;
&lt;br /&gt;
==== .ecp XML structure ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;settings&lt;br /&gt;
		ecf=&amp;quot;/path/to/ecf/sample.ecf&amp;quot;&lt;br /&gt;
		last_target=&amp;quot;target1&amp;quot;&lt;br /&gt;
		project_path=&amp;quot;/projects/sample&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
	&amp;lt;target&lt;br /&gt;
		name=&amp;quot;target1&amp;quot;&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		working_directory=&amp;quot;/projects/testing&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
		&amp;lt;command_line active=&amp;quot;true&amp;quot; last=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--use this and that&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--crack a smile&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/command_line&amp;gt;&lt;br /&gt;
		&amp;lt;environment&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;ISE_EIFFEL&amp;quot; value=&amp;quot;/path/to/estudio/5.7.58953&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;GOBO&amp;quot; value=&amp;quot;/path/to/gobo&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/environment&amp;gt;&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
	&amp;lt;target name=&amp;quot;target2&amp;quot;&amp;gt;&lt;br /&gt;
		...&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ECP classes ====&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_PROJECT&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	ecf: STRING&lt;br /&gt;
			-- Path to .ecf file&lt;br /&gt;
&lt;br /&gt;
	last_target: STRING&lt;br /&gt;
			-- Name of last used target&lt;br /&gt;
 &lt;br /&gt;
	project_path: STRING&lt;br /&gt;
			-- Path to folder containing the EIFGENs generated folder&lt;br /&gt;
 &lt;br /&gt;
	targets: LIST [ECP_TARGET]&lt;br /&gt;
			-- The configuration targets.&lt;br /&gt;
 &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project target&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_TARGET&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	name: STRING&lt;br /&gt;
			-- Name of the target&lt;br /&gt;
&lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio chosen to compile the target&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the target was compiled&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the compilation took place&lt;br /&gt;
&lt;br /&gt;
	working_directory: STRING&lt;br /&gt;
			-- Working directory selected by the user&lt;br /&gt;
			-- Optional, if not specified, the working folder is the folder containing the .ecp file&lt;br /&gt;
&lt;br /&gt;
	use_arguments: BOOLEAN&lt;br /&gt;
			-- Use arguments?&lt;br /&gt;
&lt;br /&gt;
	last_argument: STRING&lt;br /&gt;
			-- Last used argument.&lt;br /&gt;
&lt;br /&gt;
	arguments: LIST [STRING]&lt;br /&gt;
			-- List of arguments used by current target&lt;br /&gt;
&lt;br /&gt;
	evironment_variables: LIST [ECP_ENVIRONMENT_VARIABLE]&lt;br /&gt;
			-- List of environment variables refered to in the .ecf file for current target&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== What does this bring us? ====&lt;br /&gt;
* it is possible to open an eiffel project from a .ecp file, with the right version of estudio, environment settings etc.&lt;br /&gt;
* it is possible to recompile a project from scratch from a .ecp file easily (all the needed info is there)&lt;br /&gt;
* if environment variables changed since the project was compiled, the user can be warned&lt;br /&gt;
&lt;br /&gt;
=== What to do with the 'environment settings' ===&lt;br /&gt;
&lt;br /&gt;
Why do we keep the 'used environment variables'? Why do they matter?&lt;br /&gt;
Typically, when compiling a project, developers refer to clusters using environment variables.&lt;br /&gt;
But what should happen if compilation1 used var1, and compilation2 uses a different value for var1?&lt;br /&gt;
Right now, nothing special happens, compilation2 simply goes on, not even knowing that var1 changed...&lt;br /&gt;
&lt;br /&gt;
It is however important to detect this, and it is very easy to implement too.&lt;br /&gt;
Many situations occur that can lead to compilation errors and corrupted projects due to this environment-variable situation.&lt;br /&gt;
Problems typically occur in companies with many users and machines juggling with a set of different environments.&lt;br /&gt;
Also, a project is often setup with all the right environment variables, but then users want to later on simply open a given project without worrying what environment variables were used to set it up, keeping these in the .ecp file would allow for &amp;quot;simply double-click the .ecp file to open a project&amp;quot; kind of thing.&lt;br /&gt;
&lt;br /&gt;
The following suggestion should allow to take care of this problem elegantly.&lt;br /&gt;
&lt;br /&gt;
* When a compilation is initiated, the 'env vars' list in the project settings file is empty&lt;br /&gt;
* The following steps would be implemented in an 'initial pass' (before degree 6) by the compiler&lt;br /&gt;
* Each time the compile encounters an env var in the .ecf file (and only there), it looks at what was previously present in the .ecp:&lt;br /&gt;
** if the env var is used for the first time (not yet defined in the .ecp) then set it in the .ecp&lt;br /&gt;
** if the env var was already there, then compare it:&lt;br /&gt;
*** if the current env var value is equal to the one stored in the .ecp, then it's good, just continue compilation&lt;br /&gt;
*** if they differ, then remember they differed and remeber both values&lt;br /&gt;
** do the above for all env vars refered to in the .ecf&lt;br /&gt;
* Now at the end of this &amp;quot;initial pass&amp;quot; we have a set of &amp;quot;differing&amp;quot; env vars&lt;br /&gt;
** if the set is empty, go on to degree 6 as usual&lt;br /&gt;
** if the set is not empty, then proceed as follows (2 different situations)&lt;br /&gt;
*** in GUI mode, popup a modal dialog showing the differences and asking the user whether it's OK to continue (a nice touch would be to let the user choose which version to use for each env var, old or new version)&lt;br /&gt;
*** in batch mode, 2 different cases&lt;br /&gt;
**** abort compilation if for example a -strict flag is specified on the command line&lt;br /&gt;
**** continue compilation with a warning listing the diffs otherwise&lt;br /&gt;
* Apply the same logic for the &amp;quot;hostname&amp;quot; and &amp;quot;username&amp;quot; info in the .ecp file (also before degree 6)&lt;br /&gt;
** if the project is being opened on a different machine than the one that created the last .ecp:&lt;br /&gt;
*** popup the warning dialog, asking the user whether it's OK to continue opening the project or not&lt;br /&gt;
*** in batch mode:&lt;br /&gt;
**** fail if -strict is specified&lt;br /&gt;
**** warn otherwise&lt;br /&gt;
* If the compilation proceeds (either because user said OK, or because -strict was not specified), overwrite the info in the .ecp with the new values&lt;br /&gt;
* The same logic could be applied to other pieces of info in the .ecp (such as project path etc.. some users open their projects from local folders such as C:\projects on Windows, as well as UNC folders such as \\MACHINE\projects, sometimes at the same time!)&lt;br /&gt;
&lt;br /&gt;
=== Handling projects being opened several times at once ===&lt;br /&gt;
Typically, if the same project (same EIFGENs) is opened several times (from different machines for example) at once, there's a risk of the project getting corrputed&lt;br /&gt;
There is a very simple way to handle this problem elegantly:&lt;br /&gt;
* create a file in /&amp;lt;project path&amp;gt;/EIFGENs/&amp;lt;target&amp;gt;/ec.lock as soon as the project is open and put the following info in it:&lt;br /&gt;
** the estudio version&lt;br /&gt;
** the hostname and username opening the project&lt;br /&gt;
** the date and time when it was opened&lt;br /&gt;
** the &amp;quot;process_id&amp;quot; of the compiler opening the project (and creating this .lock file)&lt;br /&gt;
* delete this file as soon as the project is closed (ie, the batch job exits, or the user closes the IDE)&lt;br /&gt;
* if the compiler crashes and doesn't get the chance to close and delete this file, it's OK&lt;br /&gt;
* if when opening the project the file already exists, then 2 situations:&lt;br /&gt;
** in batch mode:&lt;br /&gt;
*** exit immediately with an error saying that the &amp;quot;ec.lock&amp;quot; file needs to be deleted (either manually or by closing the other running process) before the project can be opened in batch mode&lt;br /&gt;
** in GUI mode:&lt;br /&gt;
*** popup a dialog asking the user what to do, the user has the following info and choices:&lt;br /&gt;
*** the popup shows which user/host/date has the project opened&lt;br /&gt;
*** &amp;quot;Open read-only&amp;quot; - allows the user to open the project without the capability to compile it (as to avoid corrupting the project)&lt;br /&gt;
*** &amp;quot;Open anyway, I know it's not open&amp;quot; - this option deletes the .lock file and recreates it (this would typically happen if the compiler crashed and did not get a chance to delete this .lock file)&lt;br /&gt;
*** &amp;quot;Cancel&amp;quot; project opening operation&lt;br /&gt;
&lt;br /&gt;
Suggested format for this .lock file is also XML, here's an example of such a file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;lock&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		install=&amp;quot;C:\Eiffel57&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		date=&amp;quot;2006/05/28 17:56:27&amp;quot;&lt;br /&gt;
		pid=&amp;quot;2451&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The hostname and username info has an obvious added value (one knows who has the project open and where)&lt;br /&gt;
The 'process_id' info would allow third-party Eiffel project management tools to &amp;quot;communicate&amp;quot; eventually with the ec.exe process that has the project open in the future, or kill the process, or change its priority etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project lock file&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_LOCK&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio that created the .lock file&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the .lock file was created&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the .lock file was created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	date: STRING&lt;br /&gt;
			-- Date when .lock file was created&lt;br /&gt;
			-- Maybe this does not need to be an attribute...&lt;br /&gt;
			-- The creation date of the file itself should give same info anyway&lt;br /&gt;
&lt;br /&gt;
	pid: INTEGER&lt;br /&gt;
			-- Process id of the process that created this lock file&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Command-line arguments for 'ec' and 'estudio' ===&lt;br /&gt;
'ec' and 'estudio' should accept similar command line arguments for coherence&lt;br /&gt;
* To create a project, user must provide 2 arguments: -project_path and -config&lt;br /&gt;
* To simply open a project, the user provides -project argument&lt;br /&gt;
&lt;br /&gt;
==== 'ec' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
;-strict&lt;br /&gt;
:Flag indicating whether environment settings should match accross compilations&lt;br /&gt;
:If not specified, compiler issues a warning if environment variables modified since last compilation&lt;br /&gt;
:If specified, compiler aborts with an error listing mismatching environment variables&lt;br /&gt;
&lt;br /&gt;
* Command line arguments -config and -project_path must be specified together for project creation, when these 2 arguments are provided:&lt;br /&gt;
** a new .ecp is always created (existing .ecp is deleted and recreated)&lt;br /&gt;
** any existing EIFGENs is deleted prior to compilation&lt;br /&gt;
** EIFGENs folder is stored in same 'project_path' folder as the .ecp&lt;br /&gt;
** users can choose a different path for the EIFGENs folder either by:&lt;br /&gt;
*** creating a .ecp file themselves&lt;br /&gt;
*** using the graphical IDE, which could allow for such customization (ec.exe in batch mode does not)&lt;br /&gt;
* -project is used to open an alrady compiled once project&lt;br /&gt;
* the pair [-project_path, -config] is exclusive with -project (users can not specify the -project along with -project_path or -config)&lt;br /&gt;
* -target is always optional and may be provided for both project creation or project opening&lt;br /&gt;
* -strict makes sense only for project opening&lt;br /&gt;
&lt;br /&gt;
==== 'estudio' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
&lt;br /&gt;
Similar rules as above apply.&lt;br /&gt;
The graphical IDE should ask questions to user only if something left unspecified.&lt;br /&gt;
&lt;br /&gt;
==== Scenarios ====&lt;br /&gt;
* Create a new project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
estudio -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Open an existing project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project /projects/sample/sample.ecp -freeze -c_compile&lt;br /&gt;
estudio -project /project/sample/sample.ecp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecp file is equivalent to &amp;lt;code&amp;gt;estudio -project &amp;lt;ecp&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecf file is handled like so:&lt;br /&gt;
** if a .ecp file with same name as the .ecf is present in same folder, open the .ecp file in that same folder&lt;br /&gt;
** otherwise, prompt the user to choose which .ecp file to use&lt;br /&gt;
*** list all recently compiled projects that could match&lt;br /&gt;
*** allow user to 'browse' to .ecp location&lt;br /&gt;
*** allow user to create a new project out of the .ecp file&lt;br /&gt;
&lt;br /&gt;
=== Pseudo-code algorithm ===&lt;br /&gt;
* .ecp files are processed once when the project is opened (before first degree 6)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
if arguments.project_path or arguments.config then&lt;br /&gt;
	if arguments.project then&lt;br /&gt;
		abort (&amp;quot;specify either -project or [-project_path + -config]&amp;quot;)&lt;br /&gt;
	elseif not arguments.project_path then&lt;br /&gt;
		abort (&amp;quot;missing -project_path argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	elsief not arguments.config then&lt;br /&gt;
		abort (&amp;quot;missing -config argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	create_new_project (arguments.project_path, arguments.config)&lt;br /&gt;
elseif arguments.project then&lt;br /&gt;
	if arguments.project.extension = &amp;quot;ecp&amp;quot; then&lt;br /&gt;
		open_project (arguments.project)&lt;br /&gt;
	elseif arguments.project.extension = &amp;quot;epr&amp;quot; then&lt;br /&gt;
		convert_old_epr (arguments.project)&lt;br /&gt;
	else&lt;br /&gt;
		abort (&amp;quot;Unsupported project file&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
else&lt;br /&gt;
	?&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
create_new_project (a_project_path, a_config: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		--create new .ecp file&lt;br /&gt;
		--delete EIFGENs if present&lt;br /&gt;
		open_project (created_ecp_file.path)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
open_project (a_ecp_path: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		create ecp.make (a_ecp_path)&lt;br /&gt;
		--check that associated .ecf file exists&lt;br /&gt;
		--go through .ecf file and list all environment variables it uses&lt;br /&gt;
		--go through all env vars used and:&lt;br /&gt;
			--get their 'old' value from .ecp (if any)&lt;br /&gt;
			--get their 'new' current value (given by shell)&lt;br /&gt;
			if var.is_mismatch then&lt;br /&gt;
				mismatches.extend (var)&lt;br /&gt;
			end&lt;br /&gt;
		--apply similar comparison for ecp.host and ecp.username&lt;br /&gt;
		if not mismatches.is_empty then&lt;br /&gt;
			if gui_mode then&lt;br /&gt;
				-- Show mismatches to user and ask him to pick the correct values, and allow him to cancel compilation altogether&lt;br /&gt;
			elseif arguments.strict then&lt;br /&gt;
				abort (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			else&lt;br /&gt;
				warn (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		--create or update .ecp file, store 'new' env vars values&lt;br /&gt;
		--check that EIFGENs exists, if not create it&lt;br /&gt;
		--create .lock file&lt;br /&gt;
		--project is opened, we may start compiling it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=What_the_Smart_Docking_library_looks_like&amp;diff=3374</id>
		<title>What the Smart Docking library looks like</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=What_the_Smart_Docking_library_looks_like&amp;diff=3374"/>
				<updated>2006-06-13T04:23:58Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Multiple levels of docking and nesting ==&lt;br /&gt;
&lt;br /&gt;
There will be a snapshot here.&lt;br /&gt;
&lt;br /&gt;
== Tear-off widgets and vertical title tabs when docking left/right ==&lt;br /&gt;
&lt;br /&gt;
There will be a snapshot here.&lt;br /&gt;
&lt;br /&gt;
== Only a editor's area, which means zones which are not editor type contents can’t drag into the main window area, and vice versa ==&lt;br /&gt;
&lt;br /&gt;
There will be a snapshot here.&lt;br /&gt;
&lt;br /&gt;
== The tool bar is also dockable ==&lt;br /&gt;
    * Multiple tool bars in a single row.&lt;br /&gt;
&lt;br /&gt;
    * Audo hide tool bar buttons when not enough space.&lt;br /&gt;
&lt;br /&gt;
    * When multiple tool bar in one row and not enough space, can resize tool bar zone manually.&lt;br /&gt;
&lt;br /&gt;
    * Tool bar can float.&lt;br /&gt;
  &lt;br /&gt;
    * When tool bar floating, user can drag border of tool bar and resize tool bar buttons to different rows.&lt;br /&gt;
&lt;br /&gt;
    * Customize supported.&lt;br /&gt;
&lt;br /&gt;
    * Double click on the header of a docking tool bar, it'll float to last floating position and last floating size. Or double click title bar of floating tool bar zone, it'll dock to last docked row and position.&lt;br /&gt;
&lt;br /&gt;
== Docking feedbacks ==&lt;br /&gt;
   * There are two kinds of docking feedback currently available:&lt;br /&gt;
&lt;br /&gt;
   One used in WIndows:&lt;br /&gt;
There will be a snapshot here.&lt;br /&gt;
&lt;br /&gt;
   The other one used in Linux or on Windows when using remote desktop (terminal service):&lt;br /&gt;
There will be a snapshot here.&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3085</id>
		<title>ProposalProjectFiles</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3085"/>
				<updated>2006-05-30T07:01:42Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: /* What does this bring us? */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Configuration]]&lt;br /&gt;
[[Category:EiffelStudio]]&lt;br /&gt;
[[Category:Compiler]]&lt;br /&gt;
[[Category:Projects]]&lt;br /&gt;
== Rationale ==&lt;br /&gt;
Currently, 5.7 offers the following status on project files:&lt;br /&gt;
* a .ecf file describes the Eiffel system to compile, without any compiled-project specific info (see [[Configuration]])&lt;br /&gt;
* .ecf files used to be called .acex, but this has been abandoned in favor of the .ecf extension&lt;br /&gt;
* compiled-project specific info is stored in a .user file in the same folder as the .ecf&lt;br /&gt;
* the .user file resides in the same folder as the corresponding .ecf&lt;br /&gt;
* the .user file is a stored object of type USER_OPTIONS&lt;br /&gt;
* [[ConfigurationMigration]] page describes how .ace files are migrated to the new .ecf format, and gives some info on the compiled-project files structure&lt;br /&gt;
* a folder called '''EIFGENs''' holds all the files representing a compiled project&lt;br /&gt;
* the .user file contains the path to the EIFGENs folder&lt;br /&gt;
* it is possible to have the .ecf and .user files in another folder than the one containing the EIFGENs (but it is not possible to share the same .user file for different users and machines)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are some limitations to the current implementation&lt;br /&gt;
* the .ecf file can not be used from a network share (the .user file will contain info relative to the machine that performed the compilation, like a path to the EIFGENs folder that is meaningful only from the machine that created the project)&lt;br /&gt;
* if the .ecf file is not in the same folder as the EIFGENs, the .user file bounds it to that folder anyway, we might as well then fix the location of the EIFGENs folder and have it necessarily be in the same folder as the .ecf&lt;br /&gt;
* the .user file could contain more info allowing a more coherent management of Eiffel projects, the following scenarios are not handled correctly right now:&lt;br /&gt;
** a group of developers wants to share the same .ecf file, but have different compilation folders&lt;br /&gt;
** if a user compiles a project with environment variable GOBO defined for example, then closes the project, reopens it but forgets to define GOBO this time around, the compiler fails with an obscure error stating that &amp;quot;/library/kernel&amp;quot; is missing, the user has to guess that GOBO is not defined...&lt;br /&gt;
** opening the same project several times at once usually leads to project corruption, and there is no way to know whether a project is already open or not&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
* It should be possible to open any project from a file (by double-clicking on the file for example)&lt;br /&gt;
* Opening an already compiled project should restore the environment as it was when project was compiled (as much as possible, for coherence)&lt;br /&gt;
* It should be possible to instruct the compiler to recompile a project from scratch using that same file&lt;br /&gt;
* It should be possible for third party tools (other than estudio compiler itself) to work with that project description file (why not, many people could contribute tools that work with estudio projects)&lt;br /&gt;
* We consider that the situation of opening a project from estudio itself is covered no matter what we choose (estudio will always show an &amp;quot;open project&amp;quot; dialog that will list previously compiled projects and will allow to create a new project using a wizard)&lt;br /&gt;
* The interesting bits are for &amp;quot;batch&amp;quot; or &amp;quot;automated&amp;quot; project creation and compilation&lt;br /&gt;
* It should be possible to have different targets of the same project compiled with different versions of estudio, situations in which this is useful:&lt;br /&gt;
** one wants to compile a 'win32' and 'win64' version of the same project&lt;br /&gt;
** one wants to compile a 'release' and 'experimental' version of the same project using 2 different estudio deliveries&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
* a .ecf file describes an Eiffel system in general (it's equivalent to an Eiffel class)&lt;br /&gt;
* a .ecp file is also generated by the compiler holding all the other project specific info (it's equivalent to an Eiffel object - an instance of a .ecf 'class' mentioned above)&lt;br /&gt;
** the .ecp file contains all the info currently in the .user file, and more&lt;br /&gt;
** the .ecp file can be used to compile a project from scratch etc.&lt;br /&gt;
&lt;br /&gt;
=== Project structure ===&lt;br /&gt;
* .ecf file can be located anywhere, can be shared amongst users, machines, estudio versions etc.&lt;br /&gt;
* .ecp file can be located anywhere (but will reside in the folder containing the EIFGENs most of the time)&lt;br /&gt;
* .ecp file is not supposed to be shared, it's specific to a machine and to a user&lt;br /&gt;
* an EIFGENs folder can be deleted and recreated entirely from the info made available in a .ecp file&lt;br /&gt;
* an EIFGENs folder can be opened in the state it was left after last compilation from the info made available in a .ecp file&lt;br /&gt;
&lt;br /&gt;
=== The configuration file: .ecf ===&lt;br /&gt;
The .ecf file remains as is now, containing the definition of the system to compile,&lt;br /&gt;
with eventually several targets (but no information relative to an actual compilation is stored in there).&lt;br /&gt;
See [[Configuration]]&lt;br /&gt;
&lt;br /&gt;
If a user double-clicks or otherwise tries to open a project given only the .ecf file, then the following happens:&lt;br /&gt;
* in batch mode, an error is issued stating that a project can not be opened from a .ecf file&lt;br /&gt;
* in GUI mode, recently compiled projects corresponding to the .ecf are shown to the user, which has the option of selecting one of them, or browsing to the actual project location)&lt;br /&gt;
&lt;br /&gt;
=== The project file: .ecp ===&lt;br /&gt;
A .ecp file is similar to the .ecf file, but contains only project specific info.&lt;br /&gt;
It is also an XML file serialized from a set of dedicated Eiffel objects.&lt;br /&gt;
&lt;br /&gt;
A project may be opened from a .ecp file easily, since it holds all the needed info.&lt;br /&gt;
&lt;br /&gt;
An .ecp file holds all the info relative to the current compilation, this info is (exhaustively):&lt;br /&gt;
* the path to the .ecf file&lt;br /&gt;
* a list of settings per compilation target&lt;br /&gt;
* the 'last used target' (for convenience)&lt;br /&gt;
* the 'project path' containing the EIFGENs&lt;br /&gt;
* each 'compilation target' contains the following info:&lt;br /&gt;
** the name of the target&lt;br /&gt;
** the version of estudio that compiled the target&lt;br /&gt;
** the name of the machine that build the project&lt;br /&gt;
** the username of the account under which the project was built&lt;br /&gt;
** the working directory that the user chose (by default it's the folder containing the .ecp file)&lt;br /&gt;
** the last command line arguments the project was started with (in debug mode)&lt;br /&gt;
** the list of used command line arguments (for convenience)&lt;br /&gt;
** are command line arguments 'active'&lt;br /&gt;
** all the used environment variables (an environment variable is 'used' if it appears in the .ecf file)&lt;br /&gt;
&lt;br /&gt;
The .ecp file should not be a stored Eiffel object for 2 reasons:&lt;br /&gt;
* it depends on the version of storable used, and presents retrieval problems if the API of the stored object is modified&lt;br /&gt;
* if contributors want to open that storable, they have to have the right Eiffel class in their system&lt;br /&gt;
&lt;br /&gt;
==== .ecp XML structure ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;settings&lt;br /&gt;
		ecf=&amp;quot;/path/to/ecf/sample.ecf&amp;quot;&lt;br /&gt;
		last_target=&amp;quot;target1&amp;quot;&lt;br /&gt;
		project_path=&amp;quot;/projects/sample&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
	&amp;lt;target&lt;br /&gt;
		name=&amp;quot;target1&amp;quot;&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		working_directory=&amp;quot;/projects/testing&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
		&amp;lt;command_line active=&amp;quot;true&amp;quot; last=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--use this and that&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--crack a smile&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/command_line&amp;gt;&lt;br /&gt;
		&amp;lt;environment&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;ISE_EIFFEL&amp;quot; value=&amp;quot;/path/to/estudio/5.7.58953&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;GOBO&amp;quot; value=&amp;quot;/path/to/gobo&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/environment&amp;gt;&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
	&amp;lt;target name=&amp;quot;target2&amp;quot;&amp;gt;&lt;br /&gt;
		...&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ECP classes ====&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_PROJECT&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	ecf: STRING&lt;br /&gt;
			-- Path to .ecf file&lt;br /&gt;
&lt;br /&gt;
	last_target: STRING&lt;br /&gt;
			-- Name of last used target&lt;br /&gt;
 &lt;br /&gt;
	project_path: STRING&lt;br /&gt;
			-- Path to folder containing the EIFGENs generated folder&lt;br /&gt;
 &lt;br /&gt;
	targets: LIST [ECP_TARGET]&lt;br /&gt;
			-- The configuration targets.&lt;br /&gt;
 &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project target&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_TARGET&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	name: STRING&lt;br /&gt;
			-- Name of the target&lt;br /&gt;
&lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio chosen to compile the target&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the target was compiled&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the compilation took place&lt;br /&gt;
&lt;br /&gt;
	working_directory: STRING&lt;br /&gt;
			-- Working directory selected by the user&lt;br /&gt;
			-- Optional, if not specified, the working folder is the folder containing the .ecp file&lt;br /&gt;
&lt;br /&gt;
	use_arguments: BOOLEAN&lt;br /&gt;
			-- Use arguments?&lt;br /&gt;
&lt;br /&gt;
	last_argument: STRING&lt;br /&gt;
			-- Last used argument.&lt;br /&gt;
&lt;br /&gt;
	arguments: LIST [STRING]&lt;br /&gt;
			-- List of arguments used by current target&lt;br /&gt;
&lt;br /&gt;
	evironment_variables: LIST [ECP_ENVIRONMENT_VARIABLE]&lt;br /&gt;
			-- List of environment variables refered to in the .ecf file for current target&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== What does this bring us? ====&lt;br /&gt;
* it is possible to open an eiffel project from a .ecp file, with the right version of estudio, environment settings etc.&lt;br /&gt;
* it is possible to recompile a project from scratch from a .ecp file easily (all the needed info is there)&lt;br /&gt;
* if environment variables changed since the project was compiled, the user can be warned&lt;br /&gt;
&lt;br /&gt;
=== What to do with the 'environment settings' ===&lt;br /&gt;
&lt;br /&gt;
Why do we keep the 'used environment variables'? Why do they matter?&lt;br /&gt;
Typically, when compiling a project, developers refer to clusters using environment variables.&lt;br /&gt;
But what should happen if compilation1 used var1, and compilation2 uses a different value for var1?&lt;br /&gt;
Right now, nothing special happens, compilation2 simply goes on, not even knowing that var1 changed...&lt;br /&gt;
&lt;br /&gt;
It is however important to detect this, and it is very easy to implement too.&lt;br /&gt;
Many situations occur that can lead to compilation errors and corrupted projects due to this environment-variable situation.&lt;br /&gt;
Problems typically occur in companies with many users and machines juggling with a set of different environments.&lt;br /&gt;
Also, a project is often setup with all the right environment variables, but then users want to later on simply open a given project without worrying what environment variables were used to set it up, keeping these in the .ecp file would allow for &amp;quot;simply double-click the .ecp file to open a project&amp;quot; kind of thing.&lt;br /&gt;
&lt;br /&gt;
The following suggestion should allow to take care of this problem elegantly.&lt;br /&gt;
&lt;br /&gt;
* When a compilation is initiated, the 'env vars' list in the project settings file is empty&lt;br /&gt;
* The following steps would be implemented in an 'initial pass' (before degree 6) by the compiler&lt;br /&gt;
* Each time the compile encounters an env var in the .ecf file (and only there), it looks at what was previously present in the .ecp:&lt;br /&gt;
** if the env var is used for the first time (not yet defined in the .ecp) then set it in the .ecp&lt;br /&gt;
** if the env var was already there, then compare it:&lt;br /&gt;
*** if the current env var value is equal to the one stored in the .ecp, then it's good, just continue compilation&lt;br /&gt;
*** if they differ, then remember they differed and remeber both values&lt;br /&gt;
** do the above for all env vars refered to in the .ecf&lt;br /&gt;
* Now at the end of this &amp;quot;initial pass&amp;quot; we have a set of &amp;quot;differing&amp;quot; env vars&lt;br /&gt;
** if the set is empty, go on to degree 6 as usual&lt;br /&gt;
** if the set is not empty, then proceed as follows (2 different situations)&lt;br /&gt;
*** in GUI mode, popup a modal dialog showing the differences and asking the user whether it's OK to continue (a nice touch would be to let the user choose which version to use for each env var, old or new version)&lt;br /&gt;
*** in batch mode, 2 different cases&lt;br /&gt;
**** abort compilation if for example a -strict flag is specified on the command line&lt;br /&gt;
**** continue compilation with a warning listing the diffs otherwise&lt;br /&gt;
* Apply the same logic for the &amp;quot;hostname&amp;quot; and &amp;quot;username&amp;quot; info in the .ecp file (also before degree 6)&lt;br /&gt;
** if the project is being opened on a different machine than the one that created the last .ecp:&lt;br /&gt;
*** popup the warning dialog, asking the user whether it's OK to continue opening the project or not&lt;br /&gt;
*** in batch mode:&lt;br /&gt;
**** fail if -strict is specified&lt;br /&gt;
**** warn otherwise&lt;br /&gt;
* If the compilation proceeds (either because user said OK, or because -strict was not specified), overwrite the info in the .ecp with the new values&lt;br /&gt;
* The same logic could be applied to other pieces of info in the .ecp (such as project path etc.. some users open their projects from local folders such as C:\projects on Windows, as well as UNC folders such as \\MACHINE\projects, sometimes at the same time!)&lt;br /&gt;
&lt;br /&gt;
=== Handling projects being opened several times at once ===&lt;br /&gt;
Typically, if the same project (same EIFGENs) is opened several times (from different machines for example) at once, there's a risk of the project getting corrputed&lt;br /&gt;
There is a very simple way to handle this problem elegantly:&lt;br /&gt;
* create a file in /&amp;lt;project path&amp;gt;/EIFGENs/&amp;lt;target&amp;gt;/ec.lock as soon as the project is open and put the following info in it:&lt;br /&gt;
** the estudio version&lt;br /&gt;
** the hostname and username opening the project&lt;br /&gt;
** the date and time when it was opened&lt;br /&gt;
** the &amp;quot;process_id&amp;quot; of the compiler opening the project (and creating this .lock file)&lt;br /&gt;
* delete this file as soon as the project is closed (ie, the batch job exits, or the user closes the IDE)&lt;br /&gt;
* if the compiler crashes and doesn't get the chance to close and delete this file, it's OK&lt;br /&gt;
* if when opening the project the file already exists, then 2 situations:&lt;br /&gt;
** in batch mode:&lt;br /&gt;
*** exit immediately with an error saying that the &amp;quot;ec.lock&amp;quot; file needs to be deleted (either manually or by closing the other running process) before the project can be opened in batch mode&lt;br /&gt;
** in GUI mode:&lt;br /&gt;
*** popup a dialog asking the user what to do, the user has the following info and choices:&lt;br /&gt;
*** the popup shows which user/host/date has the project opened&lt;br /&gt;
*** &amp;quot;Open read-only&amp;quot; - allows the user to open the project without the capability to compile it (as to avoid corrupting the project)&lt;br /&gt;
*** &amp;quot;Open anyway, I know it's not open&amp;quot; - this option deletes the .lock file and recreates it (this would typically happen if the compiler crashed and did not get a chance to delete this .lock file)&lt;br /&gt;
*** &amp;quot;Cancel&amp;quot; project opening operation&lt;br /&gt;
&lt;br /&gt;
Suggested format for this .lock file is also XML, here's an example of such a file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;lock&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		date=&amp;quot;2006/05/28 17:56:27&amp;quot;&lt;br /&gt;
		pid=&amp;quot;2451&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The hostname and username info has an obvious added value (one knows who has the project open and where)&lt;br /&gt;
The 'process_id' info would allow third-party Eiffel project management tools to &amp;quot;communicate&amp;quot; eventually with the ec.exe process that has the project open in the future, or kill the process, or change its priority etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project lock file&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_LOCK&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio that created the .lock file&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the .lock file was created&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the .lock file was created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	date: STRING&lt;br /&gt;
			-- Date when .lock file was created&lt;br /&gt;
			-- Maybe this does not need to be an attribute...&lt;br /&gt;
			-- The creation date of the file itself should give same info anyway&lt;br /&gt;
&lt;br /&gt;
	pid: INTEGER&lt;br /&gt;
			-- Process id of the process that created this lock file&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Command-line arguments for 'ec' and 'estudio' ===&lt;br /&gt;
'ec' and 'estudio' should accept similar command line arguments for coherence&lt;br /&gt;
* To create a project, user must provide 2 arguments: -project_path and -config&lt;br /&gt;
* To simply open a project, the user provides -project argument&lt;br /&gt;
&lt;br /&gt;
==== 'ec' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
;-strict&lt;br /&gt;
:Flag indicating whether environment settings should match accross compilations&lt;br /&gt;
:If not specified, compiler issues a warning if environment variables modified since last compilation&lt;br /&gt;
:If specified, compiler aborts with an error listing mismatching environment variables&lt;br /&gt;
&lt;br /&gt;
* Command line arguments -config and -project_path must be specified together for project creation, when these 2 arguments are provided:&lt;br /&gt;
** a new .ecp is always created (existing .ecp is deleted and recreated)&lt;br /&gt;
** any existing EIFGENs is deleted prior to compilation&lt;br /&gt;
** EIFGENs folder is stored in same 'project_path' folder as the .ecp&lt;br /&gt;
** users can choose a different path for the EIFGENs folder either by:&lt;br /&gt;
*** creating a .ecp file themselves&lt;br /&gt;
*** using the graphical IDE, which could allow for such customization (ec.exe in batch mode does not)&lt;br /&gt;
* -project is used to open an alrady compiled once project&lt;br /&gt;
* the pair [-project_path, -config] is exclusive with -project (users can not specify the -project along with -project_path or -config)&lt;br /&gt;
* -target is always optional and may be provided for both project creation or project opening&lt;br /&gt;
* -strict makes sense only for project opening&lt;br /&gt;
&lt;br /&gt;
==== 'estudio' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
&lt;br /&gt;
Similar rules as above apply.&lt;br /&gt;
The graphical IDE should ask questions to user only if something left unspecified.&lt;br /&gt;
&lt;br /&gt;
==== Scenarios ====&lt;br /&gt;
* Create a new project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
estudio -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Open an existing project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project /projects/sample/sample.ecp -freeze -c_compile&lt;br /&gt;
estudio -project /project/sample/sample.ecp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecp file is equivalent to &amp;lt;code&amp;gt;estudio -project &amp;lt;ecp&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecf file is handled like so:&lt;br /&gt;
** if a .ecp file with same name as the .ecf is present in same folder, open the .ecp file in that same folder&lt;br /&gt;
** otherwise, prompt the user to choose which .ecp file to use&lt;br /&gt;
*** list all recently compiled projects that could match&lt;br /&gt;
*** allow user to 'browse' to .ecp location&lt;br /&gt;
*** allow user to create a new project out of the .ecp file&lt;br /&gt;
&lt;br /&gt;
=== Pseudo-code algorithm ===&lt;br /&gt;
* .ecp files are processed once when the project is opened (before first degree 6)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
if arguments.project_path or arguments.config then&lt;br /&gt;
	if arguments.project then&lt;br /&gt;
		abort (&amp;quot;specify either -project or [-project_path + -config]&amp;quot;)&lt;br /&gt;
	elseif not arguments.project_path then&lt;br /&gt;
		abort (&amp;quot;missing -project_path argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	elsief not arguments.config then&lt;br /&gt;
		abort (&amp;quot;missing -config argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	create_new_project (arguments.project_path, arguments.config)&lt;br /&gt;
elseif arguments.project then&lt;br /&gt;
	if arguments.project.extension = &amp;quot;ecp&amp;quot; then&lt;br /&gt;
		open_project (arguments.project)&lt;br /&gt;
	elseif arguments.project.extension = &amp;quot;epr&amp;quot; then&lt;br /&gt;
		convert_old_epr (arguments.project)&lt;br /&gt;
	else&lt;br /&gt;
		abort (&amp;quot;Unsupported project file&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
else&lt;br /&gt;
	?&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
create_new_project (a_project_path, a_config: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		--create new .ecp file&lt;br /&gt;
		--delete EIFGENs if present&lt;br /&gt;
		open_project (created_ecp_file.path)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
open_project (a_ecp_path: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		create ecp.make (a_ecp_path)&lt;br /&gt;
		--check that associated .ecf file exists&lt;br /&gt;
		--go through .ecf file and list all environment variables it uses&lt;br /&gt;
		--go through all env vars used and:&lt;br /&gt;
			--get their 'old' value from .ecp (if any)&lt;br /&gt;
			--get their 'new' current value (given by shell)&lt;br /&gt;
			if var.is_mismatch then&lt;br /&gt;
				mismatches.extend (var)&lt;br /&gt;
			end&lt;br /&gt;
		--apply similar comparison for ecp.host and ecp.username&lt;br /&gt;
		if not mismatches.is_empty then&lt;br /&gt;
			if gui_mode then&lt;br /&gt;
				-- Show mismatches to user and ask him to pick the correct values, and allow him to cancel compilation altogether&lt;br /&gt;
			elseif arguments.strict then&lt;br /&gt;
				abort (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			else&lt;br /&gt;
				warn (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		--create or update .ecp file, store 'new' env vars values&lt;br /&gt;
		--check that EIFGENs exists, if not create it&lt;br /&gt;
		--create .lock file&lt;br /&gt;
		--project is opened, we may start compiling it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3084</id>
		<title>ProposalProjectFiles</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3084"/>
				<updated>2006-05-30T06:57:53Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: /* Pseudo-code algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Configuration]]&lt;br /&gt;
[[Category:EiffelStudio]]&lt;br /&gt;
[[Category:Compiler]]&lt;br /&gt;
[[Category:Projects]]&lt;br /&gt;
== Rationale ==&lt;br /&gt;
Currently, 5.7 offers the following status on project files:&lt;br /&gt;
* a .ecf file describes the Eiffel system to compile, without any compiled-project specific info (see [[Configuration]])&lt;br /&gt;
* .ecf files used to be called .acex, but this has been abandoned in favor of the .ecf extension&lt;br /&gt;
* compiled-project specific info is stored in a .user file in the same folder as the .ecf&lt;br /&gt;
* the .user file resides in the same folder as the corresponding .ecf&lt;br /&gt;
* the .user file is a stored object of type USER_OPTIONS&lt;br /&gt;
* [[ConfigurationMigration]] page describes how .ace files are migrated to the new .ecf format, and gives some info on the compiled-project files structure&lt;br /&gt;
* a folder called '''EIFGENs''' holds all the files representing a compiled project&lt;br /&gt;
* the .user file contains the path to the EIFGENs folder&lt;br /&gt;
* it is possible to have the .ecf and .user files in another folder than the one containing the EIFGENs (but it is not possible to share the same .user file for different users and machines)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are some limitations to the current implementation&lt;br /&gt;
* the .ecf file can not be used from a network share (the .user file will contain info relative to the machine that performed the compilation, like a path to the EIFGENs folder that is meaningful only from the machine that created the project)&lt;br /&gt;
* if the .ecf file is not in the same folder as the EIFGENs, the .user file bounds it to that folder anyway, we might as well then fix the location of the EIFGENs folder and have it necessarily be in the same folder as the .ecf&lt;br /&gt;
* the .user file could contain more info allowing a more coherent management of Eiffel projects, the following scenarios are not handled correctly right now:&lt;br /&gt;
** a group of developers wants to share the same .ecf file, but have different compilation folders&lt;br /&gt;
** if a user compiles a project with environment variable GOBO defined for example, then closes the project, reopens it but forgets to define GOBO this time around, the compiler fails with an obscure error stating that &amp;quot;/library/kernel&amp;quot; is missing, the user has to guess that GOBO is not defined...&lt;br /&gt;
** opening the same project several times at once usually leads to project corruption, and there is no way to know whether a project is already open or not&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
* It should be possible to open any project from a file (by double-clicking on the file for example)&lt;br /&gt;
* Opening an already compiled project should restore the environment as it was when project was compiled (as much as possible, for coherence)&lt;br /&gt;
* It should be possible to instruct the compiler to recompile a project from scratch using that same file&lt;br /&gt;
* It should be possible for third party tools (other than estudio compiler itself) to work with that project description file (why not, many people could contribute tools that work with estudio projects)&lt;br /&gt;
* We consider that the situation of opening a project from estudio itself is covered no matter what we choose (estudio will always show an &amp;quot;open project&amp;quot; dialog that will list previously compiled projects and will allow to create a new project using a wizard)&lt;br /&gt;
* The interesting bits are for &amp;quot;batch&amp;quot; or &amp;quot;automated&amp;quot; project creation and compilation&lt;br /&gt;
* It should be possible to have different targets of the same project compiled with different versions of estudio, situations in which this is useful:&lt;br /&gt;
** one wants to compile a 'win32' and 'win64' version of the same project&lt;br /&gt;
** one wants to compile a 'release' and 'experimental' version of the same project using 2 different estudio deliveries&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
* a .ecf file describes an Eiffel system in general (it's equivalent to an Eiffel class)&lt;br /&gt;
* a .ecp file is also generated by the compiler holding all the other project specific info (it's equivalent to an Eiffel object - an instance of a .ecf 'class' mentioned above)&lt;br /&gt;
** the .ecp file contains all the info currently in the .user file, and more&lt;br /&gt;
** the .ecp file can be used to compile a project from scratch etc.&lt;br /&gt;
&lt;br /&gt;
=== Project structure ===&lt;br /&gt;
* .ecf file can be located anywhere, can be shared amongst users, machines, estudio versions etc.&lt;br /&gt;
* .ecp file can be located anywhere (but will reside in the folder containing the EIFGENs most of the time)&lt;br /&gt;
* .ecp file is not supposed to be shared, it's specific to a machine and to a user&lt;br /&gt;
* an EIFGENs folder can be deleted and recreated entirely from the info made available in a .ecp file&lt;br /&gt;
* an EIFGENs folder can be opened in the state it was left after last compilation from the info made available in a .ecp file&lt;br /&gt;
&lt;br /&gt;
=== The configuration file: .ecf ===&lt;br /&gt;
The .ecf file remains as is now, containing the definition of the system to compile,&lt;br /&gt;
with eventually several targets (but no information relative to an actual compilation is stored in there).&lt;br /&gt;
See [[Configuration]]&lt;br /&gt;
&lt;br /&gt;
If a user double-clicks or otherwise tries to open a project given only the .ecf file, then the following happens:&lt;br /&gt;
* in batch mode, an error is issued stating that a project can not be opened from a .ecf file&lt;br /&gt;
* in GUI mode, recently compiled projects corresponding to the .ecf are shown to the user, which has the option of selecting one of them, or browsing to the actual project location)&lt;br /&gt;
&lt;br /&gt;
=== The project file: .ecp ===&lt;br /&gt;
A .ecp file is similar to the .ecf file, but contains only project specific info.&lt;br /&gt;
It is also an XML file serialized from a set of dedicated Eiffel objects.&lt;br /&gt;
&lt;br /&gt;
A project may be opened from a .ecp file easily, since it holds all the needed info.&lt;br /&gt;
&lt;br /&gt;
An .ecp file holds all the info relative to the current compilation, this info is (exhaustively):&lt;br /&gt;
* the path to the .ecf file&lt;br /&gt;
* a list of settings per compilation target&lt;br /&gt;
* the 'last used target' (for convenience)&lt;br /&gt;
* the 'project path' containing the EIFGENs&lt;br /&gt;
* each 'compilation target' contains the following info:&lt;br /&gt;
** the name of the target&lt;br /&gt;
** the version of estudio that compiled the target&lt;br /&gt;
** the name of the machine that build the project&lt;br /&gt;
** the username of the account under which the project was built&lt;br /&gt;
** the working directory that the user chose (by default it's the folder containing the .ecp file)&lt;br /&gt;
** the last command line arguments the project was started with (in debug mode)&lt;br /&gt;
** the list of used command line arguments (for convenience)&lt;br /&gt;
** are command line arguments 'active'&lt;br /&gt;
** all the used environment variables (an environment variable is 'used' if it appears in the .ecf file)&lt;br /&gt;
&lt;br /&gt;
The .ecp file should not be a stored Eiffel object for 2 reasons:&lt;br /&gt;
* it depends on the version of storable used, and presents retrieval problems if the API of the stored object is modified&lt;br /&gt;
* if contributors want to open that storable, they have to have the right Eiffel class in their system&lt;br /&gt;
&lt;br /&gt;
==== .ecp XML structure ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;settings&lt;br /&gt;
		ecf=&amp;quot;/path/to/ecf/sample.ecf&amp;quot;&lt;br /&gt;
		last_target=&amp;quot;target1&amp;quot;&lt;br /&gt;
		project_path=&amp;quot;/projects/sample&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
	&amp;lt;target&lt;br /&gt;
		name=&amp;quot;target1&amp;quot;&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		working_directory=&amp;quot;/projects/testing&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
		&amp;lt;command_line active=&amp;quot;true&amp;quot; last=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--use this and that&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--crack a smile&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/command_line&amp;gt;&lt;br /&gt;
		&amp;lt;environment&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;ISE_EIFFEL&amp;quot; value=&amp;quot;/path/to/estudio/5.7.58953&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;GOBO&amp;quot; value=&amp;quot;/path/to/gobo&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/environment&amp;gt;&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
	&amp;lt;target name=&amp;quot;target2&amp;quot;&amp;gt;&lt;br /&gt;
		...&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ECP classes ====&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_PROJECT&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	ecf: STRING&lt;br /&gt;
			-- Path to .ecf file&lt;br /&gt;
&lt;br /&gt;
	last_target: STRING&lt;br /&gt;
			-- Name of last used target&lt;br /&gt;
 &lt;br /&gt;
	project_path: STRING&lt;br /&gt;
			-- Path to folder containing the EIFGENs generated folder&lt;br /&gt;
 &lt;br /&gt;
	targets: LIST [ECP_TARGET]&lt;br /&gt;
			-- The configuration targets.&lt;br /&gt;
 &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project target&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_TARGET&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	name: STRING&lt;br /&gt;
			-- Name of the target&lt;br /&gt;
&lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio chosen to compile the target&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the target was compiled&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the compilation took place&lt;br /&gt;
&lt;br /&gt;
	working_directory: STRING&lt;br /&gt;
			-- Working directory selected by the user&lt;br /&gt;
			-- Optional, if not specified, the working folder is the folder containing the .ecp file&lt;br /&gt;
&lt;br /&gt;
	use_arguments: BOOLEAN&lt;br /&gt;
			-- Use arguments?&lt;br /&gt;
&lt;br /&gt;
	last_argument: STRING&lt;br /&gt;
			-- Last used argument.&lt;br /&gt;
&lt;br /&gt;
	arguments: LIST [STRING]&lt;br /&gt;
			-- List of arguments used by current target&lt;br /&gt;
&lt;br /&gt;
	evironment_variables: LIST [ECP_ENVIRONMENT_VARIABLE]&lt;br /&gt;
			-- List of environment variables refered to in the .ecf file for current target&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== What does this bring us? ====&lt;br /&gt;
* it is possible to open an eiffel project from a .ecp file, with the right version of estudio, environment settings etc.&lt;br /&gt;
* is is possible to recompile a project from scratch from a .ecp file easily (all the needed info is there)&lt;br /&gt;
* if environment variables changed since the project was compiled, the user can be warned&lt;br /&gt;
&lt;br /&gt;
=== What to do with the 'environment settings' ===&lt;br /&gt;
&lt;br /&gt;
Why do we keep the 'used environment variables'? Why do they matter?&lt;br /&gt;
Typically, when compiling a project, developers refer to clusters using environment variables.&lt;br /&gt;
But what should happen if compilation1 used var1, and compilation2 uses a different value for var1?&lt;br /&gt;
Right now, nothing special happens, compilation2 simply goes on, not even knowing that var1 changed...&lt;br /&gt;
&lt;br /&gt;
It is however important to detect this, and it is very easy to implement too.&lt;br /&gt;
Many situations occur that can lead to compilation errors and corrupted projects due to this environment-variable situation.&lt;br /&gt;
Problems typically occur in companies with many users and machines juggling with a set of different environments.&lt;br /&gt;
Also, a project is often setup with all the right environment variables, but then users want to later on simply open a given project without worrying what environment variables were used to set it up, keeping these in the .ecp file would allow for &amp;quot;simply double-click the .ecp file to open a project&amp;quot; kind of thing.&lt;br /&gt;
&lt;br /&gt;
The following suggestion should allow to take care of this problem elegantly.&lt;br /&gt;
&lt;br /&gt;
* When a compilation is initiated, the 'env vars' list in the project settings file is empty&lt;br /&gt;
* The following steps would be implemented in an 'initial pass' (before degree 6) by the compiler&lt;br /&gt;
* Each time the compile encounters an env var in the .ecf file (and only there), it looks at what was previously present in the .ecp:&lt;br /&gt;
** if the env var is used for the first time (not yet defined in the .ecp) then set it in the .ecp&lt;br /&gt;
** if the env var was already there, then compare it:&lt;br /&gt;
*** if the current env var value is equal to the one stored in the .ecp, then it's good, just continue compilation&lt;br /&gt;
*** if they differ, then remember they differed and remeber both values&lt;br /&gt;
** do the above for all env vars refered to in the .ecf&lt;br /&gt;
* Now at the end of this &amp;quot;initial pass&amp;quot; we have a set of &amp;quot;differing&amp;quot; env vars&lt;br /&gt;
** if the set is empty, go on to degree 6 as usual&lt;br /&gt;
** if the set is not empty, then proceed as follows (2 different situations)&lt;br /&gt;
*** in GUI mode, popup a modal dialog showing the differences and asking the user whether it's OK to continue (a nice touch would be to let the user choose which version to use for each env var, old or new version)&lt;br /&gt;
*** in batch mode, 2 different cases&lt;br /&gt;
**** abort compilation if for example a -strict flag is specified on the command line&lt;br /&gt;
**** continue compilation with a warning listing the diffs otherwise&lt;br /&gt;
* Apply the same logic for the &amp;quot;hostname&amp;quot; and &amp;quot;username&amp;quot; info in the .ecp file (also before degree 6)&lt;br /&gt;
** if the project is being opened on a different machine than the one that created the last .ecp:&lt;br /&gt;
*** popup the warning dialog, asking the user whether it's OK to continue opening the project or not&lt;br /&gt;
*** in batch mode:&lt;br /&gt;
**** fail if -strict is specified&lt;br /&gt;
**** warn otherwise&lt;br /&gt;
* If the compilation proceeds (either because user said OK, or because -strict was not specified), overwrite the info in the .ecp with the new values&lt;br /&gt;
* The same logic could be applied to other pieces of info in the .ecp (such as project path etc.. some users open their projects from local folders such as C:\projects on Windows, as well as UNC folders such as \\MACHINE\projects, sometimes at the same time!)&lt;br /&gt;
&lt;br /&gt;
=== Handling projects being opened several times at once ===&lt;br /&gt;
Typically, if the same project (same EIFGENs) is opened several times (from different machines for example) at once, there's a risk of the project getting corrputed&lt;br /&gt;
There is a very simple way to handle this problem elegantly:&lt;br /&gt;
* create a file in /&amp;lt;project path&amp;gt;/EIFGENs/&amp;lt;target&amp;gt;/ec.lock as soon as the project is open and put the following info in it:&lt;br /&gt;
** the estudio version&lt;br /&gt;
** the hostname and username opening the project&lt;br /&gt;
** the date and time when it was opened&lt;br /&gt;
** the &amp;quot;process_id&amp;quot; of the compiler opening the project (and creating this .lock file)&lt;br /&gt;
* delete this file as soon as the project is closed (ie, the batch job exits, or the user closes the IDE)&lt;br /&gt;
* if the compiler crashes and doesn't get the chance to close and delete this file, it's OK&lt;br /&gt;
* if when opening the project the file already exists, then 2 situations:&lt;br /&gt;
** in batch mode:&lt;br /&gt;
*** exit immediately with an error saying that the &amp;quot;ec.lock&amp;quot; file needs to be deleted (either manually or by closing the other running process) before the project can be opened in batch mode&lt;br /&gt;
** in GUI mode:&lt;br /&gt;
*** popup a dialog asking the user what to do, the user has the following info and choices:&lt;br /&gt;
*** the popup shows which user/host/date has the project opened&lt;br /&gt;
*** &amp;quot;Open read-only&amp;quot; - allows the user to open the project without the capability to compile it (as to avoid corrupting the project)&lt;br /&gt;
*** &amp;quot;Open anyway, I know it's not open&amp;quot; - this option deletes the .lock file and recreates it (this would typically happen if the compiler crashed and did not get a chance to delete this .lock file)&lt;br /&gt;
*** &amp;quot;Cancel&amp;quot; project opening operation&lt;br /&gt;
&lt;br /&gt;
Suggested format for this .lock file is also XML, here's an example of such a file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;lock&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		date=&amp;quot;2006/05/28 17:56:27&amp;quot;&lt;br /&gt;
		pid=&amp;quot;2451&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The hostname and username info has an obvious added value (one knows who has the project open and where)&lt;br /&gt;
The 'process_id' info would allow third-party Eiffel project management tools to &amp;quot;communicate&amp;quot; eventually with the ec.exe process that has the project open in the future, or kill the process, or change its priority etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project lock file&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_LOCK&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio that created the .lock file&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the .lock file was created&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the .lock file was created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	date: STRING&lt;br /&gt;
			-- Date when .lock file was created&lt;br /&gt;
			-- Maybe this does not need to be an attribute...&lt;br /&gt;
			-- The creation date of the file itself should give same info anyway&lt;br /&gt;
&lt;br /&gt;
	pid: INTEGER&lt;br /&gt;
			-- Process id of the process that created this lock file&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Command-line arguments for 'ec' and 'estudio' ===&lt;br /&gt;
'ec' and 'estudio' should accept similar command line arguments for coherence&lt;br /&gt;
* To create a project, user must provide 2 arguments: -project_path and -config&lt;br /&gt;
* To simply open a project, the user provides -project argument&lt;br /&gt;
&lt;br /&gt;
==== 'ec' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
;-strict&lt;br /&gt;
:Flag indicating whether environment settings should match accross compilations&lt;br /&gt;
:If not specified, compiler issues a warning if environment variables modified since last compilation&lt;br /&gt;
:If specified, compiler aborts with an error listing mismatching environment variables&lt;br /&gt;
&lt;br /&gt;
* Command line arguments -config and -project_path must be specified together for project creation, when these 2 arguments are provided:&lt;br /&gt;
** a new .ecp is always created (existing .ecp is deleted and recreated)&lt;br /&gt;
** any existing EIFGENs is deleted prior to compilation&lt;br /&gt;
** EIFGENs folder is stored in same 'project_path' folder as the .ecp&lt;br /&gt;
** users can choose a different path for the EIFGENs folder either by:&lt;br /&gt;
*** creating a .ecp file themselves&lt;br /&gt;
*** using the graphical IDE, which could allow for such customization (ec.exe in batch mode does not)&lt;br /&gt;
* -project is used to open an alrady compiled once project&lt;br /&gt;
* the pair [-project_path, -config] is exclusive with -project (users can not specify the -project along with -project_path or -config)&lt;br /&gt;
* -target is always optional and may be provided for both project creation or project opening&lt;br /&gt;
* -strict makes sense only for project opening&lt;br /&gt;
&lt;br /&gt;
==== 'estudio' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
&lt;br /&gt;
Similar rules as above apply.&lt;br /&gt;
The graphical IDE should ask questions to user only if something left unspecified.&lt;br /&gt;
&lt;br /&gt;
==== Scenarios ====&lt;br /&gt;
* Create a new project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
estudio -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Open an existing project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project /projects/sample/sample.ecp -freeze -c_compile&lt;br /&gt;
estudio -project /project/sample/sample.ecp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecp file is equivalent to &amp;lt;code&amp;gt;estudio -project &amp;lt;ecp&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecf file is handled like so:&lt;br /&gt;
** if a .ecp file with same name as the .ecf is present in same folder, open the .ecp file in that same folder&lt;br /&gt;
** otherwise, prompt the user to choose which .ecp file to use&lt;br /&gt;
*** list all recently compiled projects that could match&lt;br /&gt;
*** allow user to 'browse' to .ecp location&lt;br /&gt;
*** allow user to create a new project out of the .ecp file&lt;br /&gt;
&lt;br /&gt;
=== Pseudo-code algorithm ===&lt;br /&gt;
* .ecp files are processed once when the project is opened (before first degree 6)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
if arguments.project_path or arguments.config then&lt;br /&gt;
	if arguments.project then&lt;br /&gt;
		abort (&amp;quot;specify either -project or [-project_path + -config]&amp;quot;)&lt;br /&gt;
	elseif not arguments.project_path then&lt;br /&gt;
		abort (&amp;quot;missing -project_path argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	elsief not arguments.config then&lt;br /&gt;
		abort (&amp;quot;missing -config argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	create_new_project (arguments.project_path, arguments.config)&lt;br /&gt;
elseif arguments.project then&lt;br /&gt;
	if arguments.project.extension = &amp;quot;ecp&amp;quot; then&lt;br /&gt;
		open_project (arguments.project)&lt;br /&gt;
	elseif arguments.project.extension = &amp;quot;epr&amp;quot; then&lt;br /&gt;
		convert_old_epr (arguments.project)&lt;br /&gt;
	else&lt;br /&gt;
		abort (&amp;quot;Unsupported project file&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
else&lt;br /&gt;
	?&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
create_new_project (a_project_path, a_config: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		--create new .ecp file&lt;br /&gt;
		--delete EIFGENs if present&lt;br /&gt;
		open_project (created_ecp_file.path)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
open_project (a_ecp_path: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		create ecp.make (a_ecp_path)&lt;br /&gt;
		--check that associated .ecf file exists&lt;br /&gt;
		--go through .ecf file and list all environment variables it uses&lt;br /&gt;
		--go through all env vars used and:&lt;br /&gt;
			--get their 'old' value from .ecp (if any)&lt;br /&gt;
			--get their 'new' current value (given by shell)&lt;br /&gt;
			if var.is_mismatch then&lt;br /&gt;
				mismatches.extend (var)&lt;br /&gt;
			end&lt;br /&gt;
		--apply similar comparison for ecp.host and ecp.username&lt;br /&gt;
		if not mismatches.is_empty then&lt;br /&gt;
			if gui_mode then&lt;br /&gt;
				-- Show mismatches to user and ask him to pick the correct values, and allow him to cancel compilation altogether&lt;br /&gt;
			elseif arguments.strict then&lt;br /&gt;
				abort (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			else&lt;br /&gt;
				warn (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		--create or update .ecp file, store 'new' env vars values&lt;br /&gt;
		--check that EIFGENs exists, if not create it&lt;br /&gt;
		--create .lock file&lt;br /&gt;
		--project is opened, we may start compiling it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3083</id>
		<title>ProposalProjectFiles</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3083"/>
				<updated>2006-05-30T06:44:01Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: /* Pseudo-code algorithm */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Configuration]]&lt;br /&gt;
[[Category:EiffelStudio]]&lt;br /&gt;
[[Category:Compiler]]&lt;br /&gt;
[[Category:Projects]]&lt;br /&gt;
== Rationale ==&lt;br /&gt;
Currently, 5.7 offers the following status on project files:&lt;br /&gt;
* a .ecf file describes the Eiffel system to compile, without any compiled-project specific info (see [[Configuration]])&lt;br /&gt;
* .ecf files used to be called .acex, but this has been abandoned in favor of the .ecf extension&lt;br /&gt;
* compiled-project specific info is stored in a .user file in the same folder as the .ecf&lt;br /&gt;
* the .user file resides in the same folder as the corresponding .ecf&lt;br /&gt;
* the .user file is a stored object of type USER_OPTIONS&lt;br /&gt;
* [[ConfigurationMigration]] page describes how .ace files are migrated to the new .ecf format, and gives some info on the compiled-project files structure&lt;br /&gt;
* a folder called '''EIFGENs''' holds all the files representing a compiled project&lt;br /&gt;
* the .user file contains the path to the EIFGENs folder&lt;br /&gt;
* it is possible to have the .ecf and .user files in another folder than the one containing the EIFGENs (but it is not possible to share the same .user file for different users and machines)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are some limitations to the current implementation&lt;br /&gt;
* the .ecf file can not be used from a network share (the .user file will contain info relative to the machine that performed the compilation, like a path to the EIFGENs folder that is meaningful only from the machine that created the project)&lt;br /&gt;
* if the .ecf file is not in the same folder as the EIFGENs, the .user file bounds it to that folder anyway, we might as well then fix the location of the EIFGENs folder and have it necessarily be in the same folder as the .ecf&lt;br /&gt;
* the .user file could contain more info allowing a more coherent management of Eiffel projects, the following scenarios are not handled correctly right now:&lt;br /&gt;
** a group of developers wants to share the same .ecf file, but have different compilation folders&lt;br /&gt;
** if a user compiles a project with environment variable GOBO defined for example, then closes the project, reopens it but forgets to define GOBO this time around, the compiler fails with an obscure error stating that &amp;quot;/library/kernel&amp;quot; is missing, the user has to guess that GOBO is not defined...&lt;br /&gt;
** opening the same project several times at once usually leads to project corruption, and there is no way to know whether a project is already open or not&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
* It should be possible to open any project from a file (by double-clicking on the file for example)&lt;br /&gt;
* Opening an already compiled project should restore the environment as it was when project was compiled (as much as possible, for coherence)&lt;br /&gt;
* It should be possible to instruct the compiler to recompile a project from scratch using that same file&lt;br /&gt;
* It should be possible for third party tools (other than estudio compiler itself) to work with that project description file (why not, many people could contribute tools that work with estudio projects)&lt;br /&gt;
* We consider that the situation of opening a project from estudio itself is covered no matter what we choose (estudio will always show an &amp;quot;open project&amp;quot; dialog that will list previously compiled projects and will allow to create a new project using a wizard)&lt;br /&gt;
* The interesting bits are for &amp;quot;batch&amp;quot; or &amp;quot;automated&amp;quot; project creation and compilation&lt;br /&gt;
* It should be possible to have different targets of the same project compiled with different versions of estudio, situations in which this is useful:&lt;br /&gt;
** one wants to compile a 'win32' and 'win64' version of the same project&lt;br /&gt;
** one wants to compile a 'release' and 'experimental' version of the same project using 2 different estudio deliveries&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
* a .ecf file describes an Eiffel system in general (it's equivalent to an Eiffel class)&lt;br /&gt;
* a .ecp file is also generated by the compiler holding all the other project specific info (it's equivalent to an Eiffel object - an instance of a .ecf 'class' mentioned above)&lt;br /&gt;
** the .ecp file contains all the info currently in the .user file, and more&lt;br /&gt;
** the .ecp file can be used to compile a project from scratch etc.&lt;br /&gt;
&lt;br /&gt;
=== Project structure ===&lt;br /&gt;
* .ecf file can be located anywhere, can be shared amongst users, machines, estudio versions etc.&lt;br /&gt;
* .ecp file can be located anywhere (but will reside in the folder containing the EIFGENs most of the time)&lt;br /&gt;
* .ecp file is not supposed to be shared, it's specific to a machine and to a user&lt;br /&gt;
* an EIFGENs folder can be deleted and recreated entirely from the info made available in a .ecp file&lt;br /&gt;
* an EIFGENs folder can be opened in the state it was left after last compilation from the info made available in a .ecp file&lt;br /&gt;
&lt;br /&gt;
=== The configuration file: .ecf ===&lt;br /&gt;
The .ecf file remains as is now, containing the definition of the system to compile,&lt;br /&gt;
with eventually several targets (but no information relative to an actual compilation is stored in there).&lt;br /&gt;
See [[Configuration]]&lt;br /&gt;
&lt;br /&gt;
If a user double-clicks or otherwise tries to open a project given only the .ecf file, then the following happens:&lt;br /&gt;
* in batch mode, an error is issued stating that a project can not be opened from a .ecf file&lt;br /&gt;
* in GUI mode, recently compiled projects corresponding to the .ecf are shown to the user, which has the option of selecting one of them, or browsing to the actual project location)&lt;br /&gt;
&lt;br /&gt;
=== The project file: .ecp ===&lt;br /&gt;
A .ecp file is similar to the .ecf file, but contains only project specific info.&lt;br /&gt;
It is also an XML file serialized from a set of dedicated Eiffel objects.&lt;br /&gt;
&lt;br /&gt;
A project may be opened from a .ecp file easily, since it holds all the needed info.&lt;br /&gt;
&lt;br /&gt;
An .ecp file holds all the info relative to the current compilation, this info is (exhaustively):&lt;br /&gt;
* the path to the .ecf file&lt;br /&gt;
* a list of settings per compilation target&lt;br /&gt;
* the 'last used target' (for convenience)&lt;br /&gt;
* the 'project path' containing the EIFGENs&lt;br /&gt;
* each 'compilation target' contains the following info:&lt;br /&gt;
** the name of the target&lt;br /&gt;
** the version of estudio that compiled the target&lt;br /&gt;
** the name of the machine that build the project&lt;br /&gt;
** the username of the account under which the project was built&lt;br /&gt;
** the working directory that the user chose (by default it's the folder containing the .ecp file)&lt;br /&gt;
** the last command line arguments the project was started with (in debug mode)&lt;br /&gt;
** the list of used command line arguments (for convenience)&lt;br /&gt;
** are command line arguments 'active'&lt;br /&gt;
** all the used environment variables (an environment variable is 'used' if it appears in the .ecf file)&lt;br /&gt;
&lt;br /&gt;
The .ecp file should not be a stored Eiffel object for 2 reasons:&lt;br /&gt;
* it depends on the version of storable used, and presents retrieval problems if the API of the stored object is modified&lt;br /&gt;
* if contributors want to open that storable, they have to have the right Eiffel class in their system&lt;br /&gt;
&lt;br /&gt;
==== .ecp XML structure ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;settings&lt;br /&gt;
		ecf=&amp;quot;/path/to/ecf/sample.ecf&amp;quot;&lt;br /&gt;
		last_target=&amp;quot;target1&amp;quot;&lt;br /&gt;
		project_path=&amp;quot;/projects/sample&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
	&amp;lt;target&lt;br /&gt;
		name=&amp;quot;target1&amp;quot;&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		working_directory=&amp;quot;/projects/testing&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
		&amp;lt;command_line active=&amp;quot;true&amp;quot; last=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--use this and that&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--crack a smile&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/command_line&amp;gt;&lt;br /&gt;
		&amp;lt;environment&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;ISE_EIFFEL&amp;quot; value=&amp;quot;/path/to/estudio/5.7.58953&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;GOBO&amp;quot; value=&amp;quot;/path/to/gobo&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/environment&amp;gt;&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
	&amp;lt;target name=&amp;quot;target2&amp;quot;&amp;gt;&lt;br /&gt;
		...&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ECP classes ====&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_PROJECT&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	ecf: STRING&lt;br /&gt;
			-- Path to .ecf file&lt;br /&gt;
&lt;br /&gt;
	last_target: STRING&lt;br /&gt;
			-- Name of last used target&lt;br /&gt;
 &lt;br /&gt;
	project_path: STRING&lt;br /&gt;
			-- Path to folder containing the EIFGENs generated folder&lt;br /&gt;
 &lt;br /&gt;
	targets: LIST [ECP_TARGET]&lt;br /&gt;
			-- The configuration targets.&lt;br /&gt;
 &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project target&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_TARGET&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	name: STRING&lt;br /&gt;
			-- Name of the target&lt;br /&gt;
&lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio chosen to compile the target&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the target was compiled&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the compilation took place&lt;br /&gt;
&lt;br /&gt;
	working_directory: STRING&lt;br /&gt;
			-- Working directory selected by the user&lt;br /&gt;
			-- Optional, if not specified, the working folder is the folder containing the .ecp file&lt;br /&gt;
&lt;br /&gt;
	use_arguments: BOOLEAN&lt;br /&gt;
			-- Use arguments?&lt;br /&gt;
&lt;br /&gt;
	last_argument: STRING&lt;br /&gt;
			-- Last used argument.&lt;br /&gt;
&lt;br /&gt;
	arguments: LIST [STRING]&lt;br /&gt;
			-- List of arguments used by current target&lt;br /&gt;
&lt;br /&gt;
	evironment_variables: LIST [ECP_ENVIRONMENT_VARIABLE]&lt;br /&gt;
			-- List of environment variables refered to in the .ecf file for current target&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== What does this bring us? ====&lt;br /&gt;
* it is possible to open an eiffel project from a .ecp file, with the right version of estudio, environment settings etc.&lt;br /&gt;
* is is possible to recompile a project from scratch from a .ecp file easily (all the needed info is there)&lt;br /&gt;
* if environment variables changed since the project was compiled, the user can be warned&lt;br /&gt;
&lt;br /&gt;
=== What to do with the 'environment settings' ===&lt;br /&gt;
&lt;br /&gt;
Why do we keep the 'used environment variables'? Why do they matter?&lt;br /&gt;
Typically, when compiling a project, developers refer to clusters using environment variables.&lt;br /&gt;
But what should happen if compilation1 used var1, and compilation2 uses a different value for var1?&lt;br /&gt;
Right now, nothing special happens, compilation2 simply goes on, not even knowing that var1 changed...&lt;br /&gt;
&lt;br /&gt;
It is however important to detect this, and it is very easy to implement too.&lt;br /&gt;
Many situations occur that can lead to compilation errors and corrupted projects due to this environment-variable situation.&lt;br /&gt;
Problems typically occur in companies with many users and machines juggling with a set of different environments.&lt;br /&gt;
Also, a project is often setup with all the right environment variables, but then users want to later on simply open a given project without worrying what environment variables were used to set it up, keeping these in the .ecp file would allow for &amp;quot;simply double-click the .ecp file to open a project&amp;quot; kind of thing.&lt;br /&gt;
&lt;br /&gt;
The following suggestion should allow to take care of this problem elegantly.&lt;br /&gt;
&lt;br /&gt;
* When a compilation is initiated, the 'env vars' list in the project settings file is empty&lt;br /&gt;
* The following steps would be implemented in an 'initial pass' (before degree 6) by the compiler&lt;br /&gt;
* Each time the compile encounters an env var in the .ecf file (and only there), it looks at what was previously present in the .ecp:&lt;br /&gt;
** if the env var is used for the first time (not yet defined in the .ecp) then set it in the .ecp&lt;br /&gt;
** if the env var was already there, then compare it:&lt;br /&gt;
*** if the current env var value is equal to the one stored in the .ecp, then it's good, just continue compilation&lt;br /&gt;
*** if they differ, then remember they differed and remeber both values&lt;br /&gt;
** do the above for all env vars refered to in the .ecf&lt;br /&gt;
* Now at the end of this &amp;quot;initial pass&amp;quot; we have a set of &amp;quot;differing&amp;quot; env vars&lt;br /&gt;
** if the set is empty, go on to degree 6 as usual&lt;br /&gt;
** if the set is not empty, then proceed as follows (2 different situations)&lt;br /&gt;
*** in GUI mode, popup a modal dialog showing the differences and asking the user whether it's OK to continue (a nice touch would be to let the user choose which version to use for each env var, old or new version)&lt;br /&gt;
*** in batch mode, 2 different cases&lt;br /&gt;
**** abort compilation if for example a -strict flag is specified on the command line&lt;br /&gt;
**** continue compilation with a warning listing the diffs otherwise&lt;br /&gt;
* Apply the same logic for the &amp;quot;hostname&amp;quot; and &amp;quot;username&amp;quot; info in the .ecp file (also before degree 6)&lt;br /&gt;
** if the project is being opened on a different machine than the one that created the last .ecp:&lt;br /&gt;
*** popup the warning dialog, asking the user whether it's OK to continue opening the project or not&lt;br /&gt;
*** in batch mode:&lt;br /&gt;
**** fail if -strict is specified&lt;br /&gt;
**** warn otherwise&lt;br /&gt;
* If the compilation proceeds (either because user said OK, or because -strict was not specified), overwrite the info in the .ecp with the new values&lt;br /&gt;
* The same logic could be applied to other pieces of info in the .ecp (such as project path etc.. some users open their projects from local folders such as C:\projects on Windows, as well as UNC folders such as \\MACHINE\projects, sometimes at the same time!)&lt;br /&gt;
&lt;br /&gt;
=== Handling projects being opened several times at once ===&lt;br /&gt;
Typically, if the same project (same EIFGENs) is opened several times (from different machines for example) at once, there's a risk of the project getting corrputed&lt;br /&gt;
There is a very simple way to handle this problem elegantly:&lt;br /&gt;
* create a file in /&amp;lt;project path&amp;gt;/EIFGENs/&amp;lt;target&amp;gt;/ec.lock as soon as the project is open and put the following info in it:&lt;br /&gt;
** the estudio version&lt;br /&gt;
** the hostname and username opening the project&lt;br /&gt;
** the date and time when it was opened&lt;br /&gt;
** the &amp;quot;process_id&amp;quot; of the compiler opening the project (and creating this .lock file)&lt;br /&gt;
* delete this file as soon as the project is closed (ie, the batch job exits, or the user closes the IDE)&lt;br /&gt;
* if the compiler crashes and doesn't get the chance to close and delete this file, it's OK&lt;br /&gt;
* if when opening the project the file already exists, then 2 situations:&lt;br /&gt;
** in batch mode:&lt;br /&gt;
*** exit immediately with an error saying that the &amp;quot;ec.lock&amp;quot; file needs to be deleted (either manually or by closing the other running process) before the project can be opened in batch mode&lt;br /&gt;
** in GUI mode:&lt;br /&gt;
*** popup a dialog asking the user what to do, the user has the following info and choices:&lt;br /&gt;
*** the popup shows which user/host/date has the project opened&lt;br /&gt;
*** &amp;quot;Open read-only&amp;quot; - allows the user to open the project without the capability to compile it (as to avoid corrupting the project)&lt;br /&gt;
*** &amp;quot;Open anyway, I know it's not open&amp;quot; - this option deletes the .lock file and recreates it (this would typically happen if the compiler crashed and did not get a chance to delete this .lock file)&lt;br /&gt;
*** &amp;quot;Cancel&amp;quot; project opening operation&lt;br /&gt;
&lt;br /&gt;
Suggested format for this .lock file is also XML, here's an example of such a file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;lock&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		date=&amp;quot;2006/05/28 17:56:27&amp;quot;&lt;br /&gt;
		pid=&amp;quot;2451&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The hostname and username info has an obvious added value (one knows who has the project open and where)&lt;br /&gt;
The 'process_id' info would allow third-party Eiffel project management tools to &amp;quot;communicate&amp;quot; eventually with the ec.exe process that has the project open in the future, or kill the process, or change its priority etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project lock file&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_LOCK&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio that created the .lock file&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the .lock file was created&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the .lock file was created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	date: STRING&lt;br /&gt;
			-- Date when .lock file was created&lt;br /&gt;
			-- Maybe this does not need to be an attribute...&lt;br /&gt;
			-- The creation date of the file itself should give same info anyway&lt;br /&gt;
&lt;br /&gt;
	pid: INTEGER&lt;br /&gt;
			-- Process id of the process that created this lock file&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Command-line arguments for 'ec' and 'estudio' ===&lt;br /&gt;
'ec' and 'estudio' should accept similar command line arguments for coherence&lt;br /&gt;
* To create a project, user must provide 2 arguments: -project_path and -config&lt;br /&gt;
* To simply open a project, the user provides -project argument&lt;br /&gt;
&lt;br /&gt;
==== 'ec' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
;-strict&lt;br /&gt;
:Flag indicating whether environment settings should match accross compilations&lt;br /&gt;
:If not specified, compiler issues a warning if environment variables modified since last compilation&lt;br /&gt;
:If specified, compiler aborts with an error listing mismatching environment variables&lt;br /&gt;
&lt;br /&gt;
* Command line arguments -config and -project_path must be specified together for project creation, when these 2 arguments are provided:&lt;br /&gt;
** a new .ecp is always created (existing .ecp is deleted and recreated)&lt;br /&gt;
** any existing EIFGENs is deleted prior to compilation&lt;br /&gt;
** EIFGENs folder is stored in same 'project_path' folder as the .ecp&lt;br /&gt;
** users can choose a different path for the EIFGENs folder either by:&lt;br /&gt;
*** creating a .ecp file themselves&lt;br /&gt;
*** using the graphical IDE, which could allow for such customization (ec.exe in batch mode does not)&lt;br /&gt;
* -project is used to open an alrady compiled once project&lt;br /&gt;
* the pair [-project_path, -config] is exclusive with -project (users can not specify the -project along with -project_path or -config)&lt;br /&gt;
* -target is always optional and may be provided for both project creation or project opening&lt;br /&gt;
* -strict makes sense only for project opening&lt;br /&gt;
&lt;br /&gt;
==== 'estudio' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
&lt;br /&gt;
Similar rules as above apply.&lt;br /&gt;
The graphical IDE should ask questions to user only if something left unspecified.&lt;br /&gt;
&lt;br /&gt;
==== Scenarios ====&lt;br /&gt;
* Create a new project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
estudio -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Open an existing project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project /projects/sample/sample.ecp -freeze -c_compile&lt;br /&gt;
estudio -project /project/sample/sample.ecp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecp file is equivalent to &amp;lt;code&amp;gt;estudio -project &amp;lt;ecp&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecf file is handled like so:&lt;br /&gt;
** if a .ecp file with same name as the .ecf is present in same folder, open the .ecp file in that same folder&lt;br /&gt;
** otherwise, prompt the user to choose which .ecp file to use&lt;br /&gt;
*** list all recently compiled projects that could match&lt;br /&gt;
*** allow user to 'browse' to .ecp location&lt;br /&gt;
*** allow user to create a new project out of the .ecp file&lt;br /&gt;
&lt;br /&gt;
=== Pseudo-code algorithm ===&lt;br /&gt;
* .ecp files are processed once when the project is opened (before first degree 6)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
if arguments.project_path or arguments.config then&lt;br /&gt;
	if arguments.project then&lt;br /&gt;
		abort (&amp;quot;specify either -project or [-project_path + -config]&amp;quot;)&lt;br /&gt;
	elseif not arguments.project_path then&lt;br /&gt;
		abort (&amp;quot;missing -project_path argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	elsief not arguments.config then&lt;br /&gt;
		abort (&amp;quot;missing -config argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	create_new_project (arguments.project_path, arguments.config)&lt;br /&gt;
elseif arguments.project then&lt;br /&gt;
	if arguments.project.extension = &amp;quot;ecp&amp;quot; then&lt;br /&gt;
		open_project (arguments.project)&lt;br /&gt;
	elseif arguments.project.extension = &amp;quot;epr&amp;quot; then&lt;br /&gt;
		convert_old_epr (arguments.project)&lt;br /&gt;
	else&lt;br /&gt;
		abort (&amp;quot;Unsupported project file&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
else&lt;br /&gt;
	?&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
create_new_project (a_project_path, a_config: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		--create new .ecp file&lt;br /&gt;
		--delete EIFGENs if present&lt;br /&gt;
		open_project (created_ecp_file.path)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
open_project (a_ecp_path: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		create ecp.make (a_ecp_path)&lt;br /&gt;
		--check that associated .ecf file exists&lt;br /&gt;
		--go through .ecf file and list all environment variables it uses&lt;br /&gt;
		--go through all env vars used and:&lt;br /&gt;
			--get their 'old' value from .ecp (if any)&lt;br /&gt;
			--get their 'new' current value (given by shell)&lt;br /&gt;
			if var.is_mismatch then&lt;br /&gt;
				mismatches.extend (var)&lt;br /&gt;
			end&lt;br /&gt;
		-- apply similar comparison for ecp.host and ecp.username&lt;br /&gt;
		if not mismatches.is_empty then&lt;br /&gt;
			if gui_mode then&lt;br /&gt;
				-- Show mismatches to user and ask him to pick the correct values, and allow him to cancel compilation altogether&lt;br /&gt;
			elseif arguments.strict then&lt;br /&gt;
				abort (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			else&lt;br /&gt;
				warn (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		--check that EIFGENs exists, if not create it&lt;br /&gt;
		--create .lock file&lt;br /&gt;
		--project is opened, we may start compiling it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3082</id>
		<title>ProposalProjectFiles</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3082"/>
				<updated>2006-05-30T06:36:17Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: /* Specification */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Configuration]]&lt;br /&gt;
[[Category:EiffelStudio]]&lt;br /&gt;
[[Category:Compiler]]&lt;br /&gt;
[[Category:Projects]]&lt;br /&gt;
== Rationale ==&lt;br /&gt;
Currently, 5.7 offers the following status on project files:&lt;br /&gt;
* a .ecf file describes the Eiffel system to compile, without any compiled-project specific info (see [[Configuration]])&lt;br /&gt;
* .ecf files used to be called .acex, but this has been abandoned in favor of the .ecf extension&lt;br /&gt;
* compiled-project specific info is stored in a .user file in the same folder as the .ecf&lt;br /&gt;
* the .user file resides in the same folder as the corresponding .ecf&lt;br /&gt;
* the .user file is a stored object of type USER_OPTIONS&lt;br /&gt;
* [[ConfigurationMigration]] page describes how .ace files are migrated to the new .ecf format, and gives some info on the compiled-project files structure&lt;br /&gt;
* a folder called '''EIFGENs''' holds all the files representing a compiled project&lt;br /&gt;
* the .user file contains the path to the EIFGENs folder&lt;br /&gt;
* it is possible to have the .ecf and .user files in another folder than the one containing the EIFGENs (but it is not possible to share the same .user file for different users and machines)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are some limitations to the current implementation&lt;br /&gt;
* the .ecf file can not be used from a network share (the .user file will contain info relative to the machine that performed the compilation, like a path to the EIFGENs folder that is meaningful only from the machine that created the project)&lt;br /&gt;
* if the .ecf file is not in the same folder as the EIFGENs, the .user file bounds it to that folder anyway, we might as well then fix the location of the EIFGENs folder and have it necessarily be in the same folder as the .ecf&lt;br /&gt;
* the .user file could contain more info allowing a more coherent management of Eiffel projects, the following scenarios are not handled correctly right now:&lt;br /&gt;
** a group of developers wants to share the same .ecf file, but have different compilation folders&lt;br /&gt;
** if a user compiles a project with environment variable GOBO defined for example, then closes the project, reopens it but forgets to define GOBO this time around, the compiler fails with an obscure error stating that &amp;quot;/library/kernel&amp;quot; is missing, the user has to guess that GOBO is not defined...&lt;br /&gt;
** opening the same project several times at once usually leads to project corruption, and there is no way to know whether a project is already open or not&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
* It should be possible to open any project from a file (by double-clicking on the file for example)&lt;br /&gt;
* Opening an already compiled project should restore the environment as it was when project was compiled (as much as possible, for coherence)&lt;br /&gt;
* It should be possible to instruct the compiler to recompile a project from scratch using that same file&lt;br /&gt;
* It should be possible for third party tools (other than estudio compiler itself) to work with that project description file (why not, many people could contribute tools that work with estudio projects)&lt;br /&gt;
* We consider that the situation of opening a project from estudio itself is covered no matter what we choose (estudio will always show an &amp;quot;open project&amp;quot; dialog that will list previously compiled projects and will allow to create a new project using a wizard)&lt;br /&gt;
* The interesting bits are for &amp;quot;batch&amp;quot; or &amp;quot;automated&amp;quot; project creation and compilation&lt;br /&gt;
* It should be possible to have different targets of the same project compiled with different versions of estudio, situations in which this is useful:&lt;br /&gt;
** one wants to compile a 'win32' and 'win64' version of the same project&lt;br /&gt;
** one wants to compile a 'release' and 'experimental' version of the same project using 2 different estudio deliveries&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
* a .ecf file describes an Eiffel system in general (it's equivalent to an Eiffel class)&lt;br /&gt;
* a .ecp file is also generated by the compiler holding all the other project specific info (it's equivalent to an Eiffel object - an instance of a .ecf 'class' mentioned above)&lt;br /&gt;
** the .ecp file contains all the info currently in the .user file, and more&lt;br /&gt;
** the .ecp file can be used to compile a project from scratch etc.&lt;br /&gt;
&lt;br /&gt;
=== Project structure ===&lt;br /&gt;
* .ecf file can be located anywhere, can be shared amongst users, machines, estudio versions etc.&lt;br /&gt;
* .ecp file can be located anywhere (but will reside in the folder containing the EIFGENs most of the time)&lt;br /&gt;
* .ecp file is not supposed to be shared, it's specific to a machine and to a user&lt;br /&gt;
* an EIFGENs folder can be deleted and recreated entirely from the info made available in a .ecp file&lt;br /&gt;
* an EIFGENs folder can be opened in the state it was left after last compilation from the info made available in a .ecp file&lt;br /&gt;
&lt;br /&gt;
=== The configuration file: .ecf ===&lt;br /&gt;
The .ecf file remains as is now, containing the definition of the system to compile,&lt;br /&gt;
with eventually several targets (but no information relative to an actual compilation is stored in there).&lt;br /&gt;
See [[Configuration]]&lt;br /&gt;
&lt;br /&gt;
If a user double-clicks or otherwise tries to open a project given only the .ecf file, then the following happens:&lt;br /&gt;
* in batch mode, an error is issued stating that a project can not be opened from a .ecf file&lt;br /&gt;
* in GUI mode, recently compiled projects corresponding to the .ecf are shown to the user, which has the option of selecting one of them, or browsing to the actual project location)&lt;br /&gt;
&lt;br /&gt;
=== The project file: .ecp ===&lt;br /&gt;
A .ecp file is similar to the .ecf file, but contains only project specific info.&lt;br /&gt;
It is also an XML file serialized from a set of dedicated Eiffel objects.&lt;br /&gt;
&lt;br /&gt;
A project may be opened from a .ecp file easily, since it holds all the needed info.&lt;br /&gt;
&lt;br /&gt;
An .ecp file holds all the info relative to the current compilation, this info is (exhaustively):&lt;br /&gt;
* the path to the .ecf file&lt;br /&gt;
* a list of settings per compilation target&lt;br /&gt;
* the 'last used target' (for convenience)&lt;br /&gt;
* the 'project path' containing the EIFGENs&lt;br /&gt;
* each 'compilation target' contains the following info:&lt;br /&gt;
** the name of the target&lt;br /&gt;
** the version of estudio that compiled the target&lt;br /&gt;
** the name of the machine that build the project&lt;br /&gt;
** the username of the account under which the project was built&lt;br /&gt;
** the working directory that the user chose (by default it's the folder containing the .ecp file)&lt;br /&gt;
** the last command line arguments the project was started with (in debug mode)&lt;br /&gt;
** the list of used command line arguments (for convenience)&lt;br /&gt;
** are command line arguments 'active'&lt;br /&gt;
** all the used environment variables (an environment variable is 'used' if it appears in the .ecf file)&lt;br /&gt;
&lt;br /&gt;
The .ecp file should not be a stored Eiffel object for 2 reasons:&lt;br /&gt;
* it depends on the version of storable used, and presents retrieval problems if the API of the stored object is modified&lt;br /&gt;
* if contributors want to open that storable, they have to have the right Eiffel class in their system&lt;br /&gt;
&lt;br /&gt;
==== .ecp XML structure ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;settings&lt;br /&gt;
		ecf=&amp;quot;/path/to/ecf/sample.ecf&amp;quot;&lt;br /&gt;
		last_target=&amp;quot;target1&amp;quot;&lt;br /&gt;
		project_path=&amp;quot;/projects/sample&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
	&amp;lt;target&lt;br /&gt;
		name=&amp;quot;target1&amp;quot;&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		working_directory=&amp;quot;/projects/testing&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
		&amp;lt;command_line active=&amp;quot;true&amp;quot; last=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--use this and that&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--crack a smile&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/command_line&amp;gt;&lt;br /&gt;
		&amp;lt;environment&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;ISE_EIFFEL&amp;quot; value=&amp;quot;/path/to/estudio/5.7.58953&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;GOBO&amp;quot; value=&amp;quot;/path/to/gobo&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/environment&amp;gt;&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
	&amp;lt;target name=&amp;quot;target2&amp;quot;&amp;gt;&lt;br /&gt;
		...&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ECP classes ====&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_PROJECT&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	ecf: STRING&lt;br /&gt;
			-- Path to .ecf file&lt;br /&gt;
&lt;br /&gt;
	last_target: STRING&lt;br /&gt;
			-- Name of last used target&lt;br /&gt;
 &lt;br /&gt;
	project_path: STRING&lt;br /&gt;
			-- Path to folder containing the EIFGENs generated folder&lt;br /&gt;
 &lt;br /&gt;
	targets: LIST [ECP_TARGET]&lt;br /&gt;
			-- The configuration targets.&lt;br /&gt;
 &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project target&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_TARGET&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	name: STRING&lt;br /&gt;
			-- Name of the target&lt;br /&gt;
&lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio chosen to compile the target&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the target was compiled&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the compilation took place&lt;br /&gt;
&lt;br /&gt;
	working_directory: STRING&lt;br /&gt;
			-- Working directory selected by the user&lt;br /&gt;
			-- Optional, if not specified, the working folder is the folder containing the .ecp file&lt;br /&gt;
&lt;br /&gt;
	use_arguments: BOOLEAN&lt;br /&gt;
			-- Use arguments?&lt;br /&gt;
&lt;br /&gt;
	last_argument: STRING&lt;br /&gt;
			-- Last used argument.&lt;br /&gt;
&lt;br /&gt;
	arguments: LIST [STRING]&lt;br /&gt;
			-- List of arguments used by current target&lt;br /&gt;
&lt;br /&gt;
	evironment_variables: LIST [ECP_ENVIRONMENT_VARIABLE]&lt;br /&gt;
			-- List of environment variables refered to in the .ecf file for current target&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== What does this bring us? ====&lt;br /&gt;
* it is possible to open an eiffel project from a .ecp file, with the right version of estudio, environment settings etc.&lt;br /&gt;
* is is possible to recompile a project from scratch from a .ecp file easily (all the needed info is there)&lt;br /&gt;
* if environment variables changed since the project was compiled, the user can be warned&lt;br /&gt;
&lt;br /&gt;
=== What to do with the 'environment settings' ===&lt;br /&gt;
&lt;br /&gt;
Why do we keep the 'used environment variables'? Why do they matter?&lt;br /&gt;
Typically, when compiling a project, developers refer to clusters using environment variables.&lt;br /&gt;
But what should happen if compilation1 used var1, and compilation2 uses a different value for var1?&lt;br /&gt;
Right now, nothing special happens, compilation2 simply goes on, not even knowing that var1 changed...&lt;br /&gt;
&lt;br /&gt;
It is however important to detect this, and it is very easy to implement too.&lt;br /&gt;
Many situations occur that can lead to compilation errors and corrupted projects due to this environment-variable situation.&lt;br /&gt;
Problems typically occur in companies with many users and machines juggling with a set of different environments.&lt;br /&gt;
Also, a project is often setup with all the right environment variables, but then users want to later on simply open a given project without worrying what environment variables were used to set it up, keeping these in the .ecp file would allow for &amp;quot;simply double-click the .ecp file to open a project&amp;quot; kind of thing.&lt;br /&gt;
&lt;br /&gt;
The following suggestion should allow to take care of this problem elegantly.&lt;br /&gt;
&lt;br /&gt;
* When a compilation is initiated, the 'env vars' list in the project settings file is empty&lt;br /&gt;
* The following steps would be implemented in an 'initial pass' (before degree 6) by the compiler&lt;br /&gt;
* Each time the compile encounters an env var in the .ecf file (and only there), it looks at what was previously present in the .ecp:&lt;br /&gt;
** if the env var is used for the first time (not yet defined in the .ecp) then set it in the .ecp&lt;br /&gt;
** if the env var was already there, then compare it:&lt;br /&gt;
*** if the current env var value is equal to the one stored in the .ecp, then it's good, just continue compilation&lt;br /&gt;
*** if they differ, then remember they differed and remeber both values&lt;br /&gt;
** do the above for all env vars refered to in the .ecf&lt;br /&gt;
* Now at the end of this &amp;quot;initial pass&amp;quot; we have a set of &amp;quot;differing&amp;quot; env vars&lt;br /&gt;
** if the set is empty, go on to degree 6 as usual&lt;br /&gt;
** if the set is not empty, then proceed as follows (2 different situations)&lt;br /&gt;
*** in GUI mode, popup a modal dialog showing the differences and asking the user whether it's OK to continue (a nice touch would be to let the user choose which version to use for each env var, old or new version)&lt;br /&gt;
*** in batch mode, 2 different cases&lt;br /&gt;
**** abort compilation if for example a -strict flag is specified on the command line&lt;br /&gt;
**** continue compilation with a warning listing the diffs otherwise&lt;br /&gt;
* Apply the same logic for the &amp;quot;hostname&amp;quot; and &amp;quot;username&amp;quot; info in the .ecp file (also before degree 6)&lt;br /&gt;
** if the project is being opened on a different machine than the one that created the last .ecp:&lt;br /&gt;
*** popup the warning dialog, asking the user whether it's OK to continue opening the project or not&lt;br /&gt;
*** in batch mode:&lt;br /&gt;
**** fail if -strict is specified&lt;br /&gt;
**** warn otherwise&lt;br /&gt;
* If the compilation proceeds (either because user said OK, or because -strict was not specified), overwrite the info in the .ecp with the new values&lt;br /&gt;
* The same logic could be applied to other pieces of info in the .ecp (such as project path etc.. some users open their projects from local folders such as C:\projects on Windows, as well as UNC folders such as \\MACHINE\projects, sometimes at the same time!)&lt;br /&gt;
&lt;br /&gt;
=== Handling projects being opened several times at once ===&lt;br /&gt;
Typically, if the same project (same EIFGENs) is opened several times (from different machines for example) at once, there's a risk of the project getting corrputed&lt;br /&gt;
There is a very simple way to handle this problem elegantly:&lt;br /&gt;
* create a file in /&amp;lt;project path&amp;gt;/EIFGENs/&amp;lt;target&amp;gt;/ec.lock as soon as the project is open and put the following info in it:&lt;br /&gt;
** the estudio version&lt;br /&gt;
** the hostname and username opening the project&lt;br /&gt;
** the date and time when it was opened&lt;br /&gt;
** the &amp;quot;process_id&amp;quot; of the compiler opening the project (and creating this .lock file)&lt;br /&gt;
* delete this file as soon as the project is closed (ie, the batch job exits, or the user closes the IDE)&lt;br /&gt;
* if the compiler crashes and doesn't get the chance to close and delete this file, it's OK&lt;br /&gt;
* if when opening the project the file already exists, then 2 situations:&lt;br /&gt;
** in batch mode:&lt;br /&gt;
*** exit immediately with an error saying that the &amp;quot;ec.lock&amp;quot; file needs to be deleted (either manually or by closing the other running process) before the project can be opened in batch mode&lt;br /&gt;
** in GUI mode:&lt;br /&gt;
*** popup a dialog asking the user what to do, the user has the following info and choices:&lt;br /&gt;
*** the popup shows which user/host/date has the project opened&lt;br /&gt;
*** &amp;quot;Open read-only&amp;quot; - allows the user to open the project without the capability to compile it (as to avoid corrupting the project)&lt;br /&gt;
*** &amp;quot;Open anyway, I know it's not open&amp;quot; - this option deletes the .lock file and recreates it (this would typically happen if the compiler crashed and did not get a chance to delete this .lock file)&lt;br /&gt;
*** &amp;quot;Cancel&amp;quot; project opening operation&lt;br /&gt;
&lt;br /&gt;
Suggested format for this .lock file is also XML, here's an example of such a file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;lock&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		date=&amp;quot;2006/05/28 17:56:27&amp;quot;&lt;br /&gt;
		pid=&amp;quot;2451&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The hostname and username info has an obvious added value (one knows who has the project open and where)&lt;br /&gt;
The 'process_id' info would allow third-party Eiffel project management tools to &amp;quot;communicate&amp;quot; eventually with the ec.exe process that has the project open in the future, or kill the process, or change its priority etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project lock file&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_LOCK&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio that created the .lock file&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the .lock file was created&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the .lock file was created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	date: STRING&lt;br /&gt;
			-- Date when .lock file was created&lt;br /&gt;
			-- Maybe this does not need to be an attribute...&lt;br /&gt;
			-- The creation date of the file itself should give same info anyway&lt;br /&gt;
&lt;br /&gt;
	pid: INTEGER&lt;br /&gt;
			-- Process id of the process that created this lock file&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Command-line arguments for 'ec' and 'estudio' ===&lt;br /&gt;
'ec' and 'estudio' should accept similar command line arguments for coherence&lt;br /&gt;
* To create a project, user must provide 2 arguments: -project_path and -config&lt;br /&gt;
* To simply open a project, the user provides -project argument&lt;br /&gt;
&lt;br /&gt;
==== 'ec' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
;-strict&lt;br /&gt;
:Flag indicating whether environment settings should match accross compilations&lt;br /&gt;
:If not specified, compiler issues a warning if environment variables modified since last compilation&lt;br /&gt;
:If specified, compiler aborts with an error listing mismatching environment variables&lt;br /&gt;
&lt;br /&gt;
* Command line arguments -config and -project_path must be specified together for project creation, when these 2 arguments are provided:&lt;br /&gt;
** a new .ecp is always created (existing .ecp is deleted and recreated)&lt;br /&gt;
** any existing EIFGENs is deleted prior to compilation&lt;br /&gt;
** EIFGENs folder is stored in same 'project_path' folder as the .ecp&lt;br /&gt;
** users can choose a different path for the EIFGENs folder either by:&lt;br /&gt;
*** creating a .ecp file themselves&lt;br /&gt;
*** using the graphical IDE, which could allow for such customization (ec.exe in batch mode does not)&lt;br /&gt;
* -project is used to open an alrady compiled once project&lt;br /&gt;
* the pair [-project_path, -config] is exclusive with -project (users can not specify the -project along with -project_path or -config)&lt;br /&gt;
* -target is always optional and may be provided for both project creation or project opening&lt;br /&gt;
* -strict makes sense only for project opening&lt;br /&gt;
&lt;br /&gt;
==== 'estudio' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
&lt;br /&gt;
Similar rules as above apply.&lt;br /&gt;
The graphical IDE should ask questions to user only if something left unspecified.&lt;br /&gt;
&lt;br /&gt;
==== Scenarios ====&lt;br /&gt;
* Create a new project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
estudio -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Open an existing project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project /projects/sample/sample.ecp -freeze -c_compile&lt;br /&gt;
estudio -project /project/sample/sample.ecp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecp file is equivalent to &amp;lt;code&amp;gt;estudio -project &amp;lt;ecp&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecf file is handled like so:&lt;br /&gt;
** if a .ecp file with same name as the .ecf is present in same folder, open the .ecp file in that same folder&lt;br /&gt;
** otherwise, prompt the user to choose which .ecp file to use&lt;br /&gt;
*** list all recently compiled projects that could match&lt;br /&gt;
*** allow user to 'browse' to .ecp location&lt;br /&gt;
*** allow user to create a new project out of the .ecp file&lt;br /&gt;
&lt;br /&gt;
=== Pseudo-code algorithm ===&lt;br /&gt;
* .ecp files are processed once when the project is opened (before first degree 6)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
if arguments.project_path or arguments.config then&lt;br /&gt;
	if arguments.project then&lt;br /&gt;
		abort (&amp;quot;specify either -project or [-project_path + -config]&amp;quot;)&lt;br /&gt;
	elseif not arguments.project_path then&lt;br /&gt;
		abort (&amp;quot;missing -project_path argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	elsief not arguments.config then&lt;br /&gt;
		abort (&amp;quot;missing -config argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	create_new_project (arguments.project_path, arguments.config)&lt;br /&gt;
elseif arguments.project then&lt;br /&gt;
	if arguments.project.extension = &amp;quot;ecp&amp;quot; then&lt;br /&gt;
		open_project (arguments.project)&lt;br /&gt;
	elseif arguments.project.extension = &amp;quot;epr&amp;quot; then&lt;br /&gt;
		convert_old_epr (arguments.project)&lt;br /&gt;
	else&lt;br /&gt;
		abort (&amp;quot;Unsupported project file&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
else&lt;br /&gt;
	?&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
create_new_project (a_project_path, a_config: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		--create new .ecp file&lt;br /&gt;
		--delete EIFGENs if present&lt;br /&gt;
		open_project (created_ecp_file.path)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
open_project (a_ecp_path: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		create ecp.make (a_ecp_path)&lt;br /&gt;
		--check that associated .ecf file exists&lt;br /&gt;
		--go through .ecf file and list all environment variables it uses&lt;br /&gt;
		--go through all env vars used and:&lt;br /&gt;
			--get their 'old' value from .ecp (if any)&lt;br /&gt;
			--get their 'new' current value (given by shell)&lt;br /&gt;
			if var.is_mismatch then&lt;br /&gt;
				mismatches.extend (var)&lt;br /&gt;
			end&lt;br /&gt;
		if not mismatches.is_empty then&lt;br /&gt;
			if gui_mode then&lt;br /&gt;
				-- Show mismatches to user and ask him to pick the correct values, and allow him to cancel compilation altogether&lt;br /&gt;
			elseif arguments.strict then&lt;br /&gt;
				abort (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			else&lt;br /&gt;
				warn (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		--check that EIFGENs exists, if not create it&lt;br /&gt;
		--create .lock file&lt;br /&gt;
		--project is opened, we may start compiling it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3081</id>
		<title>ProposalProjectFiles</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3081"/>
				<updated>2006-05-30T06:34:58Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Configuration]]&lt;br /&gt;
[[Category:EiffelStudio]]&lt;br /&gt;
[[Category:Compiler]]&lt;br /&gt;
[[Category:Projects]]&lt;br /&gt;
== Rationale ==&lt;br /&gt;
Currently, 5.7 offers the following status on project files:&lt;br /&gt;
* a .ecf file describes the Eiffel system to compile, without any compiled-project specific info (see [[Configuration]])&lt;br /&gt;
* .ecf files used to be called .acex, but this has been abandoned in favor of the .ecf extension&lt;br /&gt;
* compiled-project specific info is stored in a .user file in the same folder as the .ecf&lt;br /&gt;
* the .user file resides in the same folder as the corresponding .ecf&lt;br /&gt;
* the .user file is a stored object of type USER_OPTIONS&lt;br /&gt;
* [[ConfigurationMigration]] page describes how .ace files are migrated to the new .ecf format, and gives some info on the compiled-project files structure&lt;br /&gt;
* a folder called '''EIFGENs''' holds all the files representing a compiled project&lt;br /&gt;
* the .user file contains the path to the EIFGENs folder&lt;br /&gt;
* it is possible to have the .ecf and .user files in another folder than the one containing the EIFGENs (but it is not possible to share the same .user file for different users and machines)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There are some limitations to the current implementation&lt;br /&gt;
* the .ecf file can not be used from a network share (the .user file will contain info relative to the machine that performed the compilation, like a path to the EIFGENs folder that is meaningful only from the machine that created the project)&lt;br /&gt;
* if the .ecf file is not in the same folder as the EIFGENs, the .user file bounds it to that folder anyway, we might as well then fix the location of the EIFGENs folder and have it necessarily be in the same folder as the .ecf&lt;br /&gt;
* the .user file could contain more info allowing a more coherent management of Eiffel projects, the following scenarios are not handled correctly right now:&lt;br /&gt;
** a group of developers wants to share the same .ecf file, but have different compilation folders&lt;br /&gt;
** if a user compiles a project with environment variable GOBO defined for example, then closes the project, reopens it but forgets to define GOBO this time around, the compiler fails with an obscure error stating that &amp;quot;/library/kernel&amp;quot; is missing, the user has to guess that GOBO is not defined...&lt;br /&gt;
** opening the same project several times at once usually leads to project corruption, and there is no way to know whether a project is already open or not&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
* It should be possible to open any project from a file (by double-clicking on the file for example)&lt;br /&gt;
* Opening an already compiled project should restore the environment as it was when project was compiled (as much as possible, for coherence)&lt;br /&gt;
* It should be possible to instruct the compiler to recompile a project from scratch using that same file&lt;br /&gt;
* It should be possible for third party tools (other than estudio compiler itself) to work with that project descrition file (why not, many people could contribute tools that work with estudio projects)&lt;br /&gt;
* We consider that the situation of opening a project from estudio itself is covered no matter what we choose (estudio will always show an &amp;quot;open project&amp;quot; dialog that will list previously compiled projects and will allow to create a new project using a wizard)&lt;br /&gt;
* The interesting bits are for &amp;quot;batch&amp;quot; or &amp;quot;automated&amp;quot; project creation and compilation&lt;br /&gt;
* It should be possible to have different targets of the same project compiled with different versions of estudio, situations in which this is useful:&lt;br /&gt;
** one wants to compile a 'win32' and 'win64' version of the same project&lt;br /&gt;
** one wants to compile a 'release' and 'experimental' version of the same project using 2 different estudio deliveries&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
* a .ecf file describes an Eiffel system in general (it's equivalent to an Eiffel class)&lt;br /&gt;
* a .ecp file is also generated by the compiler holding all the other project specific info (it's equivalent to an Eiffel object - an instance of a .ecf 'class' mentioned above)&lt;br /&gt;
** the .ecp file contains all the info currently in the .user file, and more&lt;br /&gt;
** the .ecp file can be used to compile a project from scratch etc.&lt;br /&gt;
&lt;br /&gt;
=== Project structure ===&lt;br /&gt;
* .ecf file can be located anywhere, can be shared amongst users, machines, estudio versions etc.&lt;br /&gt;
* .ecp file can be located anywhere (but will reside in the folder containing the EIFGENs most of the time)&lt;br /&gt;
* .ecp file is not supposed to be shared, it's specific to a machine and to a user&lt;br /&gt;
* an EIFGENs folder can be deleted and recreated entirely from the info made available in a .ecp file&lt;br /&gt;
* an EIFGENs folder can be opened in the state it was left after last compilation from the info made available in a .ecp file&lt;br /&gt;
&lt;br /&gt;
=== The configuration file: .ecf ===&lt;br /&gt;
The .ecf file remains as is now, containing the definition of the system to compile,&lt;br /&gt;
with eventually several targets (but no information relative to an actual compilation is stored in there).&lt;br /&gt;
See [[Configuration]]&lt;br /&gt;
&lt;br /&gt;
If a user double-clicks or otherwise tries to open a project given only the .ecf file, then the following happens:&lt;br /&gt;
* in batch mode, an error is issued stating that a project can not be opened from a .ecf file&lt;br /&gt;
* in GUI mode, recently compiled projects corresponding to the .ecf are shown to the user, which has the option of selecting one of them, or browsing to the actual project location)&lt;br /&gt;
&lt;br /&gt;
=== The project file: .ecp ===&lt;br /&gt;
A .ecp file is similar to the .ecf file, but contains only project specific info.&lt;br /&gt;
It is also an XML file serialized from a set of dedicated Eiffel objects.&lt;br /&gt;
&lt;br /&gt;
A project may be opened from a .ecp file easily, since it holds all the needed info.&lt;br /&gt;
&lt;br /&gt;
An .ecp file holds all the info relative to the current compilation, this info is (exhaustively):&lt;br /&gt;
* the path to the .ecf file&lt;br /&gt;
* a list of settings per compilation target&lt;br /&gt;
* the 'last used target' (for convenience)&lt;br /&gt;
* the 'project path' containing the EIFGENs&lt;br /&gt;
* each 'compilation target' contains the following info:&lt;br /&gt;
** the name of the target&lt;br /&gt;
** the version of estudio that compiled the target&lt;br /&gt;
** the name of the machine that build the project&lt;br /&gt;
** the username of the account under which the project was built&lt;br /&gt;
** the working directory that the user chose (by default it's the folder containing the .ecp file)&lt;br /&gt;
** the last command line arguments the project was started with (in debug mode)&lt;br /&gt;
** the list of used command line arguments (for convenience)&lt;br /&gt;
** are command line arguments 'active'&lt;br /&gt;
** all the used environment variables (an environment variable is 'used' if it appears in the .ecf file)&lt;br /&gt;
&lt;br /&gt;
The .ecp file should not be a stored Eiffel object for 2 reasons:&lt;br /&gt;
* it depends on the version of storable used, and presents retrieval problems if the API of the stored object is modified&lt;br /&gt;
* if contributors want to open that storable, they have to have the right Eiffel class in their system&lt;br /&gt;
&lt;br /&gt;
==== .ecp XML structure ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;settings&lt;br /&gt;
		ecf=&amp;quot;/path/to/ecf/sample.ecf&amp;quot;&lt;br /&gt;
		last_target=&amp;quot;target1&amp;quot;&lt;br /&gt;
		project_path=&amp;quot;/projects/sample&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
	&amp;lt;target&lt;br /&gt;
		name=&amp;quot;target1&amp;quot;&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		working_directory=&amp;quot;/projects/testing&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
		&amp;lt;command_line active=&amp;quot;true&amp;quot; last=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--use this and that&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--crack a smile&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/command_line&amp;gt;&lt;br /&gt;
		&amp;lt;environment&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;ISE_EIFFEL&amp;quot; value=&amp;quot;/path/to/estudio/5.7.58953&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;GOBO&amp;quot; value=&amp;quot;/path/to/gobo&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/environment&amp;gt;&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
	&amp;lt;target name=&amp;quot;target2&amp;quot;&amp;gt;&lt;br /&gt;
		...&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ECP classes ====&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_PROJECT&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	ecf: STRING&lt;br /&gt;
			-- Path to .ecf file&lt;br /&gt;
&lt;br /&gt;
	last_target: STRING&lt;br /&gt;
			-- Name of last used target&lt;br /&gt;
 &lt;br /&gt;
	project_path: STRING&lt;br /&gt;
			-- Path to folder containing the EIFGENs generated folder&lt;br /&gt;
 &lt;br /&gt;
	targets: LIST [ECP_TARGET]&lt;br /&gt;
			-- The configuration targets.&lt;br /&gt;
 &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project target&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_TARGET&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	name: STRING&lt;br /&gt;
			-- Name of the target&lt;br /&gt;
&lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio chosen to compile the target&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the target was compiled&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the compilation took place&lt;br /&gt;
&lt;br /&gt;
	working_directory: STRING&lt;br /&gt;
			-- Working directory selected by the user&lt;br /&gt;
			-- Optional, if not specified, the working folder is the folder containing the .ecp file&lt;br /&gt;
&lt;br /&gt;
	use_arguments: BOOLEAN&lt;br /&gt;
			-- Use arguments?&lt;br /&gt;
&lt;br /&gt;
	last_argument: STRING&lt;br /&gt;
			-- Last used argument.&lt;br /&gt;
&lt;br /&gt;
	arguments: LIST [STRING]&lt;br /&gt;
			-- List of arguments used by current target&lt;br /&gt;
&lt;br /&gt;
	evironment_variables: LIST [ECP_ENVIRONMENT_VARIABLE]&lt;br /&gt;
			-- List of environment variables refered to in the .ecf file for current target&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== What does this bring us? ====&lt;br /&gt;
* it is possible to open an eiffel project from a .ecp file, with the right version of estudio, environment settings etc.&lt;br /&gt;
* is is possible to recompile a project from scratch from a .ecp file easily (all the needed info is there)&lt;br /&gt;
* if environment variables changed since the project was compiled, the user can be warned&lt;br /&gt;
&lt;br /&gt;
=== What to do with the 'environment settings' ===&lt;br /&gt;
&lt;br /&gt;
Why do we keep the 'used environment variables'? Why do they matter?&lt;br /&gt;
Typically, when compiling a project, developers refer to clusters using environment variables.&lt;br /&gt;
But what should happen if compilation1 used var1, and compilation2 uses a different value for var1?&lt;br /&gt;
Right now, nothing special happens, compilation2 simply goes on, not even knowing that var1 changed...&lt;br /&gt;
&lt;br /&gt;
It is however important to detect this, and it is very easy to implement too.&lt;br /&gt;
Many situations occur that can lead to compilation errors and corrupted projects due to this environment-variable situation.&lt;br /&gt;
Problems typically occur in companies with many users and machines juggling with a set of different environments.&lt;br /&gt;
Also, a project is often setup with all the right environment variables, but then users want to later on simply open a given project without worrying what environment variables were used to set it up, keeping these in the .ecp file would allow for &amp;quot;simply double-click the .ecp file to open a project&amp;quot; kind of thing.&lt;br /&gt;
&lt;br /&gt;
The following suggestion should allow to take care of this problem elegantly.&lt;br /&gt;
&lt;br /&gt;
* When a compilation is initiated, the 'env vars' list in the project settings file is empty&lt;br /&gt;
* The following steps would be implemented in an 'initial pass' (before degree 6) by the compiler&lt;br /&gt;
* Each time the compile encounters an env var in the .ecf file (and only there), it looks at what was previously present in the .ecp:&lt;br /&gt;
** if the env var is used for the first time (not yet defined in the .ecp) then set it in the .ecp&lt;br /&gt;
** if the env var was already there, then compare it:&lt;br /&gt;
*** if the current env var value is equal to the one stored in the .ecp, then it's good, just continue compilation&lt;br /&gt;
*** if they differ, then remember they differed and remeber both values&lt;br /&gt;
** do the above for all env vars refered to in the .ecf&lt;br /&gt;
* Now at the end of this &amp;quot;initial pass&amp;quot; we have a set of &amp;quot;differing&amp;quot; env vars&lt;br /&gt;
** if the set is empty, go on to degree 6 as usual&lt;br /&gt;
** if the set is not empty, then proceed as follows (2 different situations)&lt;br /&gt;
*** in GUI mode, popup a modal dialog showing the differences and asking the user whether it's OK to continue (a nice touch would be to let the user choose which version to use for each env var, old or new version)&lt;br /&gt;
*** in batch mode, 2 different cases&lt;br /&gt;
**** abort compilation if for example a -strict flag is specified on the command line&lt;br /&gt;
**** continue compilation with a warning listing the diffs otherwise&lt;br /&gt;
* Apply the same logic for the &amp;quot;hostname&amp;quot; and &amp;quot;username&amp;quot; info in the .ecp file (also before degree 6)&lt;br /&gt;
** if the project is being opened on a different machine than the one that created the last .ecp:&lt;br /&gt;
*** popup the warning dialog, asking the user whether it's OK to continue opening the project or not&lt;br /&gt;
*** in batch mode:&lt;br /&gt;
**** fail if -strict is specified&lt;br /&gt;
**** warn otherwise&lt;br /&gt;
* If the compilation proceeds (either because user said OK, or because -strict was not specified), overwrite the info in the .ecp with the new values&lt;br /&gt;
* The same logic could be applied to other pieces of info in the .ecp (such as project path etc.. some users open their projects from local folders such as C:\projects on Windows, as well as UNC folders such as \\MACHINE\projects, sometimes at the same time!)&lt;br /&gt;
&lt;br /&gt;
=== Handling projects being opened several times at once ===&lt;br /&gt;
Typically, if the same project (same EIFGENs) is opened several times (from different machines for example) at once, there's a risk of the project getting corrputed&lt;br /&gt;
There is a very simple way to handle this problem elegantly:&lt;br /&gt;
* create a file in /&amp;lt;project path&amp;gt;/EIFGENs/&amp;lt;target&amp;gt;/ec.lock as soon as the project is open and put the following info in it:&lt;br /&gt;
** the estudio version&lt;br /&gt;
** the hostname and username opening the project&lt;br /&gt;
** the date and time when it was opened&lt;br /&gt;
** the &amp;quot;process_id&amp;quot; of the compiler opening the project (and creating this .lock file)&lt;br /&gt;
* delete this file as soon as the project is closed (ie, the batch job exits, or the user closes the IDE)&lt;br /&gt;
* if the compiler crashes and doesn't get the chance to close and delete this file, it's OK&lt;br /&gt;
* if when opening the project the file already exists, then 2 situations:&lt;br /&gt;
** in batch mode:&lt;br /&gt;
*** exit immediately with an error saying that the &amp;quot;ec.lock&amp;quot; file needs to be deleted (either manually or by closing the other running process) before the project can be opened in batch mode&lt;br /&gt;
** in GUI mode:&lt;br /&gt;
*** popup a dialog asking the user what to do, the user has the following info and choices:&lt;br /&gt;
*** the popup shows which user/host/date has the project opened&lt;br /&gt;
*** &amp;quot;Open read-only&amp;quot; - allows the user to open the project without the capability to compile it (as to avoid corrupting the project)&lt;br /&gt;
*** &amp;quot;Open anyway, I know it's not open&amp;quot; - this option deletes the .lock file and recreates it (this would typically happen if the compiler crashed and did not get a chance to delete this .lock file)&lt;br /&gt;
*** &amp;quot;Cancel&amp;quot; project opening operation&lt;br /&gt;
&lt;br /&gt;
Suggested format for this .lock file is also XML, here's an example of such a file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;lock&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		date=&amp;quot;2006/05/28 17:56:27&amp;quot;&lt;br /&gt;
		pid=&amp;quot;2451&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The hostname and username info has an obvious added value (one knows who has the project open and where)&lt;br /&gt;
The 'process_id' info would allow third-party Eiffel project management tools to &amp;quot;communicate&amp;quot; eventually with the ec.exe process that has the project open in the future, or kill the process, or change its priority etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project lock file&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_LOCK&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio that created the .lock file&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the .lock file was created&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the .lock file was created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	date: STRING&lt;br /&gt;
			-- Date when .lock file was created&lt;br /&gt;
			-- Maybe this does not need to be an attribute...&lt;br /&gt;
			-- The creation date of the file itself should give same info anyway&lt;br /&gt;
&lt;br /&gt;
	pid: INTEGER&lt;br /&gt;
			-- Process id of the process that created this lock file&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Command-line arguments for 'ec' and 'estudio' ===&lt;br /&gt;
'ec' and 'estudio' should accept similar command line arguments for coherence&lt;br /&gt;
* To create a project, user must provide 2 arguments: -project_path and -config&lt;br /&gt;
* To simply open a project, the user provides -project argument&lt;br /&gt;
&lt;br /&gt;
==== 'ec' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
;-strict&lt;br /&gt;
:Flag indicating whether environment settings should match accross compilations&lt;br /&gt;
:If not specified, compiler issues a warning if environment variables modified since last compilation&lt;br /&gt;
:If specified, compiler aborts with an error listing mismatching environment variables&lt;br /&gt;
&lt;br /&gt;
* Command line arguments -config and -project_path must be specified together for project creation, when these 2 arguments are provided:&lt;br /&gt;
** a new .ecp is always created (existing .ecp is deleted and recreated)&lt;br /&gt;
** any existing EIFGENs is deleted prior to compilation&lt;br /&gt;
** EIFGENs folder is stored in same 'project_path' folder as the .ecp&lt;br /&gt;
** users can choose a different path for the EIFGENs folder either by:&lt;br /&gt;
*** creating a .ecp file themselves&lt;br /&gt;
*** using the graphical IDE, which could allow for such customization (ec.exe in batch mode does not)&lt;br /&gt;
* -project is used to open an alrady compiled once project&lt;br /&gt;
* the pair [-project_path, -config] is exclusive with -project (users can not specify the -project along with -project_path or -config)&lt;br /&gt;
* -target is always optional and may be provided for both project creation or project opening&lt;br /&gt;
* -strict makes sense only for project opening&lt;br /&gt;
&lt;br /&gt;
==== 'estudio' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
&lt;br /&gt;
Similar rules as above apply.&lt;br /&gt;
The graphical IDE should ask questions to user only if something left unspecified.&lt;br /&gt;
&lt;br /&gt;
==== Scenarios ====&lt;br /&gt;
* Create a new project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
estudio -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Open an existing project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project /projects/sample/sample.ecp -freeze -c_compile&lt;br /&gt;
estudio -project /project/sample/sample.ecp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecp file is equivalent to &amp;lt;code&amp;gt;estudio -project &amp;lt;ecp&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecf file is handled like so:&lt;br /&gt;
** if a .ecp file with same name as the .ecf is present in same folder, open the .ecp file in that same folder&lt;br /&gt;
** otherwise, prompt the user to choose which .ecp file to use&lt;br /&gt;
*** list all recently compiled projects that could match&lt;br /&gt;
*** allow user to 'browse' to .ecp location&lt;br /&gt;
*** allow user to create a new project out of the .ecp file&lt;br /&gt;
&lt;br /&gt;
=== Pseudo-code algorithm ===&lt;br /&gt;
* .ecp files are processed once when the project is opened (before first degree 6)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
if arguments.project_path or arguments.config then&lt;br /&gt;
	if arguments.project then&lt;br /&gt;
		abort (&amp;quot;specify either -project or [-project_path + -config]&amp;quot;)&lt;br /&gt;
	elseif not arguments.project_path then&lt;br /&gt;
		abort (&amp;quot;missing -project_path argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	elsief not arguments.config then&lt;br /&gt;
		abort (&amp;quot;missing -config argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	create_new_project (arguments.project_path, arguments.config)&lt;br /&gt;
elseif arguments.project then&lt;br /&gt;
	if arguments.project.extension = &amp;quot;ecp&amp;quot; then&lt;br /&gt;
		open_project (arguments.project)&lt;br /&gt;
	elseif arguments.project.extension = &amp;quot;epr&amp;quot; then&lt;br /&gt;
		convert_old_epr (arguments.project)&lt;br /&gt;
	else&lt;br /&gt;
		abort (&amp;quot;Unsupported project file&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
else&lt;br /&gt;
	?&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
create_new_project (a_project_path, a_config: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		--create new .ecp file&lt;br /&gt;
		--delete EIFGENs if present&lt;br /&gt;
		open_project (created_ecp_file.path)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
open_project (a_ecp_path: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		create ecp.make (a_ecp_path)&lt;br /&gt;
		--check that associated .ecf file exists&lt;br /&gt;
		--go through .ecf file and list all environment variables it uses&lt;br /&gt;
		--go through all env vars used and:&lt;br /&gt;
			--get their 'old' value from .ecp (if any)&lt;br /&gt;
			--get their 'new' current value (given by shell)&lt;br /&gt;
			if var.is_mismatch then&lt;br /&gt;
				mismatches.extend (var)&lt;br /&gt;
			end&lt;br /&gt;
		if not mismatches.is_empty then&lt;br /&gt;
			if gui_mode then&lt;br /&gt;
				-- Show mismatches to user and ask him to pick the correct values, and allow him to cancel compilation altogether&lt;br /&gt;
			elseif arguments.strict then&lt;br /&gt;
				abort (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			else&lt;br /&gt;
				warn (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		--check that EIFGENs exists, if not create it&lt;br /&gt;
		--create .lock file&lt;br /&gt;
		--project is opened, we may start compiling it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3080</id>
		<title>ProposalProjectFiles</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3080"/>
				<updated>2006-05-30T06:28:31Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Configuration]]&lt;br /&gt;
[[Category:EiffelStudio]]&lt;br /&gt;
[[Category:Compiler]]&lt;br /&gt;
[[Category:Projects]]&lt;br /&gt;
== Rationale ==&lt;br /&gt;
Currently, 5.7 offers the following status on project files:&lt;br /&gt;
* a .ecf file describes the Eiffel system to compile, without any compiled-project specific info (see [[Configuration]])&lt;br /&gt;
* .ecf files used to be called .acex, but this has been abandoned in favor of the .ecf extension&lt;br /&gt;
* compiled-project specific info is stored in a .user file in the same folder as the .ecf&lt;br /&gt;
* the .user file resides in the same folder as the corresponding .ecf&lt;br /&gt;
* the .user file is a stored object of type USER_OPTIONS&lt;br /&gt;
* [[ConfigurationMigration]] page describes how .ace files are migrated to the new .ecf format, and gives some info on the compiled-project files structure&lt;br /&gt;
* a folder called '''EIFGENs''' holds all the files representing a compiled project&lt;br /&gt;
* the .user file contains the path to the EIFGENs folder&lt;br /&gt;
* it is possible then to delete the EIFGENs folder and recompile the project from scratch with the info from the .ecf and .user files&lt;br /&gt;
* it is also possible to open the project using the .ecf file (as long as the .user file is also present)&lt;br /&gt;
* it is possible to have the .ecf and .user files in another folder than the one containing the EIFGENs (but it is not possible to share the same .user file for different users and machines)&lt;br /&gt;
&lt;br /&gt;
There are several limitations to this approach&lt;br /&gt;
* the .ecf file can not be used from a network share (the .user file will contain info relative to the machine that performed the compilation, like a path to the EIFGENs folder that is meaningful only from the machine that created the project)&lt;br /&gt;
* if the .ecf file is not in the same folder as the EIFGENs, the .user file bounds it to that folder anyway, we might as well then fix the location of the EIFGENs folder and have it necessarily be in the same folder as the .ecf&lt;br /&gt;
* the .user file could contain more info allowing a more coherent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
* It should be possible to open any project from a file (by double-clicking on the file for example)&lt;br /&gt;
* Opening an already compiled project should restore the environment as it was when project was compiled (as much as possible, for coherence)&lt;br /&gt;
* It should be possible to instruct the compiler to recompile a project from scratch using that same file&lt;br /&gt;
* It should be possible for third party tools (other than estudio compiler itself) to work with that project descrition file (why not, many people could contribute tools that work with estudio projects)&lt;br /&gt;
* We consider that the situation of opening a project from estudio itself is covered no matter what we choose (estudio will always show an &amp;quot;open project&amp;quot; dialog that will list previously compiled projects and will allow to create a new project using a wizard)&lt;br /&gt;
* The interesting bits are for &amp;quot;batch&amp;quot; or &amp;quot;automated&amp;quot; project creation and compilation&lt;br /&gt;
* It should be possible to have different targets of the same project compiled with different versions of estudio, situations in which this is useful:&lt;br /&gt;
** one wants to compile a 'win32' and 'win64' version of the same project&lt;br /&gt;
** one wants to compile a 'release' and 'experimental' version of the same project using 2 different estudio deliveries&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
* a .ecf file describes an Eiffel system in general (it's equivalent to an Eiffel class)&lt;br /&gt;
* a .ecp file is also generated by the compiler holding all the other project specific info (it's equivalent to an Eiffel object - an instance of a .ecf 'class' mentioned above)&lt;br /&gt;
** the .ecp file contains all the info currently in the .user file, and more&lt;br /&gt;
** the .ecp file can be used to compile a project from scratch etc.&lt;br /&gt;
&lt;br /&gt;
=== Project structure ===&lt;br /&gt;
* .ecf file can be located anywhere, can be shared amongst users, machines, estudio versions etc.&lt;br /&gt;
* .ecp file can be located anywhere (but will reside in the folder containing the EIFGENs most of the time)&lt;br /&gt;
* .ecp file is not supposed to be shared, it's specific to a machine and to a user&lt;br /&gt;
* an EIFGENs folder can be deleted and recreated entirely from the info made available in a .ecp file&lt;br /&gt;
* an EIFGENs folder can be opened in the state it was left after last compilation from the info made available in a .ecp file&lt;br /&gt;
&lt;br /&gt;
=== The configuration file: .ecf ===&lt;br /&gt;
The .ecf file remains as is now, containing the definition of the system to compile,&lt;br /&gt;
with eventually several targets (but no information relative to an actual compilation is stored in there).&lt;br /&gt;
See [[Configuration]]&lt;br /&gt;
&lt;br /&gt;
If a user double-clicks or otherwise tries to open a project given only the .ecf file, then the following happens:&lt;br /&gt;
* in batch mode, an error is issued stating that a project can not be opened from a .ecf file&lt;br /&gt;
* in GUI mode, recently compiled projects corresponding to the .ecf are shown to the user, which has the option of selecting one of them, or browsing to the actual project location)&lt;br /&gt;
&lt;br /&gt;
=== The project file: .ecp ===&lt;br /&gt;
A .ecp file is similar to the .ecf file, but contains only project specific info.&lt;br /&gt;
It is also an XML file serialized from a set of dedicated Eiffel objects.&lt;br /&gt;
&lt;br /&gt;
A project may be opened from a .ecp file easily, since it holds all the needed info.&lt;br /&gt;
&lt;br /&gt;
An .ecp file holds all the info relative to the current compilation, this info is (exhaustively):&lt;br /&gt;
* the path to the .ecf file&lt;br /&gt;
* a list of settings per compilation target&lt;br /&gt;
* the 'last used target' (for convenience)&lt;br /&gt;
* the 'project path' containing the EIFGENs&lt;br /&gt;
* each 'compilation target' contains the following info:&lt;br /&gt;
** the name of the target&lt;br /&gt;
** the version of estudio that compiled the target&lt;br /&gt;
** the name of the machine that build the project&lt;br /&gt;
** the username of the account under which the project was built&lt;br /&gt;
** the working directory that the user chose (by default it's the folder containing the .ecp file)&lt;br /&gt;
** the last command line arguments the project was started with (in debug mode)&lt;br /&gt;
** the list of used command line arguments (for convenience)&lt;br /&gt;
** are command line arguments 'active'&lt;br /&gt;
** all the used environment variables (an environment variable is 'used' if it appears in the .ecf file)&lt;br /&gt;
&lt;br /&gt;
The .ecp file should not be a stored Eiffel object for 2 reasons:&lt;br /&gt;
* it depends on the version of storable used, and presents retrieval problems if the API of the stored object is modified&lt;br /&gt;
* if contributors want to open that storable, they have to have the right Eiffel class in their system&lt;br /&gt;
&lt;br /&gt;
==== .ecp XML structure ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;settings&lt;br /&gt;
		ecf=&amp;quot;/path/to/ecf/sample.ecf&amp;quot;&lt;br /&gt;
		last_target=&amp;quot;target1&amp;quot;&lt;br /&gt;
		project_path=&amp;quot;/projects/sample&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
	&amp;lt;target&lt;br /&gt;
		name=&amp;quot;target1&amp;quot;&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		working_directory=&amp;quot;/projects/testing&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
		&amp;lt;command_line active=&amp;quot;true&amp;quot; last=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--use this and that&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--crack a smile&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/command_line&amp;gt;&lt;br /&gt;
		&amp;lt;environment&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;ISE_EIFFEL&amp;quot; value=&amp;quot;/path/to/estudio/5.7.58953&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;GOBO&amp;quot; value=&amp;quot;/path/to/gobo&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/environment&amp;gt;&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
	&amp;lt;target name=&amp;quot;target2&amp;quot;&amp;gt;&lt;br /&gt;
		...&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ECP classes ====&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_PROJECT&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	ecf: STRING&lt;br /&gt;
			-- Path to .ecf file&lt;br /&gt;
&lt;br /&gt;
	last_target: STRING&lt;br /&gt;
			-- Name of last used target&lt;br /&gt;
 &lt;br /&gt;
	project_path: STRING&lt;br /&gt;
			-- Path to folder containing the EIFGENs generated folder&lt;br /&gt;
 &lt;br /&gt;
	targets: LIST [ECP_TARGET]&lt;br /&gt;
			-- The configuration targets.&lt;br /&gt;
 &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project target&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_TARGET&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	name: STRING&lt;br /&gt;
			-- Name of the target&lt;br /&gt;
&lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio chosen to compile the target&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the target was compiled&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the compilation took place&lt;br /&gt;
&lt;br /&gt;
	working_directory: STRING&lt;br /&gt;
			-- Working directory selected by the user&lt;br /&gt;
			-- Optional, if not specified, the working folder is the folder containing the .ecp file&lt;br /&gt;
&lt;br /&gt;
	use_arguments: BOOLEAN&lt;br /&gt;
			-- Use arguments?&lt;br /&gt;
&lt;br /&gt;
	last_argument: STRING&lt;br /&gt;
			-- Last used argument.&lt;br /&gt;
&lt;br /&gt;
	arguments: LIST [STRING]&lt;br /&gt;
			-- List of arguments used by current target&lt;br /&gt;
&lt;br /&gt;
	evironment_variables: LIST [ECP_ENVIRONMENT_VARIABLE]&lt;br /&gt;
			-- List of environment variables refered to in the .ecf file for current target&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== What does this bring us? ====&lt;br /&gt;
* it is possible to open an eiffel project from a .ecp file, with the right version of estudio, environment settings etc.&lt;br /&gt;
* is is possible to recompile a project from scratch from a .ecp file easily (all the needed info is there)&lt;br /&gt;
* if environment variables changed since the project was compiled, the user can be warned&lt;br /&gt;
&lt;br /&gt;
=== What to do with the 'environment settings' ===&lt;br /&gt;
&lt;br /&gt;
Why do we keep the 'used environment variables'? Why do they matter?&lt;br /&gt;
Typically, when compiling a project, developers refer to clusters using environment variables.&lt;br /&gt;
But what should happen if compilation1 used var1, and compilation2 uses a different value for var1?&lt;br /&gt;
Right now, nothing special happens, compilation2 simply goes on, not even knowing that var1 changed...&lt;br /&gt;
&lt;br /&gt;
It is however important to detect this, and it is very easy to implement too.&lt;br /&gt;
Many situations occur that can lead to compilation errors and corrupted projects due to this environment-variable situation.&lt;br /&gt;
Problems typically occur in companies with many users and machines juggling with a set of different environments.&lt;br /&gt;
Also, a project is often setup with all the right environment variables, but then users want to later on simply open a given project without worrying what environment variables were used to set it up, keeping these in the .ecp file would allow for &amp;quot;simply double-click the .ecp file to open a project&amp;quot; kind of thing.&lt;br /&gt;
&lt;br /&gt;
The following suggestion should allow to take care of this problem elegantly.&lt;br /&gt;
&lt;br /&gt;
* When a compilation is initiated, the 'env vars' list in the project settings file is empty&lt;br /&gt;
* The following steps would be implemented in an 'initial pass' (before degree 6) by the compiler&lt;br /&gt;
* Each time the compile encounters an env var in the .ecf file (and only there), it looks at what was previously present in the .ecp:&lt;br /&gt;
** if the env var is used for the first time (not yet defined in the .ecp) then set it in the .ecp&lt;br /&gt;
** if the env var was already there, then compare it:&lt;br /&gt;
*** if the current env var value is equal to the one stored in the .ecp, then it's good, just continue compilation&lt;br /&gt;
*** if they differ, then remember they differed and remeber both values&lt;br /&gt;
** do the above for all env vars refered to in the .ecf&lt;br /&gt;
* Now at the end of this &amp;quot;initial pass&amp;quot; we have a set of &amp;quot;differing&amp;quot; env vars&lt;br /&gt;
** if the set is empty, go on to degree 6 as usual&lt;br /&gt;
** if the set is not empty, then proceed as follows (2 different situations)&lt;br /&gt;
*** in GUI mode, popup a modal dialog showing the differences and asking the user whether it's OK to continue (a nice touch would be to let the user choose which version to use for each env var, old or new version)&lt;br /&gt;
*** in batch mode, 2 different cases&lt;br /&gt;
**** abort compilation if for example a -strict flag is specified on the command line&lt;br /&gt;
**** continue compilation with a warning listing the diffs otherwise&lt;br /&gt;
* Apply the same logic for the &amp;quot;hostname&amp;quot; and &amp;quot;username&amp;quot; info in the .ecp file (also before degree 6)&lt;br /&gt;
** if the project is being opened on a different machine than the one that created the last .ecp:&lt;br /&gt;
*** popup the warning dialog, asking the user whether it's OK to continue opening the project or not&lt;br /&gt;
*** in batch mode:&lt;br /&gt;
**** fail if -strict is specified&lt;br /&gt;
**** warn otherwise&lt;br /&gt;
* If the compilation proceeds (either because user said OK, or because -strict was not specified), overwrite the info in the .ecp with the new values&lt;br /&gt;
* The same logic could be applied to other pieces of info in the .ecp (such as project path etc.. some users open their projects from local folders such as C:\projects on Windows, as well as UNC folders such as \\MACHINE\projects, sometimes at the same time!)&lt;br /&gt;
&lt;br /&gt;
=== Handling projects being opened several times at once ===&lt;br /&gt;
Typically, if the same project (same EIFGENs) is opened several times (from different machines for example) at once, there's a risk of the project getting corrputed&lt;br /&gt;
There is a very simple way to handle this problem elegantly:&lt;br /&gt;
* create a file in /&amp;lt;project path&amp;gt;/EIFGENs/&amp;lt;target&amp;gt;/ec.lock as soon as the project is open and put the following info in it:&lt;br /&gt;
** the estudio version&lt;br /&gt;
** the hostname and username opening the project&lt;br /&gt;
** the date and time when it was opened&lt;br /&gt;
** the &amp;quot;process_id&amp;quot; of the compiler opening the project (and creating this .lock file)&lt;br /&gt;
* delete this file as soon as the project is closed (ie, the batch job exits, or the user closes the IDE)&lt;br /&gt;
* if the compiler crashes and doesn't get the chance to close and delete this file, it's OK&lt;br /&gt;
* if when opening the project the file already exists, then 2 situations:&lt;br /&gt;
** in batch mode:&lt;br /&gt;
*** exit immediately with an error saying that the &amp;quot;ec.lock&amp;quot; file needs to be deleted (either manually or by closing the other running process) before the project can be opened in batch mode&lt;br /&gt;
** in GUI mode:&lt;br /&gt;
*** popup a dialog asking the user what to do, the user has the following info and choices:&lt;br /&gt;
*** the popup shows which user/host/date has the project opened&lt;br /&gt;
*** &amp;quot;Open read-only&amp;quot; - allows the user to open the project without the capability to compile it (as to avoid corrupting the project)&lt;br /&gt;
*** &amp;quot;Open anyway, I know it's not open&amp;quot; - this option deletes the .lock file and recreates it (this would typically happen if the compiler crashed and did not get a chance to delete this .lock file)&lt;br /&gt;
*** &amp;quot;Cancel&amp;quot; project opening operation&lt;br /&gt;
&lt;br /&gt;
Suggested format for this .lock file is also XML, here's an example of such a file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;lock&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		date=&amp;quot;2006/05/28 17:56:27&amp;quot;&lt;br /&gt;
		pid=&amp;quot;2451&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The hostname and username info has an obvious added value (one knows who has the project open and where)&lt;br /&gt;
The 'process_id' info would allow third-party Eiffel project management tools to &amp;quot;communicate&amp;quot; eventually with the ec.exe process that has the project open in the future, or kill the process, or change its priority etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project lock file&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_LOCK&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio that created the .lock file&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the .lock file was created&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the .lock file was created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	date: STRING&lt;br /&gt;
			-- Date when .lock file was created&lt;br /&gt;
			-- Maybe this does not need to be an attribute...&lt;br /&gt;
			-- The creation date of the file itself should give same info anyway&lt;br /&gt;
&lt;br /&gt;
	pid: INTEGER&lt;br /&gt;
			-- Process id of the process that created this lock file&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Command-line arguments for 'ec' and 'estudio' ===&lt;br /&gt;
'ec' and 'estudio' should accept similar command line arguments for coherence&lt;br /&gt;
* To create a project, user must provide 2 arguments: -project_path and -config&lt;br /&gt;
* To simply open a project, the user provides -project argument&lt;br /&gt;
&lt;br /&gt;
==== 'ec' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
;-strict&lt;br /&gt;
:Flag indicating whether environment settings should match accross compilations&lt;br /&gt;
:If not specified, compiler issues a warning if environment variables modified since last compilation&lt;br /&gt;
:If specified, compiler aborts with an error listing mismatching environment variables&lt;br /&gt;
&lt;br /&gt;
* Command line arguments -config and -project_path must be specified together for project creation, when these 2 arguments are provided:&lt;br /&gt;
** a new .ecp is always created (existing .ecp is deleted and recreated)&lt;br /&gt;
** any existing EIFGENs is deleted prior to compilation&lt;br /&gt;
** EIFGENs folder is stored in same 'project_path' folder as the .ecp&lt;br /&gt;
** users can choose a different path for the EIFGENs folder either by:&lt;br /&gt;
*** creating a .ecp file themselves&lt;br /&gt;
*** using the graphical IDE, which could allow for such customization (ec.exe in batch mode does not)&lt;br /&gt;
* -project is used to open an alrady compiled once project&lt;br /&gt;
* the pair [-project_path, -config] is exclusive with -project (users can not specify the -project along with -project_path or -config)&lt;br /&gt;
* -target is always optional and may be provided for both project creation or project opening&lt;br /&gt;
* -strict makes sense only for project opening&lt;br /&gt;
&lt;br /&gt;
==== 'estudio' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
&lt;br /&gt;
Similar rules as above apply.&lt;br /&gt;
The graphical IDE should ask questions to user only if something left unspecified.&lt;br /&gt;
&lt;br /&gt;
==== Scenarios ====&lt;br /&gt;
* Create a new project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
estudio -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Open an existing project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project /projects/sample/sample.ecp -freeze -c_compile&lt;br /&gt;
estudio -project /project/sample/sample.ecp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecp file is equivalent to &amp;lt;code&amp;gt;estudio -project &amp;lt;ecp&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecf file is handled like so:&lt;br /&gt;
** if a .ecp file with same name as the .ecf is present in same folder, open the .ecp file in that same folder&lt;br /&gt;
** otherwise, prompt the user to choose which .ecp file to use&lt;br /&gt;
*** list all recently compiled projects that could match&lt;br /&gt;
*** allow user to 'browse' to .ecp location&lt;br /&gt;
*** allow user to create a new project out of the .ecp file&lt;br /&gt;
&lt;br /&gt;
=== Pseudo-code algorithm ===&lt;br /&gt;
* .ecp files are processed once when the project is opened (before first degree 6)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
if arguments.project_path or arguments.config then&lt;br /&gt;
	if arguments.project then&lt;br /&gt;
		abort (&amp;quot;specify either -project or [-project_path + -config]&amp;quot;)&lt;br /&gt;
	elseif not arguments.project_path then&lt;br /&gt;
		abort (&amp;quot;missing -project_path argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	elsief not arguments.config then&lt;br /&gt;
		abort (&amp;quot;missing -config argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	create_new_project (arguments.project_path, arguments.config)&lt;br /&gt;
elseif arguments.project then&lt;br /&gt;
	if arguments.project.extension = &amp;quot;ecp&amp;quot; then&lt;br /&gt;
		open_project (arguments.project)&lt;br /&gt;
	elseif arguments.project.extension = &amp;quot;epr&amp;quot; then&lt;br /&gt;
		convert_old_epr (arguments.project)&lt;br /&gt;
	else&lt;br /&gt;
		abort (&amp;quot;Unsupported project file&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
else&lt;br /&gt;
	?&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
create_new_project (a_project_path, a_config: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		--create new .ecp file&lt;br /&gt;
		--delete EIFGENs if present&lt;br /&gt;
		open_project (created_ecp_file.path)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
open_project (a_ecp_path: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		create ecp.make (a_ecp_path)&lt;br /&gt;
		--check that associated .ecf file exists&lt;br /&gt;
		--go through .ecf file and list all environment variables it uses&lt;br /&gt;
		--go through all env vars used and:&lt;br /&gt;
			--get their 'old' value from .ecp (if any)&lt;br /&gt;
			--get their 'new' current value (given by shell)&lt;br /&gt;
			if var.is_mismatch then&lt;br /&gt;
				mismatches.extend (var)&lt;br /&gt;
			end&lt;br /&gt;
		if not mismatches.is_empty then&lt;br /&gt;
			if gui_mode then&lt;br /&gt;
				-- Show mismatches to user and ask him to pick the correct values, and allow him to cancel compilation altogether&lt;br /&gt;
			elseif arguments.strict then&lt;br /&gt;
				abort (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			else&lt;br /&gt;
				warn (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		--check that EIFGENs exists, if not create it&lt;br /&gt;
		--create .lock file&lt;br /&gt;
		--project is opened, we may start compiling it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3079</id>
		<title>ProposalProjectFiles</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=ProposalProjectFiles&amp;diff=3079"/>
				<updated>2006-05-30T06:28:12Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:Configuration]]&lt;br /&gt;
[[Category:EiffelStudio]]&lt;br /&gt;
[[Category:Compiler]]&lt;br /&gt;
[[Category:Projects]]&lt;br /&gt;
= Eiffel project files&lt;br /&gt;
== Rationale ==&lt;br /&gt;
Currently, 5.7 offers the following status on project files:&lt;br /&gt;
* a .ecf file describes the Eiffel system to compile, without any compiled-project specific info (see [[Configuration]])&lt;br /&gt;
* .ecf files used to be called .acex, but this has been abandoned in favor of the .ecf extension&lt;br /&gt;
* compiled-project specific info is stored in a .user file in the same folder as the .ecf&lt;br /&gt;
* the .user file resides in the same folder as the corresponding .ecf&lt;br /&gt;
* the .user file is a stored object of type USER_OPTIONS&lt;br /&gt;
* [[ConfigurationMigration]] page describes how .ace files are migrated to the new .ecf format, and gives some info on the compiled-project files structure&lt;br /&gt;
* a folder called '''EIFGENs''' holds all the files representing a compiled project&lt;br /&gt;
* the .user file contains the path to the EIFGENs folder&lt;br /&gt;
* it is possible then to delete the EIFGENs folder and recompile the project from scratch with the info from the .ecf and .user files&lt;br /&gt;
* it is also possible to open the project using the .ecf file (as long as the .user file is also present)&lt;br /&gt;
* it is possible to have the .ecf and .user files in another folder than the one containing the EIFGENs (but it is not possible to share the same .user file for different users and machines)&lt;br /&gt;
&lt;br /&gt;
There are several limitations to this approach&lt;br /&gt;
* the .ecf file can not be used from a network share (the .user file will contain info relative to the machine that performed the compilation, like a path to the EIFGENs folder that is meaningful only from the machine that created the project)&lt;br /&gt;
* if the .ecf file is not in the same folder as the EIFGENs, the .user file bounds it to that folder anyway, we might as well then fix the location of the EIFGENs folder and have it necessarily be in the same folder as the .ecf&lt;br /&gt;
* the .user file could contain more info allowing a more coherent&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Specification ==&lt;br /&gt;
* It should be possible to open any project from a file (by double-clicking on the file for example)&lt;br /&gt;
* Opening an already compiled project should restore the environment as it was when project was compiled (as much as possible, for coherence)&lt;br /&gt;
* It should be possible to instruct the compiler to recompile a project from scratch using that same file&lt;br /&gt;
* It should be possible for third party tools (other than estudio compiler itself) to work with that project descrition file (why not, many people could contribute tools that work with estudio projects)&lt;br /&gt;
* We consider that the situation of opening a project from estudio itself is covered no matter what we choose (estudio will always show an &amp;quot;open project&amp;quot; dialog that will list previously compiled projects and will allow to create a new project using a wizard)&lt;br /&gt;
* The interesting bits are for &amp;quot;batch&amp;quot; or &amp;quot;automated&amp;quot; project creation and compilation&lt;br /&gt;
* It should be possible to have different targets of the same project compiled with different versions of estudio, situations in which this is useful:&lt;br /&gt;
** one wants to compile a 'win32' and 'win64' version of the same project&lt;br /&gt;
** one wants to compile a 'release' and 'experimental' version of the same project using 2 different estudio deliveries&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
* a .ecf file describes an Eiffel system in general (it's equivalent to an Eiffel class)&lt;br /&gt;
* a .ecp file is also generated by the compiler holding all the other project specific info (it's equivalent to an Eiffel object - an instance of a .ecf 'class' mentioned above)&lt;br /&gt;
** the .ecp file contains all the info currently in the .user file, and more&lt;br /&gt;
** the .ecp file can be used to compile a project from scratch etc.&lt;br /&gt;
&lt;br /&gt;
=== Project structure ===&lt;br /&gt;
* .ecf file can be located anywhere, can be shared amongst users, machines, estudio versions etc.&lt;br /&gt;
* .ecp file can be located anywhere (but will reside in the folder containing the EIFGENs most of the time)&lt;br /&gt;
* .ecp file is not supposed to be shared, it's specific to a machine and to a user&lt;br /&gt;
* an EIFGENs folder can be deleted and recreated entirely from the info made available in a .ecp file&lt;br /&gt;
* an EIFGENs folder can be opened in the state it was left after last compilation from the info made available in a .ecp file&lt;br /&gt;
&lt;br /&gt;
=== The configuration file: .ecf ===&lt;br /&gt;
The .ecf file remains as is now, containing the definition of the system to compile,&lt;br /&gt;
with eventually several targets (but no information relative to an actual compilation is stored in there).&lt;br /&gt;
See [[Configuration]]&lt;br /&gt;
&lt;br /&gt;
If a user double-clicks or otherwise tries to open a project given only the .ecf file, then the following happens:&lt;br /&gt;
* in batch mode, an error is issued stating that a project can not be opened from a .ecf file&lt;br /&gt;
* in GUI mode, recently compiled projects corresponding to the .ecf are shown to the user, which has the option of selecting one of them, or browsing to the actual project location)&lt;br /&gt;
&lt;br /&gt;
=== The project file: .ecp ===&lt;br /&gt;
A .ecp file is similar to the .ecf file, but contains only project specific info.&lt;br /&gt;
It is also an XML file serialized from a set of dedicated Eiffel objects.&lt;br /&gt;
&lt;br /&gt;
A project may be opened from a .ecp file easily, since it holds all the needed info.&lt;br /&gt;
&lt;br /&gt;
An .ecp file holds all the info relative to the current compilation, this info is (exhaustively):&lt;br /&gt;
* the path to the .ecf file&lt;br /&gt;
* a list of settings per compilation target&lt;br /&gt;
* the 'last used target' (for convenience)&lt;br /&gt;
* the 'project path' containing the EIFGENs&lt;br /&gt;
* each 'compilation target' contains the following info:&lt;br /&gt;
** the name of the target&lt;br /&gt;
** the version of estudio that compiled the target&lt;br /&gt;
** the name of the machine that build the project&lt;br /&gt;
** the username of the account under which the project was built&lt;br /&gt;
** the working directory that the user chose (by default it's the folder containing the .ecp file)&lt;br /&gt;
** the last command line arguments the project was started with (in debug mode)&lt;br /&gt;
** the list of used command line arguments (for convenience)&lt;br /&gt;
** are command line arguments 'active'&lt;br /&gt;
** all the used environment variables (an environment variable is 'used' if it appears in the .ecf file)&lt;br /&gt;
&lt;br /&gt;
The .ecp file should not be a stored Eiffel object for 2 reasons:&lt;br /&gt;
* it depends on the version of storable used, and presents retrieval problems if the API of the stored object is modified&lt;br /&gt;
* if contributors want to open that storable, they have to have the right Eiffel class in their system&lt;br /&gt;
&lt;br /&gt;
==== .ecp XML structure ====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;settings&lt;br /&gt;
		ecf=&amp;quot;/path/to/ecf/sample.ecf&amp;quot;&lt;br /&gt;
		last_target=&amp;quot;target1&amp;quot;&lt;br /&gt;
		project_path=&amp;quot;/projects/sample&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
	&amp;lt;target&lt;br /&gt;
		name=&amp;quot;target1&amp;quot;&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		working_directory=&amp;quot;/projects/testing&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
		&amp;lt;command_line active=&amp;quot;true&amp;quot; last=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--help&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--use this and that&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable value=&amp;quot;--crack a smile&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/command_line&amp;gt;&lt;br /&gt;
		&amp;lt;environment&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;ISE_EIFFEL&amp;quot; value=&amp;quot;/path/to/estudio/5.7.58953&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;variable name=&amp;quot;GOBO&amp;quot; value=&amp;quot;/path/to/gobo&amp;quot;&amp;gt;&lt;br /&gt;
			...&lt;br /&gt;
		&amp;lt;/environment&amp;gt;&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
	&amp;lt;target name=&amp;quot;target2&amp;quot;&amp;gt;&lt;br /&gt;
		...&lt;br /&gt;
	&amp;lt;/target&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ECP classes ====&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_PROJECT&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	ecf: STRING&lt;br /&gt;
			-- Path to .ecf file&lt;br /&gt;
&lt;br /&gt;
	last_target: STRING&lt;br /&gt;
			-- Name of last used target&lt;br /&gt;
 &lt;br /&gt;
	project_path: STRING&lt;br /&gt;
			-- Path to folder containing the EIFGENs generated folder&lt;br /&gt;
 &lt;br /&gt;
	targets: LIST [ECP_TARGET]&lt;br /&gt;
			-- The configuration targets.&lt;br /&gt;
 &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project target&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_TARGET&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	name: STRING&lt;br /&gt;
			-- Name of the target&lt;br /&gt;
&lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio chosen to compile the target&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the target was compiled&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the compilation took place&lt;br /&gt;
&lt;br /&gt;
	working_directory: STRING&lt;br /&gt;
			-- Working directory selected by the user&lt;br /&gt;
			-- Optional, if not specified, the working folder is the folder containing the .ecp file&lt;br /&gt;
&lt;br /&gt;
	use_arguments: BOOLEAN&lt;br /&gt;
			-- Use arguments?&lt;br /&gt;
&lt;br /&gt;
	last_argument: STRING&lt;br /&gt;
			-- Last used argument.&lt;br /&gt;
&lt;br /&gt;
	arguments: LIST [STRING]&lt;br /&gt;
			-- List of arguments used by current target&lt;br /&gt;
&lt;br /&gt;
	evironment_variables: LIST [ECP_ENVIRONMENT_VARIABLE]&lt;br /&gt;
			-- List of environment variables refered to in the .ecf file for current target&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== What does this bring us? ====&lt;br /&gt;
* it is possible to open an eiffel project from a .ecp file, with the right version of estudio, environment settings etc.&lt;br /&gt;
* is is possible to recompile a project from scratch from a .ecp file easily (all the needed info is there)&lt;br /&gt;
* if environment variables changed since the project was compiled, the user can be warned&lt;br /&gt;
&lt;br /&gt;
=== What to do with the 'environment settings' ===&lt;br /&gt;
&lt;br /&gt;
Why do we keep the 'used environment variables'? Why do they matter?&lt;br /&gt;
Typically, when compiling a project, developers refer to clusters using environment variables.&lt;br /&gt;
But what should happen if compilation1 used var1, and compilation2 uses a different value for var1?&lt;br /&gt;
Right now, nothing special happens, compilation2 simply goes on, not even knowing that var1 changed...&lt;br /&gt;
&lt;br /&gt;
It is however important to detect this, and it is very easy to implement too.&lt;br /&gt;
Many situations occur that can lead to compilation errors and corrupted projects due to this environment-variable situation.&lt;br /&gt;
Problems typically occur in companies with many users and machines juggling with a set of different environments.&lt;br /&gt;
Also, a project is often setup with all the right environment variables, but then users want to later on simply open a given project without worrying what environment variables were used to set it up, keeping these in the .ecp file would allow for &amp;quot;simply double-click the .ecp file to open a project&amp;quot; kind of thing.&lt;br /&gt;
&lt;br /&gt;
The following suggestion should allow to take care of this problem elegantly.&lt;br /&gt;
&lt;br /&gt;
* When a compilation is initiated, the 'env vars' list in the project settings file is empty&lt;br /&gt;
* The following steps would be implemented in an 'initial pass' (before degree 6) by the compiler&lt;br /&gt;
* Each time the compile encounters an env var in the .ecf file (and only there), it looks at what was previously present in the .ecp:&lt;br /&gt;
** if the env var is used for the first time (not yet defined in the .ecp) then set it in the .ecp&lt;br /&gt;
** if the env var was already there, then compare it:&lt;br /&gt;
*** if the current env var value is equal to the one stored in the .ecp, then it's good, just continue compilation&lt;br /&gt;
*** if they differ, then remember they differed and remeber both values&lt;br /&gt;
** do the above for all env vars refered to in the .ecf&lt;br /&gt;
* Now at the end of this &amp;quot;initial pass&amp;quot; we have a set of &amp;quot;differing&amp;quot; env vars&lt;br /&gt;
** if the set is empty, go on to degree 6 as usual&lt;br /&gt;
** if the set is not empty, then proceed as follows (2 different situations)&lt;br /&gt;
*** in GUI mode, popup a modal dialog showing the differences and asking the user whether it's OK to continue (a nice touch would be to let the user choose which version to use for each env var, old or new version)&lt;br /&gt;
*** in batch mode, 2 different cases&lt;br /&gt;
**** abort compilation if for example a -strict flag is specified on the command line&lt;br /&gt;
**** continue compilation with a warning listing the diffs otherwise&lt;br /&gt;
* Apply the same logic for the &amp;quot;hostname&amp;quot; and &amp;quot;username&amp;quot; info in the .ecp file (also before degree 6)&lt;br /&gt;
** if the project is being opened on a different machine than the one that created the last .ecp:&lt;br /&gt;
*** popup the warning dialog, asking the user whether it's OK to continue opening the project or not&lt;br /&gt;
*** in batch mode:&lt;br /&gt;
**** fail if -strict is specified&lt;br /&gt;
**** warn otherwise&lt;br /&gt;
* If the compilation proceeds (either because user said OK, or because -strict was not specified), overwrite the info in the .ecp with the new values&lt;br /&gt;
* The same logic could be applied to other pieces of info in the .ecp (such as project path etc.. some users open their projects from local folders such as C:\projects on Windows, as well as UNC folders such as \\MACHINE\projects, sometimes at the same time!)&lt;br /&gt;
&lt;br /&gt;
=== Handling projects being opened several times at once ===&lt;br /&gt;
Typically, if the same project (same EIFGENs) is opened several times (from different machines for example) at once, there's a risk of the project getting corrputed&lt;br /&gt;
There is a very simple way to handle this problem elegantly:&lt;br /&gt;
* create a file in /&amp;lt;project path&amp;gt;/EIFGENs/&amp;lt;target&amp;gt;/ec.lock as soon as the project is open and put the following info in it:&lt;br /&gt;
** the estudio version&lt;br /&gt;
** the hostname and username opening the project&lt;br /&gt;
** the date and time when it was opened&lt;br /&gt;
** the &amp;quot;process_id&amp;quot; of the compiler opening the project (and creating this .lock file)&lt;br /&gt;
* delete this file as soon as the project is closed (ie, the batch job exits, or the user closes the IDE)&lt;br /&gt;
* if the compiler crashes and doesn't get the chance to close and delete this file, it's OK&lt;br /&gt;
* if when opening the project the file already exists, then 2 situations:&lt;br /&gt;
** in batch mode:&lt;br /&gt;
*** exit immediately with an error saying that the &amp;quot;ec.lock&amp;quot; file needs to be deleted (either manually or by closing the other running process) before the project can be opened in batch mode&lt;br /&gt;
** in GUI mode:&lt;br /&gt;
*** popup a dialog asking the user what to do, the user has the following info and choices:&lt;br /&gt;
*** the popup shows which user/host/date has the project opened&lt;br /&gt;
*** &amp;quot;Open read-only&amp;quot; - allows the user to open the project without the capability to compile it (as to avoid corrupting the project)&lt;br /&gt;
*** &amp;quot;Open anyway, I know it's not open&amp;quot; - this option deletes the .lock file and recreates it (this would typically happen if the compiler crashed and did not get a chance to delete this .lock file)&lt;br /&gt;
*** &amp;quot;Cancel&amp;quot; project opening operation&lt;br /&gt;
&lt;br /&gt;
Suggested format for this .lock file is also XML, here's an example of such a file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;ISO-8859-1&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;project&lt;br /&gt;
	xmlns=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0&amp;quot;&lt;br /&gt;
	xmlns:xsi=&amp;quot;http://www.w3.org/2001/XMLSchema-instance&amp;quot;&lt;br /&gt;
	xsi:schemaLocation=&amp;quot;http://www.eiffel.com/developers/xml/project-1-0-0 http://www.eiffel.com/developers/xml/project-1-0-0.xsd&amp;quot;&lt;br /&gt;
	&amp;gt;&lt;br /&gt;
	&amp;lt;lock&lt;br /&gt;
		estudio=&amp;quot;5.7.58953&amp;quot;&lt;br /&gt;
		host=&amp;quot;zebra3.example.com&amp;quot;&lt;br /&gt;
		username=&amp;quot;marty&amp;quot;&lt;br /&gt;
		date=&amp;quot;2006/05/28 17:56:27&amp;quot;&lt;br /&gt;
		pid=&amp;quot;2451&amp;quot;&lt;br /&gt;
	/&amp;gt;&lt;br /&gt;
&amp;lt;/project&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The hostname and username info has an obvious added value (one knows who has the project open and where)&lt;br /&gt;
The 'process_id' info would allow third-party Eiffel project management tools to &amp;quot;communicate&amp;quot; eventually with the ec.exe process that has the project open in the future, or kill the process, or change its priority etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Describes an Eiffel project lock file&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date: $&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision: $&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
class&lt;br /&gt;
	ECP_LOCK&lt;br /&gt;
 &lt;br /&gt;
feature&lt;br /&gt;
 &lt;br /&gt;
	estudio: STRING&lt;br /&gt;
			-- Version of estudio that created the .lock file&lt;br /&gt;
&lt;br /&gt;
	host: STRING&lt;br /&gt;
			-- Name of the machine (host) where the .lock file was created&lt;br /&gt;
&lt;br /&gt;
	username: STRING&lt;br /&gt;
			-- Username under which the .lock file was created&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	date: STRING&lt;br /&gt;
			-- Date when .lock file was created&lt;br /&gt;
			-- Maybe this does not need to be an attribute...&lt;br /&gt;
			-- The creation date of the file itself should give same info anyway&lt;br /&gt;
&lt;br /&gt;
	pid: INTEGER&lt;br /&gt;
			-- Process id of the process that created this lock file&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Command-line arguments for 'ec' and 'estudio' ===&lt;br /&gt;
'ec' and 'estudio' should accept similar command line arguments for coherence&lt;br /&gt;
* To create a project, user must provide 2 arguments: -project_path and -config&lt;br /&gt;
* To simply open a project, the user provides -project argument&lt;br /&gt;
&lt;br /&gt;
==== 'ec' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
;-strict&lt;br /&gt;
:Flag indicating whether environment settings should match accross compilations&lt;br /&gt;
:If not specified, compiler issues a warning if environment variables modified since last compilation&lt;br /&gt;
:If specified, compiler aborts with an error listing mismatching environment variables&lt;br /&gt;
&lt;br /&gt;
* Command line arguments -config and -project_path must be specified together for project creation, when these 2 arguments are provided:&lt;br /&gt;
** a new .ecp is always created (existing .ecp is deleted and recreated)&lt;br /&gt;
** any existing EIFGENs is deleted prior to compilation&lt;br /&gt;
** EIFGENs folder is stored in same 'project_path' folder as the .ecp&lt;br /&gt;
** users can choose a different path for the EIFGENs folder either by:&lt;br /&gt;
*** creating a .ecp file themselves&lt;br /&gt;
*** using the graphical IDE, which could allow for such customization (ec.exe in batch mode does not)&lt;br /&gt;
* -project is used to open an alrady compiled once project&lt;br /&gt;
* the pair [-project_path, -config] is exclusive with -project (users can not specify the -project along with -project_path or -config)&lt;br /&gt;
* -target is always optional and may be provided for both project creation or project opening&lt;br /&gt;
* -strict makes sense only for project opening&lt;br /&gt;
&lt;br /&gt;
==== 'estudio' command line arguments (relative to project management) ====&lt;br /&gt;
;-config &amp;lt;ecf&amp;gt;&lt;br /&gt;
:Path to .ecf file to compile, when this argument is passed, -project_path must be specified as well&lt;br /&gt;
;-project_path &amp;lt;folder&amp;gt;&lt;br /&gt;
:Specifies the folder where to create the .ecp file (same name as given .ecf file). If a .ecp file is already there, it is overwritten (recreated)&lt;br /&gt;
;-project &amp;lt;ecp&amp;gt;&lt;br /&gt;
:Path to project to open.&lt;br /&gt;
;-target &amp;lt;target&amp;gt;&lt;br /&gt;
:Target to compile (optional, if not provided, 'last_target' from .ecp is used)&lt;br /&gt;
&lt;br /&gt;
Similar rules as above apply.&lt;br /&gt;
The graphical IDE should ask questions to user only if something left unspecified.&lt;br /&gt;
&lt;br /&gt;
==== Scenarios ====&lt;br /&gt;
* Create a new project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
estudio -project_path /projects/sample -config /path/to/ecf/sample.ecf -freeze -c_compile&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Open an existing project&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ec -batch -project /projects/sample/sample.ecp -freeze -c_compile&lt;br /&gt;
estudio -project /project/sample/sample.ecp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecp file is equivalent to &amp;lt;code&amp;gt;estudio -project &amp;lt;ecp&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Double-clicking on a .ecf file is handled like so:&lt;br /&gt;
** if a .ecp file with same name as the .ecf is present in same folder, open the .ecp file in that same folder&lt;br /&gt;
** otherwise, prompt the user to choose which .ecp file to use&lt;br /&gt;
*** list all recently compiled projects that could match&lt;br /&gt;
*** allow user to 'browse' to .ecp location&lt;br /&gt;
*** allow user to create a new project out of the .ecp file&lt;br /&gt;
&lt;br /&gt;
=== Pseudo-code algorithm ===&lt;br /&gt;
* .ecp files are processed once when the project is opened (before first degree 6)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
if arguments.project_path or arguments.config then&lt;br /&gt;
	if arguments.project then&lt;br /&gt;
		abort (&amp;quot;specify either -project or [-project_path + -config]&amp;quot;)&lt;br /&gt;
	elseif not arguments.project_path then&lt;br /&gt;
		abort (&amp;quot;missing -project_path argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	elsief not arguments.config then&lt;br /&gt;
		abort (&amp;quot;missing -config argument, [-project_path + -config] go together&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
	create_new_project (arguments.project_path, arguments.config)&lt;br /&gt;
elseif arguments.project then&lt;br /&gt;
	if arguments.project.extension = &amp;quot;ecp&amp;quot; then&lt;br /&gt;
		open_project (arguments.project)&lt;br /&gt;
	elseif arguments.project.extension = &amp;quot;epr&amp;quot; then&lt;br /&gt;
		convert_old_epr (arguments.project)&lt;br /&gt;
	else&lt;br /&gt;
		abort (&amp;quot;Unsupported project file&amp;quot;)&lt;br /&gt;
	end&lt;br /&gt;
else&lt;br /&gt;
	?&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
create_new_project (a_project_path, a_config: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		--create new .ecp file&lt;br /&gt;
		--delete EIFGENs if present&lt;br /&gt;
		open_project (created_ecp_file.path)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
open_project (a_ecp_path: STRING) is&lt;br /&gt;
	do&lt;br /&gt;
		create ecp.make (a_ecp_path)&lt;br /&gt;
		--check that associated .ecf file exists&lt;br /&gt;
		--go through .ecf file and list all environment variables it uses&lt;br /&gt;
		--go through all env vars used and:&lt;br /&gt;
			--get their 'old' value from .ecp (if any)&lt;br /&gt;
			--get their 'new' current value (given by shell)&lt;br /&gt;
			if var.is_mismatch then&lt;br /&gt;
				mismatches.extend (var)&lt;br /&gt;
			end&lt;br /&gt;
		if not mismatches.is_empty then&lt;br /&gt;
			if gui_mode then&lt;br /&gt;
				-- Show mismatches to user and ask him to pick the correct values, and allow him to cancel compilation altogether&lt;br /&gt;
			elseif arguments.strict then&lt;br /&gt;
				abort (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			else&lt;br /&gt;
				warn (&amp;quot;Mismatches: &amp;quot; + mismatches)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		--check that EIFGENs exists, if not create it&lt;br /&gt;
		--create .lock file&lt;br /&gt;
		--project is opened, we may start compiling it&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	<entry>
		<id>https://dev.eiffel.com/index.php?title=Configuration&amp;diff=3078</id>
		<title>Configuration</title>
		<link rel="alternate" type="text/html" href="https://dev.eiffel.com/index.php?title=Configuration&amp;diff=3078"/>
				<updated>2006-05-30T06:24:49Z</updated>
		
		<summary type="html">&lt;p&gt;Zoran: Added link to new ProjectFiles page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:EiffelStudio]]&lt;br /&gt;
[[Category:Compiler]]&lt;br /&gt;
[[Category:Configuration]]&lt;br /&gt;
== General ideas ==&lt;br /&gt;
* as much as possible independant from the system (windows/unix)&lt;br /&gt;
* one file with multiple configurations (eg. debug, release build)&lt;br /&gt;
* include/exclude as regexp pattern&lt;br /&gt;
* global ignore patterns (eg. cvs/svn)&lt;br /&gt;
* include other configuration files (eg. to add a library just include the config file of the library)&lt;br /&gt;
* relative paths&lt;br /&gt;
* actions before/after run/compile (eg. start a server)&lt;br /&gt;
&lt;br /&gt;
=== Things to implement ideas ===&lt;br /&gt;
* conditions (if windows then ... elseif unix then ... end)&lt;br /&gt;
* variables (user and predefined)&lt;br /&gt;
* inheritance of configuration&lt;br /&gt;
&lt;br /&gt;
=== Other ===&lt;br /&gt;
* convert old ace files into new format&lt;br /&gt;
* *.epr vs *.ace&lt;br /&gt;
* [[ProjectFiles]]&lt;br /&gt;
&lt;br /&gt;
== Possible implementation layout ==&lt;br /&gt;
&lt;br /&gt;
Some more information are available here: http://www.ise/tools/public_zone/index.php?op=dl&amp;amp;path=/home/patrickr/public_html/Public/project_configuration.pdf (Part with two config files has changed to only one config file.)&lt;br /&gt;
&lt;br /&gt;
[[Image:Configuration1.jpg]]&lt;br /&gt;
&lt;br /&gt;
A system consists of multiple targets. A target can extend another target. A target can have some libraries, assemblies, clusters and override clusters.&lt;br /&gt;
A library has an associated target. A cluster can have a parent cluster. An override cluster has a some groups it overrides.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;The configuration system.&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date$&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision$&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class&lt;br /&gt;
	CONF_SYSTEM&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
	name: STRING&lt;br /&gt;
			-- Name of the system.&lt;br /&gt;
&lt;br /&gt;
	uuid: STRING&lt;br /&gt;
			-- UUID of this system. Used to uniquely identify libraries.&lt;br /&gt;
&lt;br /&gt;
	targets: LIST [CONF_TARGET]&lt;br /&gt;
			-- The configuration targets.&lt;br /&gt;
&lt;br /&gt;
	library_target: CONF_TARGET&lt;br /&gt;
			-- The target to use if this is used as a library.&lt;br /&gt;
	&lt;br /&gt;
	compileable_targets: LIST [CONF_TARGET]&lt;br /&gt;
			-- Targets that can be compiled (e.g. have a root feature).&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;A configuration target.&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date$&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision$&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class&lt;br /&gt;
	CONF_TARGET&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
	name: STRING&lt;br /&gt;
			-- Name of the target.&lt;br /&gt;
&lt;br /&gt;
	version: CONF_VERSION&lt;br /&gt;
			-- Version number of the target.&lt;br /&gt;
&lt;br /&gt;
	extends: CONF_TARGET&lt;br /&gt;
			-- If we extend another target, this is the other target.&lt;br /&gt;
&lt;br /&gt;
	libraries: LIST [CONF_LIBRARY]&lt;br /&gt;
			-- The used libraries.&lt;br /&gt;
&lt;br /&gt;
	overrides: LIST [CONF_OVERRIDE]&lt;br /&gt;
			-- The override clusters.&lt;br /&gt;
&lt;br /&gt;
	clusters: LIST [CONF_CLUSTER]&lt;br /&gt;
			-- The normal clusters.&lt;br /&gt;
	&lt;br /&gt;
	assemblies: LIST [CONF_ASSEMBLY]&lt;br /&gt;
			-- The assemblies.&lt;br /&gt;
&lt;br /&gt;
	root: CONF_ROOT&lt;br /&gt;
			-- The root feature.&lt;br /&gt;
&lt;br /&gt;
	options: CONF_OPTIONS&lt;br /&gt;
			-- The options (assertions, debugs, warnings, ...)&lt;br /&gt;
&lt;br /&gt;
	file_rule: CONF_FILE_RULE&lt;br /&gt;
			-- Globally exclude/include file rules.&lt;br /&gt;
&lt;br /&gt;
	external_include: LIST [CONF_EXTERNAL_INCLUDE]&lt;br /&gt;
			-- Global external include files.&lt;br /&gt;
&lt;br /&gt;
	external_objec: LIST [CONF_EXTERNAL_OBJECT]&lt;br /&gt;
			-- Global external object files.&lt;br /&gt;
&lt;br /&gt;
	external_ressource: LIST [CONF_EXTERNAL_RESSOURCE]&lt;br /&gt;
			-- Global external ressource files.&lt;br /&gt;
&lt;br /&gt;
	pre_compile: LIST [CONF_ACTION]&lt;br /&gt;
			-- Actions to be executed before compilation.&lt;br /&gt;
&lt;br /&gt;
	post_action: LIST [CONF_ACTION]&lt;br /&gt;
			-- Actions to be executed after compilation.&lt;br /&gt;
&lt;br /&gt;
	variables: LIST [CONF_VARIABLE]&lt;br /&gt;
			-- User defined variables.&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Base class for configuration groups.&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date$&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision$&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class&lt;br /&gt;
	CONF_GROUP&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
	CONF_CONDITIONED&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
	name: STRING&lt;br /&gt;
			-- The name of the group.&lt;br /&gt;
&lt;br /&gt;
	directory: CONF_DIRECTORY&lt;br /&gt;
			-- The directory of the group.&lt;br /&gt;
&lt;br /&gt;
	options: CONF_OPTIONS&lt;br /&gt;
			-- The options (assertions, debugs, warnings, ...)&lt;br /&gt;
&lt;br /&gt;
	name_prefix: STRING&lt;br /&gt;
			-- An optional name prefix for this group.&lt;br /&gt;
&lt;br /&gt;
	renaming: HASH_TABLE [STRING, STRING]&lt;br /&gt;
			-- Mapping of renamed classes from the old name to the new name.&lt;br /&gt;
&lt;br /&gt;
	class_options: HASH_TABLE [CONF_OPTION, STRING&lt;br /&gt;
			-- Classes with specific options.&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;A library.&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date$&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision$&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class&lt;br /&gt;
	CONF_LIBRARY&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
	CONF_GROUP&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
	library_target: CONF_TARGET&lt;br /&gt;
			-- The library target.&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;A project cluster.&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date$&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision$&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class&lt;br /&gt;
	CONF_CLUSTER&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
	CONF_GROUP&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
	is_recursive: BOOLEAN&lt;br /&gt;
			-- Are subdirectories included recursively?&lt;br /&gt;
&lt;br /&gt;
	parent: CONF_CLUSTER&lt;br /&gt;
			-- An optional parent cluster.&lt;br /&gt;
&lt;br /&gt;
	dependencies: LIST [CONF_GROUP]&lt;br /&gt;
			-- Dependencies to other groups.&lt;br /&gt;
&lt;br /&gt;
	file_rule: CONF_FILE_RULE&lt;br /&gt;
			-- Globally exclude/include file rules.&lt;br /&gt;
&lt;br /&gt;
	is_visible (a_feature, a_class: STRING): BOOLEAN&lt;br /&gt;
			-- Is a feature of this cluster visible?&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;[eiffel, N]&lt;br /&gt;
indexing&lt;br /&gt;
	description: &amp;quot;Clusters that override other groups.&amp;quot;&lt;br /&gt;
	date: &amp;quot;$Date$&amp;quot;&lt;br /&gt;
	revision: &amp;quot;$Revision$&amp;quot;&lt;br /&gt;
&lt;br /&gt;
class&lt;br /&gt;
	CONF_OVERRIDE&lt;br /&gt;
&lt;br /&gt;
inherit&lt;br /&gt;
	CONF_CLUSTER&lt;br /&gt;
&lt;br /&gt;
feature&lt;br /&gt;
&lt;br /&gt;
	override: LIST [CONF_GROUP]&lt;br /&gt;
			-- The groups that this cluster overrides.&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
CONF_CONDITIONED is a class that allows to specify for which platform, build tuple something is enabled. Conditioned are: CONF_ACTION (pre-/postcompile actions), CONF_EXTERNAL_(INCLUDE|OBJECT|RESSOURCE), CONF_GROUP&lt;br /&gt;
&lt;br /&gt;
== Pseudocode example configuration ==&lt;br /&gt;
files/eiffelvision/eiffelvision.ace&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
system EiffelVision&lt;br /&gt;
&lt;br /&gt;
target Library&lt;br /&gt;
    version 2.0.0.1&lt;br /&gt;
    uuid 15ac36b5-2c65-41e9-8309-c504dd430a0b&lt;br /&gt;
&lt;br /&gt;
    library base&lt;br /&gt;
        files/base/base.ace&lt;br /&gt;
&lt;br /&gt;
    cluster vision&lt;br /&gt;
        files/vision&lt;br /&gt;
        recursive&lt;br /&gt;
        uses base&lt;br /&gt;
    &lt;br /&gt;
    external_include&lt;br /&gt;
        files/include/common.h [(all, all)]&lt;br /&gt;
        files/include/windows.h [(windows, all)]&lt;br /&gt;
        files/include/gtk [(unix, all)]&lt;br /&gt;
&lt;br /&gt;
    external_objects&lt;br /&gt;
        files/obj/windows.o [(windows, all)]&lt;br /&gt;
        files/obj/gtk.o [(unix, all)]&lt;br /&gt;
        files/obj/debug.o [(unix, workbench)]&lt;br /&gt;
&lt;br /&gt;
target Debug extends Library&lt;br /&gt;
&lt;br /&gt;
    cluster debug&lt;br /&gt;
        files/debug&lt;br /&gt;
        recursive&lt;br /&gt;
        uses base, vision&lt;br /&gt;
&lt;br /&gt;
    root debug:ROOT_CLASS:make&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
files/eiffelstudio/eiffelstudio.ace&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
system EiffelStudio&lt;br /&gt;
    version 5.0.0.1&lt;br /&gt;
    uuid 9a8d3871-ef44-484c-9029-c52d17df40f0&lt;br /&gt;
&lt;br /&gt;
target Common&lt;br /&gt;
&lt;br /&gt;
    variable gobo_setting=&amp;quot;some settings&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    exclude&lt;br /&gt;
        ^\.svn$&lt;br /&gt;
&lt;br /&gt;
    library base &lt;br /&gt;
        files/base/base.ace&lt;br /&gt;
&lt;br /&gt;
    library gobo&lt;br /&gt;
        files/gobo/gobo.ace&lt;br /&gt;
        rename &amp;quot;some_class&amp;quot; as &amp;quot;new_class&amp;quot;&lt;br /&gt;
        prefix &amp;quot;gobo_&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    cluster compiler&lt;br /&gt;
        files/compiler&lt;br /&gt;
            uses base, gobo&lt;br /&gt;
&lt;br /&gt;
    root compiler:ROOT_CLASS:make&lt;br /&gt;
&lt;br /&gt;
target Console extends Common&lt;br /&gt;
&lt;br /&gt;
    cluster console&lt;br /&gt;
        files/console&lt;br /&gt;
            uses base, gobo, compiler&lt;br /&gt;
&lt;br /&gt;
    cluster mysub (console)&lt;br /&gt;
        $/mysub&lt;br /&gt;
&lt;br /&gt;
target Workbench extends Common&lt;br /&gt;
&lt;br /&gt;
    library eiffelvision&lt;br /&gt;
        files/eiffelvision/eiffelvision.ace&lt;br /&gt;
&lt;br /&gt;
    cluster workbench&lt;br /&gt;
        files/workbench&lt;br /&gt;
            uses base, gobo, eiffelvision, compiler&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Questions and Problems ==&lt;br /&gt;
&lt;br /&gt;
*Specify use of other clusters? '''Yes'''&lt;br /&gt;
*Variables? '''If not defined, take environment variable.'''&lt;br /&gt;
*Path relative to ace file? '''Yes'''&lt;br /&gt;
*When are two libraries the same? '''UUID: http://www.famkruithof.net/guid-uuid-random.html'''&lt;br /&gt;
=== Multiple library usage ===&lt;br /&gt;
====Problem====&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
System Application&lt;br /&gt;
&lt;br /&gt;
library A&lt;br /&gt;
library B&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
System A&lt;br /&gt;
&lt;br /&gt;
library C&lt;br /&gt;
    option Yes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
System B&lt;br /&gt;
&lt;br /&gt;
library C&lt;br /&gt;
    option No&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
We have a conflict for the option on library C.&lt;br /&gt;
&lt;br /&gt;
====Solution====&lt;br /&gt;
If the library is directly used in Application, use the this options, otherwise use the options of the Application system.&lt;br /&gt;
&lt;br /&gt;
===File pattern===&lt;br /&gt;
The file pattern match against the relative path in unix format in a cluster.&lt;br /&gt;
e.g. if the cluster is in C:\mycluster&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table border=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;th&amp;gt;Pattern&amp;lt;/th&amp;gt;&lt;br /&gt;
 &amp;lt;th&amp;gt;Matches&amp;lt;/th&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&lt;br /&gt;
storage/table&lt;br /&gt;
 &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&lt;br /&gt;
    C:\mycluster\storage\table\*&lt;br /&gt;
    C:\mycluster\storage\table.e&lt;br /&gt;
    C:\mycluster\something\storage\table\*&lt;br /&gt;
 &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&lt;br /&gt;
^/storage/table/&lt;br /&gt;
 &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&lt;br /&gt;
    C:\mycluster\storage\table\*&lt;br /&gt;
 &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&lt;br /&gt;
^/.*/test/&lt;br /&gt;
 &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&lt;br /&gt;
    C:\mycluster\a\test\*&lt;br /&gt;
    C:\mycluster\b\test\*&lt;br /&gt;
 &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tr&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&lt;br /&gt;
/test/&lt;br /&gt;
 &amp;lt;/td&amp;gt;&lt;br /&gt;
 &amp;lt;td&amp;gt;&lt;br /&gt;
    C:\mycluster\a\test\*&lt;br /&gt;
    C:\mycluster\b\test\*&lt;br /&gt;
    C:\mycluster\something\table\test\*&lt;br /&gt;
 &amp;lt;/td&amp;gt;&lt;br /&gt;
&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuration file format ==&lt;br /&gt;
[[ConfigurationFileFormat|Configuration file format page]]&lt;br /&gt;
&lt;br /&gt;
== Migration ==&lt;br /&gt;
[[ConfigurationMigration|Configuration migration]]&lt;br /&gt;
&lt;br /&gt;
== Degree 6 ==&lt;br /&gt;
[[ConfigurationDegree6|Configuration degree 6]]&lt;br /&gt;
&lt;br /&gt;
== Ideas for better conditions ==&lt;br /&gt;
[[ConfigurationConditions|Configuration conditions]]&lt;/div&gt;</summary>
		<author><name>Zoran</name></author>	</entry>

	</feed>